LanguageConsole: extract mutable part to Helper class & make most methods final

This commit is contained in:
Gregory.Shrago
2015-06-19 19:30:32 +03:00
parent 10d6324f20
commit df02ae975f
4 changed files with 138 additions and 126 deletions
@@ -186,18 +186,22 @@ public final class LanguageConsoleBuilder {
private final static class GutteredLanguageConsole extends LanguageConsoleImpl {
private final GutterContentProvider gutterContentProvider;
@Nullable
private final PairFunction<VirtualFile, Project, PsiFile> psiFileFactory;
public GutteredLanguageConsole(@NotNull String title,
@NotNull Project project,
@NotNull Language language,
@Nullable GutterContentProvider gutterContentProvider,
@Nullable PairFunction<VirtualFile, Project, PsiFile> psiFileFactory) {
super(project, title, new LightVirtualFile(title, language, ""), psiFileFactory);
@Nullable final PairFunction<VirtualFile, Project, PsiFile> psiFileFactory) {
super(new Helper(project, new LightVirtualFile(title, language, "")) {
@NotNull
@Override
public PsiFile getFile() {
return psiFileFactory == null ? super.getFile() : psiFileFactory.fun(virtualFile, project);
}
});
this.gutterContentProvider = gutterContentProvider == null ? new BasicGutterContentProvider() : gutterContentProvider;
this.psiFileFactory = psiFileFactory;
}
@Override
@@ -210,18 +214,6 @@ public final class LanguageConsoleBuilder {
return 1;
}
@NotNull
@Override
protected PsiFile createFile(@NotNull Project project,
@NotNull VirtualFile virtualFile) {
if (psiFileFactory == null) {
return super.createFile(project, virtualFile);
}
else {
return psiFileFactory.fun(virtualFile, project);
}
}
@Override
protected void setupEditorDefault(@NotNull EditorEx editor) {
super.setupEditorDefault(editor);
@@ -55,7 +55,6 @@ import com.intellij.ui.components.JBScrollBar;
import com.intellij.util.DocumentUtil;
import com.intellij.util.FileContentUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.PairFunction;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.AbstractLayoutManager;
import com.intellij.util.ui.JBUI;
@@ -76,17 +75,13 @@ import java.util.Collections;
* In case of REPL consider to use {@link LanguageConsoleBuilder}
*/
public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageConsoleView, DataProvider {
private final Project myProject;
private final Helper myHelper;
private final EditorEx myConsoleEditor;
private final EditorEx myHistoryViewer;
private final Document myEditorDocument;
private final VirtualFile myVirtualFile;
protected PsiFile myFile; // will change on language change
private final JPanel myPanel = new JPanel(new MyLayout());
private String myTitle;
@Nullable
private String myPrompt = "> ";
private ConsoleViewContentType myPromptAttributes = ConsoleViewContentType.USER_INPUT;
@@ -109,53 +104,44 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
};
public LanguageConsoleImpl(@NotNull Project project, @NotNull String title, @NotNull Language language) {
this(project, title, new LightVirtualFile(title, language, ""));
this(new Helper(project, new LightVirtualFile(title, language, "")));
}
public LanguageConsoleImpl(@NotNull Project project, @NotNull String title, @NotNull VirtualFile virtualFile) {
this(project, title, virtualFile, null);
this(new Helper(project, virtualFile).setTitle(title));
}
LanguageConsoleImpl(@NotNull Project project,
@NotNull String title,
@NotNull VirtualFile lightFile,
@Nullable PairFunction<VirtualFile, Project, PsiFile> psiFileFactory) {
super(project, GlobalSearchScope.allScope(project), true, true);
myProject = project;
myTitle = title;
myVirtualFile = lightFile;
public LanguageConsoleImpl(@NotNull Helper helper) {
super(helper.project, GlobalSearchScope.allScope(helper.project), true, true);
myHelper = helper;
EditorFactory editorFactory = EditorFactory.getInstance();
myEditorDocument = FileDocumentManager.getInstance().getDocument(lightFile);
if (myEditorDocument == null) {
throw new AssertionError("no document for: " + lightFile);
}
myFile = psiFileFactory == null ? createFile(myProject, myVirtualFile) : psiFileFactory.fun(myVirtualFile, myProject);
myConsoleEditor = (EditorEx)editorFactory.createEditor(myEditorDocument, myProject);
myEditorDocument = helper.getDocument();
myConsoleEditor = (EditorEx)editorFactory.createEditor(myEditorDocument, getProject());
myConsoleEditor.addFocusListener(myFocusListener);
myCurrentEditor = myConsoleEditor;
myHistoryViewer = (EditorEx)editorFactory.createViewer(((EditorFactoryImpl)editorFactory).createDocument(true), myProject);
myHistoryViewer = (EditorEx)editorFactory.createViewer(((EditorFactoryImpl)editorFactory).createDocument(true), getProject());
myBusConnection = myProject.getMessageBus().connect();
myBusConnection = getProject().getMessageBus().connect();
// action shortcuts are not yet registered
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
installEditorFactoryListener();
}
}, myProject.getDisposed());
}, getProject().getDisposed());
}
@Override
protected EditorEx doCreateConsoleEditor() {
protected final EditorEx doCreateConsoleEditor() {
return myHistoryViewer;
}
@Override
protected void disposeEditor() {
protected final void disposeEditor() {
}
@Override
protected JComponent createCenterComponent() {
protected final JComponent createCenterComponent() {
initComponents();
return myPanel;
}
@@ -183,7 +169,7 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
myPanel.removeAll();
if (consoleEditorEnabled) {
FileEditorManager.getInstance(getProject()).closeFile(myVirtualFile);
FileEditorManager.getInstance(getProject()).closeFile(getVirtualFile());
setHistoryScrollBarVisible(false);
myPanel.add(myHistoryViewer.getComponent());
@@ -210,8 +196,8 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
}
private void setupComponents() {
setupEditorDefault(myConsoleEditor);
setupEditorDefault(myHistoryViewer);
myHelper.setupEditor(myConsoleEditor);
myHelper.setupEditor(myHistoryViewer);
myHistoryViewer.getComponent().setMinimumSize(JBUI.emptySize());
myHistoryViewer.getComponent().setPreferredSize(JBUI.emptySize());
@@ -219,7 +205,7 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
myConsoleEditor.addEditorMouseListener(EditorActionUtil.createEditorPopupHandler(IdeActions.GROUP_CONSOLE_EDITOR_POPUP));
myConsoleEditor.setHighlighter(
EditorHighlighterFactory.getInstance().createEditorHighlighter(myVirtualFile, myConsoleEditor.getColorsScheme(), myProject));
EditorHighlighterFactory.getInstance().createEditorHighlighter(getVirtualFile(), myConsoleEditor.getColorsScheme(), getProject()));
myConsoleEditor.getScrollPane().getHorizontalScrollBar().setModel(
myHistoryViewer.getScrollPane().getHorizontalScrollBar().getModel());
@@ -238,20 +224,12 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
EmptyAction.registerActionShortcuts(myHistoryViewer.getComponent(), myConsoleEditor.getComponent());
}
public boolean isConsoleEditorEnabled() {
public final boolean isConsoleEditorEnabled() {
return myPanel.getComponentCount() > 1;
}
protected void setupEditorDefault(@NotNull EditorEx editor) {
ConsoleViewUtil.setupConsoleEditor(editor, false, false);
editor.getContentComponent().setFocusCycleRoot(false);
editor.setHorizontalScrollbarVisible(true);
editor.setVerticalScrollbarVisible(true);
editor.setBorder(null);
EditorSettings editorSettings = editor.getSettings();
editorSettings.setAdditionalLinesCount(1);
editorSettings.setAdditionalColumnsCount(1);
myHelper.setupEditor(editor);
}
@Nullable
@@ -293,42 +271,37 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
}
@NotNull
public PsiFile getFile() {
return myFile;
public final PsiFile getFile() {
return myHelper.getFileSafe();
}
@NotNull
public VirtualFile getVirtualFile() {
return myVirtualFile;
public final VirtualFile getVirtualFile() {
return myHelper.virtualFile;
}
@NotNull
public EditorEx getHistoryViewer() {
public final EditorEx getHistoryViewer() {
return myHistoryViewer;
}
@NotNull
public Document getEditorDocument() {
public final Document getEditorDocument() {
return myEditorDocument;
}
@NotNull
public EditorEx getConsoleEditor() {
public final EditorEx getConsoleEditor() {
return myConsoleEditor;
}
@NotNull
public Project getProject() {
return myProject;
}
@NotNull
public String getTitle() {
return myTitle;
return myHelper.title;
}
public void setTitle(@NotNull String title) {
myTitle = title;
myHelper.setTitle(title);
}
public String addToHistory(@NotNull TextRange textRange, @NotNull EditorEx editor, boolean preserveMarkup) {
@@ -461,8 +434,8 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
if (getProject().isOpen()) {
FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
if (editorManager.isFileOpen(myVirtualFile)) {
editorManager.closeFile(myVirtualFile);
if (editorManager.isFileOpen(getVirtualFile())) {
editorManager.closeFile(getVirtualFile());
}
}
}
@@ -488,7 +461,7 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
FileEditorManagerAdapter fileEditorListener = new FileEditorManagerAdapter() {
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
if (myConsoleEditor == null || !Comparing.equal(file, myVirtualFile)) {
if (myConsoleEditor == null || !Comparing.equal(file, getVirtualFile())) {
return;
}
@@ -509,7 +482,7 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
@Override
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
if (!Comparing.equal(file, myVirtualFile)) {
if (!Comparing.equal(file, getVirtualFile())) {
return;
}
if (!Boolean.TRUE.equals(file.getUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN))) {
@@ -521,8 +494,8 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
};
myBusConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, fileEditorListener);
FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
if (editorManager.isFileOpen(myVirtualFile)) {
fileEditorListener.fileOpened(editorManager, myVirtualFile);
if (editorManager.isFileOpen(getVirtualFile())) {
fileEditorListener.fileOpened(editorManager, getVirtualFile());
}
}
@@ -533,18 +506,12 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
@NotNull
public Language getLanguage() {
return myFile.getLanguage();
return getFile().getLanguage();
}
public void setLanguage(@NotNull Language language) {
if (!(myVirtualFile instanceof LightVirtualFile)) {
throw new UnsupportedOperationException();
}
LightVirtualFile virtualFile = (LightVirtualFile)myVirtualFile;
virtualFile.setLanguage(language);
virtualFile.setContent(myEditorDocument, myEditorDocument.getText(), false);
FileContentUtil.reparseFiles(myProject, Collections.<VirtualFile>singletonList(virtualFile), false);
myFile = createFile(myProject, virtualFile);
myHelper.setLanguage(language);
myHelper.getFileSafe();
}
public void setInputText(@NotNull final String query) {
@@ -556,11 +523,6 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
});
}
@NotNull
protected PsiFile createFile(@NotNull Project project, @NotNull VirtualFile virtualFile) {
return PsiUtilCore.getPsiFile(project, virtualFile);
}
boolean isHistoryViewerForceAdditionalColumnsUsage() {
return true;
}
@@ -569,6 +531,64 @@ public class LanguageConsoleImpl extends ConsoleViewImpl implements LanguageCons
return 2;
}
public static class Helper {
public final Project project;
public final VirtualFile virtualFile;
String title;
PsiFile file;
public Helper(@NotNull Project project, @NotNull VirtualFile virtualFile) {
this.project = project;
this.virtualFile = virtualFile;
title = virtualFile.getName();
}
public Helper setTitle(String title) {
this.title = title;
return this;
}
@NotNull
public PsiFile getFile() {
return PsiUtilCore.getPsiFile(project, virtualFile);
}
@NotNull
public Document getDocument() {
Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
if (document == null) {
throw new AssertionError("no document for: " + virtualFile);
}
return document;
}
public void setLanguage(Language language) {
if (!(virtualFile instanceof LightVirtualFile)) {
throw new UnsupportedOperationException();
}
((LightVirtualFile)virtualFile).setLanguage(language);
((LightVirtualFile)virtualFile).setContent(getDocument(), getDocument().getText(), false);
FileContentUtil.reparseFiles(project, Collections.singletonList(virtualFile), false);
}
public void setupEditor(@NotNull EditorEx editor) {
ConsoleViewUtil.setupConsoleEditor(editor, false, false);
editor.getContentComponent().setFocusCycleRoot(false);
editor.setHorizontalScrollbarVisible(true);
editor.setVerticalScrollbarVisible(true);
editor.setBorder(null);
EditorSettings editorSettings = editor.getSettings();
editorSettings.setAdditionalLinesCount(1);
editorSettings.setAdditionalColumnsCount(1);
}
@NotNull
PsiFile getFileSafe() {
return file == null || !file.isValid() ? file = getFile() : file;
}
}
private class MyLayout extends AbstractLayoutManager {
@Override
public Dimension preferredLayoutSize(final Container parent) {
@@ -19,7 +19,6 @@ import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiType;
import com.intellij.testFramework.LightVirtualFile;
@@ -42,52 +41,51 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
public class GroovyShellLanguageConsoleView extends LanguageConsoleImpl {
public GroovyShellLanguageConsoleView(Project project, String name) {
super(project, name, GroovyLanguage.INSTANCE);
}
@NotNull
@Override
protected PsiFile createFile(@NotNull Project project,
@NotNull VirtualFile virtualFile) {
return new GroovyShellCodeFragment(project, (LightVirtualFile)virtualFile);
super(new Helper(project, new LightVirtualFile(name, GroovyLanguage.INSTANCE, "")) {
@NotNull
@Override
public PsiFile getFile() {
return new GroovyShellCodeFragment(project, (LightVirtualFile)virtualFile);
}
});
}
protected void processCode() {
for (GrTopStatement statement : getFile().getTopStatements()) {
GroovyShellCodeFragment groovyFile = getGroovyFile();
for (GrTopStatement statement : groovyFile.getTopStatements()) {
if (statement instanceof GrImportStatement) {
getFile().addImportsFromString(importToString((GrImportStatement)statement));
groovyFile.addImportsFromString(importToString((GrImportStatement)statement));
}
else if (statement instanceof GrMethod) {
getFile().addVariable(((GrMethod)statement).getName(), generateClosure((GrMethod)statement));
groovyFile.addVariable(((GrMethod)statement).getName(), generateClosure((GrMethod)statement));
}
else if (statement instanceof GrAssignmentExpression) {
GrAssignmentExpression assignment = (GrAssignmentExpression)statement;
GrExpression left = assignment.getLValue();
if (left instanceof GrReferenceExpression && !((GrReferenceExpression)left).isQualified()) {
getFile().addVariable(((GrReferenceExpression)left).getReferenceName(), assignment.getRValue());
groovyFile.addVariable(((GrReferenceExpression)left).getReferenceName(), assignment.getRValue());
}
}
else if (statement instanceof GrTypeDefinition) {
getFile().addTypeDefinition(prepareTypeDefinition((GrTypeDefinition)statement));
groovyFile.addTypeDefinition(prepareTypeDefinition((GrTypeDefinition)statement));
}
}
PsiType scriptType = getFile().getInferredScriptReturnType();
PsiType scriptType = groovyFile.getInferredScriptReturnType();
if (scriptType != null) {
getFile().addVariable("_", scriptType);
groovyFile.addVariable("_", scriptType);
}
}
@Override
@NotNull
public GroovyShellCodeFragment getFile() {
return (GroovyShellCodeFragment)myFile;
public GroovyShellCodeFragment getGroovyFile() {
return (GroovyShellCodeFragment)getFile();
}
@NotNull
private GrTypeDefinition prepareTypeDefinition(@NotNull GrTypeDefinition typeDefinition) {
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(getProject());
GroovyFile file = factory.createGroovyFile("", false, myFile);
GroovyFile file = factory.createGroovyFile("", false, getFile());
return (GrTypeDefinition)file.add(typeDefinition);
}
@@ -105,7 +103,7 @@ public class GroovyShellLanguageConsoleView extends LanguageConsoleImpl {
if (parameters.length > 0) buffer.delete(buffer.length() - 1, buffer.length());
buffer.append("->}");
return factory.createClosureFromText(buffer.toString(), myFile);
return factory.createClosureFromText(buffer.toString(), getFile());
}
@Nullable
@@ -151,14 +149,14 @@ public class GroovyShellLanguageConsoleView extends LanguageConsoleImpl {
}
private void clearVariables() {
getFile().clearVariables();
getGroovyFile().clearVariables();
}
private void clearClasses() {
getFile().clearClasses();
getGroovyFile().clearClasses();
}
private void clearImports() {
getFile().clearImports();
getGroovyFile().clearImports();
}
}
@@ -31,6 +31,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.Consumer;
import com.jetbrains.commandInterface.command.Command;
import com.jetbrains.commandInterface.command.CommandExecutor;
@@ -122,7 +123,16 @@ final class CommandConsole extends LanguageConsoleImpl implements Consumer<Strin
private CommandConsole(@NotNull final Module module,
@NotNull final String title,
@Nullable final Pair<List<Command>, CommandExecutor> commandsAndDefaultExecutor) {
super(module.getProject(), title, CommandLineLanguage.INSTANCE);
super(new Helper(module.getProject(), new LightVirtualFile(title, CommandLineLanguage.INSTANCE, "")) {
@Override
public void setupEditor(@NotNull EditorEx editor) {
super.setupEditor(editor);
// We do not need spaces here, because it leads to PY-15557
EditorSettings editorSettings = editor.getSettings();
editorSettings.setAdditionalLinesCount(0);
editorSettings.setAdditionalColumnsCount(0);
}
});
myCommandsAndDefaultExecutor = commandsAndDefaultExecutor;
myModule = module;
}
@@ -297,12 +307,4 @@ final class CommandConsole extends LanguageConsoleImpl implements Consumer<Strin
}
}
@Override
protected void setupEditorDefault(@NotNull final EditorEx editor) {
super.setupEditorDefault(editor);
// We do not need spaces here, because it leads to PY-15557
final EditorSettings editorSettings = editor.getSettings();
editorSettings.setAdditionalLinesCount(0);
editorSettings.setAdditionalColumnsCount(0);
}
}