Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2015-02-24 20:52:26 +03:00
54 changed files with 1520 additions and 825 deletions
@@ -27,8 +27,8 @@ import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.debugger.ui.DebuggerSessionTab;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -70,7 +70,7 @@ public class ThreadDumpAction extends AnAction implements AnAction.TransparentUp
public void run() {
XDebugSession xSession = session.getXDebugSession();
if (xSession != null) {
DebuggerSessionTab.addThreadDump(project, threads, xSession.getUI(), session);
DebuggerUtilsEx.addThreadDump(project, threads, xSession.getUI(), session);
}
}
}, ModalityState.NON_MODAL);
@@ -33,7 +33,14 @@ import com.intellij.debugger.requests.Requestor;
import com.intellij.debugger.ui.CompletionEditor;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.execution.filters.ExceptionFilters;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -47,6 +54,9 @@ import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.ui.content.Content;
import com.intellij.unscramble.ThreadDumpPanel;
import com.intellij.unscramble.ThreadState;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XSourcePosition;
@@ -399,6 +409,43 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
return null;
}
private static int myThreadDumpsCount = 0;
private static int myCurrentThreadDumpId = 1;
private static final String THREAD_DUMP_CONTENT_PREFIX = "Dump";
public static void addThreadDump(Project project, List<ThreadState> threads, final RunnerLayoutUi ui, DebuggerSession session) {
final TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
consoleBuilder.filters(ExceptionFilters.getFilters(session.getSearchScope()));
final ConsoleView consoleView = consoleBuilder.getConsole();
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
consoleView.allowHeavyFilters();
final ThreadDumpPanel panel = new ThreadDumpPanel(project, consoleView, toolbarActions, threads);
final String id = THREAD_DUMP_CONTENT_PREFIX + " #" + myCurrentThreadDumpId;
final Content content = ui.createContent(id, panel, id, null, null);
content.setCloseable(true);
content.setDescription("Thread Dump");
ui.addContent(content);
ui.selectAndFocus(content, true, true);
myThreadDumpsCount++;
myCurrentThreadDumpId++;
Disposer.register(content, new Disposable() {
@Override
public void dispose() {
myThreadDumpsCount--;
if (myThreadDumpsCount == 0) {
myCurrentThreadDumpId = 1;
}
}
});
Disposer.register(content, consoleView);
ui.selectAndFocus(content, true, false);
if (threads.size() > 0) {
panel.selectStackFrame(0);
}
}
public abstract DebuggerTreeNode getSelectedNode (DataContext context);
public abstract EvaluatorBuilder getEvaluatorBuilder();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -42,6 +42,7 @@ import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugProcessStarter;
import com.intellij.xdebugger.XDebugSession;
@@ -222,12 +223,9 @@ public class DebuggerPanelsManager implements ProjectComponent {
}
private static DebuggerSession getSession(Project project, RunContentDescriptor descriptor) {
for (XDebugSession session : XDebuggerManager.getInstance(project).getDebugSessions()) {
if (session.getRunContentDescriptor().equals(descriptor)) {
XDebugProcess process = session.getDebugProcess();
if (process instanceof JavaDebugProcess) {
return ((JavaDebugProcess)process).getDebuggerSession();
}
for (JavaDebugProcess process : XDebuggerManager.getInstance(project).getDebugProcesses(JavaDebugProcess.class)) {
if (Comparing.equal(process.getProcessHandler(), descriptor.getProcessHandler())) {
return process.getDebuggerSession();
}
}
return null;
@@ -36,12 +36,8 @@ import com.intellij.execution.ExecutionManager;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.filters.ExceptionFilters;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ExecutionConsoleEx;
import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.execution.ui.layout.PlaceInGrid;
import com.intellij.icons.AllIcons;
import com.intellij.idea.ActionsBundle;
@@ -56,8 +52,6 @@ import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManagerAdapter;
import com.intellij.ui.content.ContentManagerEvent;
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
import com.intellij.unscramble.ThreadDumpPanel;
import com.intellij.unscramble.ThreadState;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager;
@@ -68,7 +62,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.TreePath;
import java.util.List;
public class DebuggerSessionTab extends DebuggerSessionTabBase implements Disposable {
private static final Logger LOG = Logger.getInstance(DebuggerSessionTab.class);
@@ -84,7 +77,6 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos
private final DebugUIEnvironment myDebugUIEnvironment;
private final ThreadsPanel myThreadsPanel;
private static final String THREAD_DUMP_CONTENT_PREFIX = "Dump";
public DebuggerSessionTab(final Project project, final String sessionName, @NotNull final DebugUIEnvironment environment,
@NotNull DebuggerSession debuggerSession) {
@@ -447,51 +439,6 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos
myUi.selectAndFocus(myUi.findContent(DebuggerContentInfo.FRAME_CONTENT), true, false);
}
private static int myThreadDumpsCount = 0;
private static int myCurrentThreadDumpId = 1;
public static void addThreadDump(Project project, List<ThreadState> threads, final RunnerLayoutUi ui, DebuggerSession session) {
final TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
consoleBuilder.filters(ExceptionFilters.getFilters(session.getSearchScope()));
final ConsoleView consoleView = consoleBuilder.getConsole();
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
consoleView.allowHeavyFilters();
final ThreadDumpPanel panel = new ThreadDumpPanel(project, consoleView, toolbarActions, threads);
final String id = createThreadDumpContentId();
final Content content = ui.createContent(id, panel, id, null, null);
content.setCloseable(true);
content.setDescription("Thread Dump");
ui.addContent(content);
ui.selectAndFocus(content, true, true);
myThreadDumpsCount += 1;
myCurrentThreadDumpId += 1;
//Disposer.register(this, new Disposable() {
// @Override
// public void dispose() {
// ui.removeContent(content, true);
// }
//});
Disposer.register(content, new Disposable() {
@Override
public void dispose() {
myThreadDumpsCount -= 1;
if (myThreadDumpsCount == 0) {
myCurrentThreadDumpId = 1;
}
}
});
Disposer.register(content, consoleView);
ui.selectAndFocus(content, true, false);
if (threads.size() > 0) {
panel.selectStackFrame(0);
}
}
private static String createThreadDumpContentId() {
return THREAD_DUMP_CONTENT_PREFIX + " #" + myCurrentThreadDumpId;
}
private class MyDebuggerStateManager extends DebuggerStateManager {
@Override
public void fireStateChanged(DebuggerContextImpl newContext, int event) {
@@ -165,7 +165,7 @@ class JavaPredefinedConfigurations {
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.typed.symbol"),"'Symbol <'_GenericArgument+>", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.generic.casts"),"( '_Type <'_GenericArgument+> ) '_Expr", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.type.var.substitutions.in.intanceof.with.generic.types"),"'_Expr instanceof '_Type <'Substitutions+> ", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.variables.of.generic.types"),"'_Type <'_GenericArgument+> 'Var = 'Init?;", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.variables.of.generic.types"),"'_Type <'_GenericArgument+> 'Var = '_Init?;", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.diamond.operators"), "new 'ClassName<>('_Argument*)", GENERICS_TYPE),
// Add comments and metadata
@@ -226,7 +226,7 @@ class JavaPredefinedConfigurations {
" public void ejbRemove();\n" +
"}", J2EE_TYPE),
createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.ejb.interface"),"interface 'EjbInterface extends EJBObject {\n" +
" 'Type+ 'Method+('ParamType* 'ParamName*);\n" +
" '_Type+ '_Method+('_ParamType* '_ParamName*);\n" +
"}", J2EE_TYPE),
createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.servlets"),"public class 'Servlet extends '_ParentClass:*HttpServlet {\n" +
" public void '_InitServletMethod?:init ();\n" +
@@ -243,19 +243,19 @@ class JavaPredefinedConfigurations {
// Misc types
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.serializable.classes.and.their.serialization.implementation"),
"class '_Class implements '_Serializable:*Serializable {\n" +
" static final long 'VersionField?:serialVersionUID = '_VersionFieldInit?;\n" +
"class 'Class implements '_Serializable:*Serializable {\n" +
" static final long '_VersionField?:serialVersionUID = '_VersionFieldInit?;\n" +
" private static final ObjectStreamField[] '_persistentFields?:serialPersistentFields = '_persistentFieldInitial?; \n" +
" private void 'SerializationWriteHandler?:writeObject (ObjectOutputStream '_stream) throws IOException;\n" +
" private void 'SerializationReadHandler?:readObject (ObjectInputStream '_stream2) throws IOException, ClassNotFoundException;\n" +
" Object 'SpecialSerializationReadHandler?:readResolve () throws ObjectStreamException;\n" +
" Object 'SpecialSerializationWriteHandler?:writeReplace () throws ObjectStreamException;\n" +
" private void '_SerializationWriteHandler?:writeObject (ObjectOutputStream '_stream) throws IOException;\n" +
" private void '_SerializationReadHandler?:readObject (ObjectInputStream '_stream2) throws IOException, ClassNotFoundException;\n" +
" Object '_SpecialSerializationReadHandler?:readResolve () throws ObjectStreamException;\n" +
" Object '_SpecialSerializationWriteHandler?:writeReplace () throws ObjectStreamException;\n" +
"}",MISC_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.cloneable.implementations"),
"class '_Class implements '_Interface:*Cloneable {\n" +
" Object 'CloningMethod:*clone ();\n" +
"}",MISC_TYPE),
createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.]junit.test.cases"),"public class 'TestCase extends 'TestCaseClazz:*TestCase {\n" +
createSearchTemplateInfoSimple(SSRBundle.message("predefined.configuration.]junit.test.cases"),"public class 'TestCase extends '_TestCaseClazz:*TestCase {\n" +
" public void '_testMethod+:test.* ();\n" +
"}", MISC_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.singletons"),"class 'Class {\n" +
@@ -285,7 +285,7 @@ class JavaPredefinedConfigurations {
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.symbol"),"'Symbol",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields.variables.read"),"'Symbol:[read]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields_variables.with.given.name.pattern.updated"),"'Symbol:[regex( name ) && write]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.usage.of.derived.type.in.cast"),"('CastType:*Base ) 'Expr",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.usage.of.derived.type.in.cast"),"('CastType:*[regex( Base )]) '_Expr",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.declarations"),"'_Type:Object|Integer|Boolean|Long|Character|Short|Byte 'Var = '_Value:[exprtype( int|boolean|long|char|short|byte )]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.declarations"),"'_Type:int|boolean|long|char|short|byte 'Var = '_Value:[exprtype( Integer|Boolean|Long|Character|Short|Byte )]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.method.calls"),"'_Instance?.'Call('_BeforeParam*,'_Param:[ exprtype( int|boolean|long|char|short|byte ) && formal( Object|Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
@@ -1,6 +1,7 @@
package com.intellij.refactoring.typeMigration;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiExpression;
@@ -65,7 +66,9 @@ public class TypeConversionDescriptor extends TypeConversionDescriptorBase {
if (getExpression() != null) expression = getExpression();
final Project project = expression.getProject();
final ReplaceOptions options = new ReplaceOptions();
options.setMatchOptions(new MatchOptions());
final MatchOptions matchOptions = new MatchOptions();
matchOptions.setFileType(StdFileTypes.JAVA);
options.setMatchOptions(matchOptions);
final Replacer replacer = new Replacer(project, null);
try {
final String replacement = replacer.testReplace(expression.getText(), getStringToReplace(), getReplaceByString(), options);
@@ -40,12 +40,23 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
@NotNull private S myInitialSettings;
@Nullable
private JBCheckBox myUseAutoImportBox;
@Nullable
private JBCheckBox myCreateEmptyContentRootDirectoriesBox;
private boolean myHideUseAutoImportBox;
@NotNull
private ExternalSystemSettingsControlCustomizer myCustomizer;
protected AbstractExternalProjectSettingsControl(@NotNull S initialSettings) {
this(null, initialSettings, null);
}
protected AbstractExternalProjectSettingsControl(@Nullable Project project,
@NotNull S initialSettings,
@Nullable ExternalSystemSettingsControlCustomizer controlCustomizer) {
myProject = project;
myInitialSettings = initialSettings;
myCustomizer = controlCustomizer == null ? new ExternalSystemSettingsControlCustomizer() : controlCustomizer;
}
@NotNull
@@ -53,27 +64,31 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
return myInitialSettings;
}
public void hideUseAutoImportBox() {
myHideUseAutoImportBox = true;
}
@Override
public void fillUi(@NotNull PaintAwarePanel canvas, int indentLevel) {
myUseAutoImportBox = new JBCheckBox(ExternalSystemBundle.message("settings.label.use.auto.import"));
myUseAutoImportBox.setVisible(!myHideUseAutoImportBox);
canvas.add(myUseAutoImportBox, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
myCreateEmptyContentRootDirectoriesBox =
new JBCheckBox(ExternalSystemBundle.message("settings.label.create.empty.content.root.directories"));
canvas.add(myCreateEmptyContentRootDirectoriesBox, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
if (!myCustomizer.isUseAutoImportBoxHidden()) {
myUseAutoImportBox = new JBCheckBox(ExternalSystemBundle.message("settings.label.use.auto.import"));
canvas.add(myUseAutoImportBox, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
}
if (!myCustomizer.isCreateEmptyContentRootDirectoriesBoxHidden()) {
myCreateEmptyContentRootDirectoriesBox =
new JBCheckBox(ExternalSystemBundle.message("settings.label.create.empty.content.root.directories"));
canvas.add(myCreateEmptyContentRootDirectoriesBox, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
}
fillExtraControls(canvas, indentLevel);
}
protected abstract void fillExtraControls(@NotNull PaintAwarePanel content, int indentLevel);
public boolean isModified() {
return myUseAutoImportBox.isSelected() != getInitialSettings().isUseAutoImport()
|| myCreateEmptyContentRootDirectoriesBox.isSelected() != getInitialSettings().isCreateEmptyContentRootDirectories()
|| isExtraSettingModified();
boolean result = false;
if (!myCustomizer.isUseAutoImportBoxHidden() && myUseAutoImportBox != null) {
result = myUseAutoImportBox.isSelected() != getInitialSettings().isUseAutoImport();
}
if (!myCustomizer.isCreateEmptyContentRootDirectoriesBoxHidden() && myCreateEmptyContentRootDirectoriesBox != null) {
result = result || myCreateEmptyContentRootDirectoriesBox.isSelected() != getInitialSettings().isCreateEmptyContentRootDirectories();
}
return result || isExtraSettingModified();
}
protected abstract boolean isExtraSettingModified();
@@ -83,8 +98,12 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
}
public void reset(boolean isDefaultModuleCreation) {
myUseAutoImportBox.setSelected(getInitialSettings().isUseAutoImport());
myCreateEmptyContentRootDirectoriesBox.setSelected(getInitialSettings().isCreateEmptyContentRootDirectories());
if (!myCustomizer.isUseAutoImportBoxHidden() && myUseAutoImportBox != null) {
myUseAutoImportBox.setSelected(getInitialSettings().isUseAutoImport());
}
if (!myCustomizer.isCreateEmptyContentRootDirectoriesBoxHidden() && myCreateEmptyContentRootDirectoriesBox != null) {
myCreateEmptyContentRootDirectoriesBox.setSelected(getInitialSettings().isCreateEmptyContentRootDirectories());
}
resetExtraSettings(isDefaultModuleCreation);
}
@@ -92,8 +111,13 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
@Override
public void apply(@NotNull S settings) {
settings.setUseAutoImport(myUseAutoImportBox.isSelected());
settings.setCreateEmptyContentRootDirectories(myCreateEmptyContentRootDirectoriesBox.isSelected());
if (!myCustomizer.isUseAutoImportBoxHidden() && myUseAutoImportBox != null) {
settings.setUseAutoImport(myUseAutoImportBox.isSelected());
}
if (!myCustomizer.isCreateEmptyContentRootDirectoriesBoxHidden() && myCreateEmptyContentRootDirectoriesBox != null) {
settings.setCreateEmptyContentRootDirectories(myCreateEmptyContentRootDirectoriesBox.isSelected());
}
if (myInitialSettings.getExternalProjectPath() != null) {
settings.setExternalProjectPath(myInitialSettings.getExternalProjectPath());
}
@@ -112,8 +136,13 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
}
public void updateInitialSettings() {
myInitialSettings.setUseAutoImport(myUseAutoImportBox.isSelected());
myInitialSettings.setCreateEmptyContentRootDirectories(myCreateEmptyContentRootDirectoriesBox.isSelected());
if (!myCustomizer.isUseAutoImportBoxHidden() && myUseAutoImportBox != null) {
myInitialSettings.setUseAutoImport(myUseAutoImportBox.isSelected());
}
if (!myCustomizer.isCreateEmptyContentRootDirectoriesBoxHidden() && myCreateEmptyContentRootDirectoriesBox != null) {
myInitialSettings.setCreateEmptyContentRootDirectories(myCreateEmptyContentRootDirectoriesBox.isSelected());
}
updateInitialExtraSettings();
}
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2015 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 com.intellij.openapi.externalSystem.service.settings;
/**
* @author Vladislav.Soroka
* @since 2/24/2015
*/
public class ExternalSystemSettingsControlCustomizer {
private boolean hideUseAutoImportBox;
private boolean hideCreateEmptyContentRootDirectoriesBox;
public ExternalSystemSettingsControlCustomizer() {
}
public ExternalSystemSettingsControlCustomizer(boolean hideUseAutoImportBox, boolean hideCreateEmptyContentRootDirectoriesBox) {
this.hideUseAutoImportBox = hideUseAutoImportBox;
this.hideCreateEmptyContentRootDirectoriesBox = hideCreateEmptyContentRootDirectoriesBox;
}
public boolean isUseAutoImportBoxHidden() {
return hideUseAutoImportBox;
}
public boolean isCreateEmptyContentRootDirectoriesBoxHidden() {
return hideCreateEmptyContentRootDirectoriesBox;
}
}
@@ -92,6 +92,7 @@ public class ExternalSystemJdkComboBox extends ComboBoxWithWidePopup {
myProject = project;
}
@NotNull
public ExternalSystemJdkComboBox withoutJre() {
suggestJre = false;
return this;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
@@ -59,7 +60,7 @@ public class InstalledPluginsState {
public boolean hasNewerVersion(@NotNull PluginId id) {
synchronized (myLock) {
return !wasUpdated(id) && myUpdateSettings.myOutdatedPlugins.contains(id.getIdString());
return !wasUpdated(id) && myUpdateSettings.getOutdatedPlugins().contains(id.getIdString());
}
}
@@ -89,13 +90,14 @@ public class InstalledPluginsState {
String idString = id.getIdString();
synchronized (myLock) {
List<String> outdatedPlugins = myUpdateSettings.getOutdatedPlugins();
if (newer) {
if (!myUpdateSettings.myOutdatedPlugins.contains(idString)) {
myUpdateSettings.myOutdatedPlugins.add(idString);
if (!outdatedPlugins.contains(idString)) {
outdatedPlugins.add(idString);
}
}
else {
myUpdateSettings.myOutdatedPlugins.remove(idString);
outdatedPlugins.remove(idString);
}
}
}
@@ -108,7 +110,7 @@ public class InstalledPluginsState {
boolean existing = PluginManager.isPluginInstalled(id);
synchronized (myLock) {
myUpdateSettings.myOutdatedPlugins.remove(id.getIdString());
myUpdateSettings.getOutdatedPlugins().remove(id.getIdString());
if (existing) {
myUpdatedPlugins.put(id, descriptor);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -67,13 +67,13 @@ public class PluginHostsConfigurable extends BaseConfigurable {
public void apply() throws ConfigurationException {
UpdateSettings settings = UpdateSettings.getInstance();
settings.myPluginHosts.clear();
settings.myPluginHosts.addAll(myUpdatesSettingsPanel.getPluginsHosts());
settings.getStoredPluginHosts().clear();
settings.getStoredPluginHosts().addAll(myUpdatesSettingsPanel.getPluginsHosts());
}
@Override
public void reset() {
myUpdatesSettingsPanel.setPluginHosts(UpdateSettings.getInstance().myPluginHosts);
myUpdatesSettingsPanel.setPluginHosts(UpdateSettings.getInstance().getStoredPluginHosts());
}
@Override
@@ -82,7 +82,7 @@ public class PluginHostsConfigurable extends BaseConfigurable {
return false;
}
//noinspection EqualsBetweenInconvertibleTypes
return !UpdateSettings.getInstance().myPluginHosts.equals(myUpdatesSettingsPanel.getPluginsHosts());
return !UpdateSettings.getInstance().getStoredPluginHosts().equals(myUpdatesSettingsPanel.getPluginsHosts());
}
@Override
@@ -29,6 +29,7 @@ import com.intellij.openapi.ui.OnePixelDivider;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.components.panels.VerticalLayout;
import com.intellij.ui.treeStructure.SimpleNode;
@@ -40,9 +41,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.*;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -235,7 +234,9 @@ final class SettingsEditor extends AbstractEditor implements DataProvider {
mySpotlightPainter = new SpotlightPainter(myEditor, this) {
void updateNow() {
Configurable configurable = myFilter.myContext.getCurrentConfigurable();
update(myFilter, configurable, myEditor.getContent(configurable));
if (myTreeView.myTree.hasFocus() || mySearch.getTextEditor().hasFocus()) {
update(myFilter, configurable, myEditor.getContent(configurable));
}
}
};
add(BorderLayout.CENTER, mySplitter);
@@ -250,6 +251,29 @@ final class SettingsEditor extends AbstractEditor implements DataProvider {
myFilter.update(filter, false, true);
myTreeView.select(configurable);
Disposer.register(this, myTreeView);
installSpotlightRemover();
}
private void installSpotlightRemover() {
final FocusAdapter spotlightRemover = new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
final Component comp = e.getOppositeComponent();
if (comp == mySearch.getTextEditor() || comp == myTreeView.myTree) {
return;
}
mySpotlightPainter.update(null, null, null);
}
@Override
public void focusGained(FocusEvent e) {
if (!StringUtil.isEmpty(mySearch.getText())) {
mySpotlightPainter.updateNow();
}
}
};
myTreeView.myTree.addFocusListener(spotlightRemover);
mySearch.getTextEditor().addFocusListener(spotlightRemover);
}
@Override
@@ -631,7 +631,7 @@ public final class UpdateChecker {
private static boolean ourHasFailedPlugins = false;
public static void checkForUpdate(IdeaLoggingEvent event) {
if (!ourHasFailedPlugins && UpdateSettings.getInstance().CHECK_NEEDED) {
if (!ourHasFailedPlugins && UpdateSettings.getInstance().isCheckNeeded()) {
final Throwable throwable = event.getThrowable();
final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(IdeErrorsDialog.findPluginId(throwable));
if (pluginDescriptor != null && !pluginDescriptor.isBundled()) {
@@ -25,6 +25,7 @@ import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginsAdvertiser;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Alarm;
import com.intellij.util.net.NetUtils;
@@ -54,12 +55,13 @@ public class UpdateCheckerComponent implements ApplicationComponent {
public UpdateCheckerComponent(@NotNull Application app, @NotNull UpdateSettings settings) {
mySettings = settings;
if (mySettings.SECURE_CONNECTION && !NetUtils.isSniEnabled()) {
if (mySettings.isSecureConnection() && !NetUtils.isSniEnabled()) {
app.invokeLater(new Runnable() {
@Override
public void run() {
String title = IdeBundle.message("update.notifications.title");
String message = IdeBundle.message("update.sni.disabled.notification");
boolean tooOld = !SystemInfo.isJavaVersionAtLeast("1.7");
String message = IdeBundle.message(tooOld ? "update.sni.not.available.notification" : "update.sni.disabled.notification");
UpdateChecker.NOTIFICATIONS.createNotification(title, message, NotificationType.ERROR, null).notify(null);
}
}, ModalityState.NON_MODAL);
@@ -74,7 +76,7 @@ public class UpdateCheckerComponent implements ApplicationComponent {
}
private void scheduleOnStartCheck(@NotNull Application app) {
if (!mySettings.CHECK_NEEDED || mySettings.SECURE_CONNECTION && !NetUtils.isSniEnabled()) {
if (!mySettings.isCheckNeeded() || mySettings.isSecureConnection() && !NetUtils.isSniEnabled()) {
return;
}
@@ -82,9 +84,9 @@ public class UpdateCheckerComponent implements ApplicationComponent {
@Override
public void appFrameCreated(String[] commandLineArgs, @NotNull Ref<Boolean> willOpenProject) {
String currentBuild = ApplicationInfo.getInstance().getBuild().asString();
long timeToNextCheck = mySettings.LAST_TIME_CHECKED + CHECK_INTERVAL - System.currentTimeMillis();
long timeToNextCheck = mySettings.getLastTimeChecked() + CHECK_INTERVAL - System.currentTimeMillis();
if (StringUtil.compareVersionNumbers(mySettings.LAST_BUILD_CHECKED, currentBuild) < 0 || timeToNextCheck <= 0) {
if (StringUtil.compareVersionNumbers(mySettings.getLasBuildChecked(), currentBuild) < 0 || timeToNextCheck <= 0) {
myCheckRunnable.run();
}
else {
@@ -18,15 +18,13 @@ package com.intellij.openapi.updateSettings.impl;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.net.NetUtils;
import org.jdom.Element;
import com.intellij.util.xmlb.annotations.CollectionBean;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -38,94 +36,128 @@ import java.util.List;
@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml", deprecated = true)
}
)
public class UpdateSettings implements PersistentStateComponent<Element>, UserUpdateSettings {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.updateSettings.impl.UpdateSettings");
public JDOMExternalizableStringList myPluginHosts = new JDOMExternalizableStringList();
public JDOMExternalizableStringList myKnownUpdateChannels = new JDOMExternalizableStringList();
public JDOMExternalizableStringList myIgnoredBuildNumbers = new JDOMExternalizableStringList();
public JDOMExternalizableStringList myOutdatedPlugins = new JDOMExternalizableStringList();
public boolean CHECK_NEEDED = true;
public long LAST_TIME_CHECKED = 0;
public String LAST_BUILD_CHECKED = "";
public String UPDATE_CHANNEL_TYPE = ChannelStatus.RELEASE_CODE;
public boolean SECURE_CONNECTION = false;
public static UpdateSettings getInstance() {
return ServiceManager.getService(UpdateSettings.class);
}
public class UpdateSettings implements PersistentStateComponent<UpdateSettings.State>, UserUpdateSettings {
private State myState = new State();
public UpdateSettings() {
updateDefaultChannel();
}
public static UpdateSettings getInstance() {
return ServiceManager.getService(UpdateSettings.class);
}
static class State {
@CollectionBean
public final List<String> pluginHosts = new SmartList<String>();
@CollectionBean
public final List<String> knownUpdateChannels = new SmartList<String>();
@CollectionBean
public final List<String> ignoredBuildNumbers = new SmartList<String>();
@CollectionBean
public final List<String> outdatedPlugins = new SmartList<String>();
public boolean CHECK_NEEDED = true;
public long LAST_TIME_CHECKED = 0;
public String LAST_BUILD_CHECKED;
public String UPDATE_CHANNEL_TYPE = ChannelStatus.RELEASE_CODE;
public boolean SECURE_CONNECTION = false;
}
@Nullable
public String getLasBuildChecked() {
return myState.LAST_BUILD_CHECKED;
}
@NotNull
public List<String> getStoredPluginHosts() {
return myState.pluginHosts;
}
public boolean isCheckNeeded() {
return myState.CHECK_NEEDED;
}
public void setCheckNeeded(boolean value) {
myState.CHECK_NEEDED = value;
}
public boolean isSecureConnection() {
return myState.SECURE_CONNECTION;
}
public void setSecureConnection(boolean value) {
myState.SECURE_CONNECTION = value;
}
@NotNull
public String getUpdateChannelType() {
return myState.UPDATE_CHANNEL_TYPE;
}
public long getLastTimeChecked() {
return myState.LAST_TIME_CHECKED;
}
public void setUpdateChannelType(@NotNull String value) {
myState.UPDATE_CHANNEL_TYPE = value;
}
@NotNull
public List<String> getOutdatedPlugins() {
return myState.outdatedPlugins;
}
private void updateDefaultChannel() {
if (ApplicationInfoImpl.getShadowInstance().isEAP()) {
UPDATE_CHANNEL_TYPE = ChannelStatus.EAP_CODE;
myState.UPDATE_CHANNEL_TYPE = ChannelStatus.EAP_CODE;
}
}
@SuppressWarnings("deprecation")
@Override
public Element getState() {
Element element = new Element("state");
try {
DefaultJDOMExternalizer.writeExternal(this, element);
}
catch (WriteExternalException e) {
LOG.info(e);
}
return element;
public State getState() {
return myState;
}
@SuppressWarnings("deprecation")
@Override
public void loadState(Element state) {
try {
DefaultJDOMExternalizer.readExternal(this, state);
}
catch (InvalidDataException e) {
LOG.info(e);
}
public void loadState(State state) {
myState = state;
myState.LAST_BUILD_CHECKED = StringUtil.nullize(myState.LAST_BUILD_CHECKED);
updateDefaultChannel();
}
@NotNull
@Override
public List<String> getKnownChannelsIds() {
List<String> ids = new ArrayList<String>();
for (String channel : myKnownUpdateChannels) {
ids.add(channel);
}
return ids;
return new ArrayList<String>(myState.knownUpdateChannels);
}
@Override
public void setKnownChannelIds(@NotNull List<String> ids) {
myKnownUpdateChannels.clear();
myState.knownUpdateChannels.clear();
for (String id : ids) {
myKnownUpdateChannels.add(id);
myState.knownUpdateChannels.add(id);
}
}
public void forgetChannelId(String id) {
myKnownUpdateChannels.remove(id);
myState.knownUpdateChannels.remove(id);
}
@Override
public List<String> getIgnoredBuildNumbers() {
return myIgnoredBuildNumbers;
return myState.ignoredBuildNumbers;
}
@NotNull
@Override
public ChannelStatus getSelectedChannelStatus() {
return ChannelStatus.fromCode(UPDATE_CHANNEL_TYPE);
return ChannelStatus.fromCode(myState.UPDATE_CHANNEL_TYPE);
}
public List<String> getPluginHosts() {
List<String> hosts = new ArrayList<String>(myPluginHosts);
List<String> hosts = new ArrayList<String>(myState.pluginHosts);
String pluginHosts = System.getProperty("idea.plugin.hosts");
if (pluginHosts != null) {
ContainerUtil.addAll(hosts, pluginHosts.split(";"));
@@ -134,15 +166,15 @@ public class UpdateSettings implements PersistentStateComponent<Element>, UserUp
}
public void forceCheckForUpdateAfterRestart() {
LAST_TIME_CHECKED = 0;
myState.LAST_TIME_CHECKED = 0;
}
public void saveLastCheckedInfo() {
LAST_TIME_CHECKED = System.currentTimeMillis();
LAST_BUILD_CHECKED = ApplicationInfo.getInstance().getBuild().asString();
myState.LAST_TIME_CHECKED = System.currentTimeMillis();
myState.LAST_BUILD_CHECKED = ApplicationInfo.getInstance().getBuild().asString();
}
public boolean canUseSecureConnection() {
return SECURE_CONNECTION && NetUtils.isSniEnabled();
return myState.SECURE_CONNECTION && NetUtils.isSniEnabled();
}
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.util.net.NetUtils;
import com.intellij.util.text.DateFormatUtil;
@@ -64,6 +65,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear
return "preferences.updates";
}
@Override
@NotNull
public String getId() {
return getHelpTopic();
@@ -79,9 +81,9 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear
public void apply() throws ConfigurationException {
UpdateSettings settings = UpdateSettings.getInstance();
boolean wasEnabled = settings.CHECK_NEEDED;
settings.CHECK_NEEDED = myUpdatesSettingsPanel.myCheckForUpdates.isSelected();
if (wasEnabled != settings.CHECK_NEEDED) {
boolean wasEnabled = settings.isCheckNeeded();
settings.setCheckNeeded(myUpdatesSettingsPanel.myCheckForUpdates.isSelected());
if (wasEnabled != settings.isCheckNeeded()) {
UpdateCheckerComponent checker = ApplicationManager.getApplication().getComponent(UpdateCheckerComponent.class);
if (checker != null) {
if (wasEnabled) {
@@ -93,27 +95,33 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear
}
}
settings.UPDATE_CHANNEL_TYPE = myUpdatesSettingsPanel.getSelectedChannelType().getCode();
settings.SECURE_CONNECTION = myUpdatesSettingsPanel.myUseSecureConnection.isSelected();
settings.setUpdateChannelType(myUpdatesSettingsPanel.getSelectedChannelType().getCode());
settings.setSecureConnection(myUpdatesSettingsPanel.myUseSecureConnection.isSelected());
}
@Override
public void reset() {
UpdateSettings settings = UpdateSettings.getInstance();
myUpdatesSettingsPanel.myCheckForUpdates.setSelected(settings.CHECK_NEEDED);
myUpdatesSettingsPanel.myUseSecureConnection.setSelected(settings.SECURE_CONNECTION);
myUpdatesSettingsPanel.myCheckForUpdates.setSelected(settings.isCheckNeeded());
myUpdatesSettingsPanel.myUseSecureConnection.setSelected(settings.isSecureConnection());
myUpdatesSettingsPanel.updateLastCheckedLabel();
myUpdatesSettingsPanel.setSelectedChannelType(ChannelStatus.fromCode(settings.UPDATE_CHANNEL_TYPE));
myUpdatesSettingsPanel.setSelectedChannelType(ChannelStatus.fromCode(settings.getUpdateChannelType()));
}
@Override
public boolean isModified() {
if (myUpdatesSettingsPanel == null) return false;
if (myUpdatesSettingsPanel == null) {
return false;
}
UpdateSettings settings = UpdateSettings.getInstance();
if (settings.CHECK_NEEDED != myUpdatesSettingsPanel.myCheckForUpdates.isSelected()) return true;
if (settings.SECURE_CONNECTION != myUpdatesSettingsPanel.myUseSecureConnection.isSelected()) return true;
if (settings.isCheckNeeded() != myUpdatesSettingsPanel.myCheckForUpdates.isSelected() ||
settings.isSecureConnection() != myUpdatesSettingsPanel.myUseSecureConnection.isSelected()) {
return true;
}
Object channel = myUpdatesSettingsPanel.myUpdateChannels.getSelectedItem();
return channel != null && !channel.equals(ChannelStatus.fromCode(settings.UPDATE_CHANNEL_TYPE));
return channel != null && !channel.equals(ChannelStatus.fromCode(settings.getUpdateChannelType()));
}
@Override
@@ -148,12 +156,13 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear
myBuildNumber.setText(appInfo.getBuild().asString());
myCheckNow.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myCheckNow));
UpdateSettings settings = new UpdateSettings();
settings.loadState(UpdateSettings.getInstance().getState());
settings.UPDATE_CHANNEL_TYPE = getSelectedChannelType().getCode();
settings.SECURE_CONNECTION = myUseSecureConnection.isSelected();
settings.setUpdateChannelType(getSelectedChannelType().getCode());
settings.setSecureConnection(myUseSecureConnection.isSelected());
UpdateChecker.updateAndShowResult(project, settings);
updateLastCheckedLabel();
}
@@ -163,16 +172,18 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear
UpdateSettings settings = UpdateSettings.getInstance();
//noinspection unchecked
myUpdateChannels.setModel(new CollectionComboBoxModel(ChannelStatus.all(), ChannelStatus.fromCode(settings.UPDATE_CHANNEL_TYPE)));
myUpdateChannels.setModel(new CollectionComboBoxModel(ChannelStatus.all(), ChannelStatus.fromCode(settings.getUpdateChannelType())));
if (!NetUtils.isSniEnabled()) {
myUseSecureConnection.setEnabled(false);
myUseSecureConnection.setToolTipText(IdeBundle.message("update.sni.disabled.notification"));
boolean tooOld = !SystemInfo.isJavaVersionAtLeast("1.7");
String message = IdeBundle.message(tooOld ? "update.sni.not.available.notification" : "update.sni.disabled.notification");
myUseSecureConnection.setToolTipText(message);
}
}
private void updateLastCheckedLabel() {
long time = UpdateSettings.getInstance().LAST_TIME_CHECKED;
long time = UpdateSettings.getInstance().getLastTimeChecked();
myLastCheckedDate.setText(time == 0 ? IdeBundle.message("updates.last.check.never") : DateFormatUtil.formatPrettyDateTime(time));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -220,7 +220,9 @@ public class PluginsAdvertiser implements StartupActivity {
@Override
public void runActivity(@NotNull final Project project) {
if (!UpdateSettings.getInstance().CHECK_NEEDED) return;
if (!UpdateSettings.getInstance().isCheckNeeded()) {
return;
}
final UnknownFeaturesCollector collectorSuggester = UnknownFeaturesCollector.getInstance(project);
final Set<UnknownFeature> unknownFeatures = collectorSuggester.getUnknownFeatures();
final KnownExtensions extensions = loadExtensions();
@@ -944,6 +944,7 @@ update.downloading.patch.error=Failed to download patch file:\n{0}
update.plugins.update.action=&Update
update.restart.plugins.update.action=&Update and Restart
update.shutdown.plugins.update.action=&Update and Shutdown
update.sni.not.available.notification=Secure update is not supported on Java 6. Sorry.
update.sni.disabled.notification=Secure update is impossible with SNI disabled
hierarchy.method.next.occurence.name=Go to next method
@@ -32,6 +32,7 @@ public class StructuralSearchUtil {
@Contract("null -> false")
public static boolean isIdentifier(PsiElement element) {
if (element == null) return false;
final StructuralSearchProfile profile = getProfileByPsiElement(element);
return profile != null && profile.isIdentifier(element);
}
@@ -682,11 +682,9 @@ public class MatcherImpl {
assert targetNode != null : "Could not match down up when no target node";
System.out.println("elementToStartMatching = " + elementToStartMatching.getText());
match(elementToStartMatching);
matchContext.getSink().matchingFinished();
final List<MatchResult> matches = sink.getMatches();
return matches;
return sink.getMatches();
}
private class MatchOneVirtualFile extends MatchOneFile {
@@ -42,6 +42,7 @@ class StringToConstraintsTransformer {
StringBuilder miscBuffer = null;
int anonymousTypedVarsCount = 0;
boolean targetFound = false;
for(int index=0;index < pattern.length();++index) {
char ch = pattern.charAt(index);
@@ -187,6 +188,10 @@ class StringToConstraintsTransformer {
constraint.setMaxCount(maxOccurs);
constraint.setGreedy(greedy);
constraint.setPartOfSearchResults(!anonymous);
if (targetFound && !anonymous) {
throw new MalformedPatternException("Pattern may have only one target");
}
targetFound = !anonymous;
}
if (index < length && pattern.charAt(index) == ':') {
@@ -248,7 +253,19 @@ class StringToConstraintsTransformer {
// eat complete condition
miscBuffer.setLength(0);
for(++index; index < length && ((ch = pattern.charAt(index))!=']' || pattern.charAt(index-1)=='\\'); ++index) {
for(++index; index < length && ((ch = pattern.charAt(index)) != ']' || pattern.charAt(index-1) == '\\'); ++index) {
if (ch == '"') {
miscBuffer.append(ch);
for (++index; index < length && (ch = pattern.charAt(index)) != '"'; ++index) {
if (ch == '\\') {
++index;
if (index >= length) break;
ch = pattern.charAt(index);
}
miscBuffer.append(ch);
}
if (ch != '"') throw new MalformedPatternException(SSRBundle.message("error.expected.end.quote"));
}
miscBuffer.append(ch);
}
if (ch != ']') throw new MalformedPatternException(SSRBundle.message("error.expected.condition.or.bracket"));
@@ -26,10 +26,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.structuralsearch.MatchVariableConstraint;
import com.intellij.structuralsearch.NamedScriptableDefinition;
import com.intellij.structuralsearch.ReplacementVariableDefinition;
import com.intellij.structuralsearch.SSRBundle;
import com.intellij.structuralsearch.*;
import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
@@ -111,7 +108,6 @@ class EditVarConstraintsDialog extends DialogWrapper {
regexprForExprType.getDocument().addDocumentListener(new MyDocumentListener(exprTypeWithinHierarchy, notExprType));
formalArgType.getDocument().addDocumentListener(new MyDocumentListener(formalArgTypeWithinHierarchy, invertFormalArgType));
partOfSearchResults.setEnabled(!replaceContext); // todo: this doesn't do anything
containedInConstraints.setVisible(false);
withinCombo.getComboBox().setEditable(true);
@@ -297,7 +293,16 @@ class EditVarConstraintsDialog extends DialogWrapper {
varInfo.setWithinHierarchy(applyWithinTypeHierarchy.isSelected());
varInfo.setInvertRegExp(notRegexp.isSelected());
varInfo.setPartOfSearchResults(partOfSearchResults.isEnabled() && partOfSearchResults.isSelected());
final boolean target = partOfSearchResults.isSelected();
if (target) {
final MatchOptions matchOptions = configuration.getMatchOptions();
for (String name : matchOptions.getVariableConstraintNames()) {
if (!name.equals(varName)) {
matchOptions.getVariableConstraint(name).setPartOfSearchResults(false);
}
}
}
varInfo.setPartOfSearchResults(target);
varInfo.setInvertExprType(notExprType.isSelected());
varInfo.setNameOfExprType(regexprForExprType.getDocument().getText());
@@ -357,7 +362,8 @@ class EditVarConstraintsDialog extends DialogWrapper {
setSearchConstraintsVisible(true);
}
MatchVariableConstraint varInfo = configuration.getMatchOptions().getVariableConstraint(varName);
final MatchOptions matchOptions = configuration.getMatchOptions();
final MatchVariableConstraint varInfo = matchOptions.getVariableConstraint(varName);
if (varInfo == null) {
notRead.setSelected(false);
@@ -371,7 +377,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
maxoccurs.setText("1");
maxoccursUnlimited.setSelected(false);
applyWithinTypeHierarchy.setSelected(false);
partOfSearchResults.setSelected(false);
partOfSearchResults.setSelected(isTarget(varName, matchOptions));
regexprForExprType.getDocument().setText("");
notExprType.setSelected(false);
@@ -406,7 +412,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
maxoccurs.setText(Integer.toString(varInfo.getMaxCount()));
}
partOfSearchResults.setSelected( partOfSearchResults.isEnabled() && varInfo.isPartOfSearchResults() );
partOfSearchResults.setSelected(isTarget(varName, matchOptions));
exprTypeWithinHierarchy.setSelected(varInfo.isExprTypeWithinHierarchy());
regexprForExprType.getDocument().setText(varInfo.getNameOfExprType());
@@ -427,10 +433,29 @@ class EditVarConstraintsDialog extends DialogWrapper {
containedInConstraints.setVisible(contextVar);
textConstraintsPanel.setVisible(!contextVar);
expressionConstraints.setVisible(!contextVar);
partOfSearchResults.setVisible(!contextVar);
partOfSearchResults.setEnabled(!contextVar);
occurencePanel.setVisible(!contextVar);
}
private static boolean isTarget(String varName, MatchOptions matchOptions) {
if (Configuration.CONTEXT_VAR_NAME.equals(varName)) {
// Complete Match is default target
for (String name : matchOptions.getVariableConstraintNames()) {
if (!name.equals(Configuration.CONTEXT_VAR_NAME)) {
if (matchOptions.getVariableConstraint(name).isPartOfSearchResults()) {
return false;
}
}
}
return true;
}
final MatchVariableConstraint constraint = matchOptions.getVariableConstraint(varName);
if (constraint == null) {
return false;
}
return constraint.isPartOfSearchResults();
}
private void setSearchConstraintsVisible(boolean b) {
textConstraintsPanel.setVisible(b);
occurencePanel.setVisible(b);
@@ -210,10 +210,11 @@ error.two.different.type.constraints=Two different type constraints
error.incorrect.regexp.constraint=Incorrect reg exp constraint:{0} for {1}
error.expected.character=Character expected after single quote
error.overflow=Value overflow
error.expected.brace1="Digit, '}' or ',' expected"
error.expected.brace2="Digit or '}' expected"
error.expected.brace1=Digit, '}' or ',' expected
error.expected.brace2=Digit or '}' expected
error.expected.condition=Condition expected after ''{0}''
error.expected.condition.or.bracket=Condition or ']' expected
error.expected.end.quote='"' expected
invalid.modifier.type=Invalid modifier type {0}
SSRInspection.replace.with=Replace with ''{0}''
@@ -1 +1 @@
assertTrue(StrictMath.abs('v1 - 'v2) < 't);
assertTrue(StrictMath.abs('_v1 - '_v2) < '_t);
@@ -22,8 +22,8 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
public void testReplaceInLiterals() {
String s1 = "String ID_SPEED = \"Speed\";";
String s2 = "String 'name = \"'string\";";
String s2_2 = "String 'name = \"'string:[regex( .* )]\";";
String s2 = "String 'name = \"'_string\";";
String s2_2 = "String 'name = \"'_string:[regex( .* )]\";";
String s3 = "VSegAttribute $name$ = new VSegAttribute(\"$string$\");";
String expectedResult = "VSegAttribute ID_SPEED = new VSegAttribute(\"Speed\");";
@@ -58,7 +58,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String s7 = "IconLoader.getIcon(\"/ant/property.png\");\n" +
"IconLoader.getIcon(\"/ant/another/property.png\");\n";
String s8 = "IconLoader.getIcon(\"/'module/'name:[regex( \\w+ )].png\");";
String s8 = "IconLoader.getIcon(\"/'_module/'_name:[regex( \\w+ )].png\");";
String s9 = "Icons.$module$.$name$;";
String expectedResult3 = "Icons.ant.property;\n" +
"IconLoader.getIcon(\"/ant/another/property.png\");\n";
@@ -101,7 +101,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" JOptionPane.showMessageDialog(null, \"MESSAGE\");\n" +
" }\n" +
"}";
String s2 = "JOptionPane.'showDialog(null, 'msg);";
String s2 = "JOptionPane.'showDialog(null, '_msg);";
String s3 = "//FIXME provide a parent frame\n" +
"JOptionPane.$showDialog$(null, $msg$);";
@@ -125,7 +125,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
);
String s4 = "myButton.setText(\"Ok\");";
String s5 = "'Instance.'MethodCall:[regex( setText )]('Parameter*:[regex( \"Ok\" )]);";
String s5 = "'_Instance.'_MethodCall:[regex( setText )]('_Parameter*:[regex( \"Ok\" )]);";
String s6 = "$Instance$.$MethodCall$(\"OK\");";
String expectedResult2 = "myButton.setText(\"OK\");";
@@ -155,9 +155,9 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" matches = testMatcher.findMatches(s7,s8, options);\n" +
" if (matches.size()!=2) return false;";
String str2=" lastTest = 'Descr;\n" +
" matches = testMatcher.findMatches('In,'Pattern, options);\n" +
" if (matches.size()!='Number) return false;";
String str2=" lastTest = '_Descr;\n" +
" matches = testMatcher.findMatches('_In,'_Pattern, options);\n" +
" if (matches.size()!='_Number) return false;";
String str3 = "assertEquals($Descr$,testMatcher.findMatches($In$,$Pattern$, options).size(),$Number$);";
String expectedResult1 = "// searching for several constructions\n" +
" lastTest = \"several constructions match\";\n" +
@@ -191,7 +191,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
assertEquals("Empty replacement",expectedResult2,actualResult);
String str5 = "testMatcher.findMatches('In,'Pattern, options).size()";
String str5 = "testMatcher.findMatches('_In,'_Pattern, options).size()";
String str6 = "findMatchesCount($In$,$Pattern$)";
String expectedResult3="// searching for several constructions\n" +
" lastTest = \"several constructions match\";\n" +
@@ -220,9 +220,9 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" if (asyncMode) {\n" +
" myTreeModel.nodesWereInserted(parentNode,new int[] {i} );\n" +
" }";
String str11 = " 'parentNode.insert('newNode, 'i);\n" +
String str11 = " '_parentNode.insert('_newNode, '_i);\n" +
" if (asyncMode) {\n" +
" myTreeModel.nodesWereInserted('parentNode,new int[] {'i} );\n" +
" myTreeModel.nodesWereInserted('_parentNode,new int[] {'_i} );\n" +
" }";
String str12 = "addChild($parentNode$,$newNode$, $i$);";
String expectedResult5 = " addChild(parentNode,compositeNode, i);";
@@ -231,7 +231,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
assertEquals( "Array initializer replacement", expectedResult5,actualResult);
String str13 = " aaa(5,6,3,4,1,2);";
String str14 = "aaa('t{2,2},3,4,'q{2,2});";
String str14 = "aaa('_t{2,2},3,4,'_q{2,2});";
String str15 = "aaa($q$,3,4,$t$);";
String expectedResult6 = " aaa(1,2,3,4,5,6);";
@@ -239,7 +239,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
assertEquals("Parameter multiple match",expectedResult6,actualResult);
String str16 = " int c = a();";
String str17 = "'t:a ('q*,'p*)";
String str17 = "'_t:a ('_q*,'_p*)";
String str18 = "$t$($q$,1,$p$)";
String expectedResult7 = " int c = a(1);";
@@ -255,7 +255,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
assertEquals("One substition replacement",expectedResult8,actualResult);
String str22 = " instance.setAAA(anotherInstance.getBBB());";
String str23 = " 'i.'m:set(.+) ('a.'m2:get(.+) ());";
String str23 = " '_i.'_m:set(.+) ('_a.'_m2:get(.+) ());";
String str24 = " $a$.set$m2_1$( $i$.get$m_1$() );";
String expectedResult9 = " anotherInstance.setBBB( instance.getAAA() );";
@@ -291,7 +291,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String str28 = "UTElementNode elementNode = new UTElementNode(myProject, processedElement, psiFile,\n" +
" processedElement.getTextOffset(), true,\n" +
" !myUsageViewDescriptor.toMarkInvalidOrReadonlyUsages(), null);";
String str29 = "new UTElementNode('param, 'directory, 'null, '0, 'true, !'descr.toMarkInvalidOrReadonlyUsages(),\n" +
String str29 = "new UTElementNode('_param, '_directory, '_null, '_0, '_true, !'_descr.toMarkInvalidOrReadonlyUsages(),\n" +
" 'referencesWord)";
String str30 = "new UTElementNode($param$, $directory$, $null$, $0$, $true$, true,\n" +
" $referencesWord$)";
@@ -314,7 +314,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
);
String s34 = "ParamChecker.isTrue(1==1, \"!!!\");";
String s35 = "ParamChecker.isTrue('expr, 'msg)";
String s35 = "ParamChecker.isTrue('_expr, '_msg)";
String s36 = "assert $expr$ : $msg$";
String expectedResult13 = "assert 1==1 : \"!!!\";";
@@ -346,7 +346,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
);
String s40 = "ParamChecker.instanceOf(queryKey, GroupBySqlTypePolicy.GroupKey.class);";
String s41 = "ParamChecker.instanceOf('obj, 'class.class);";
String s41 = "ParamChecker.instanceOf('_obj, '_class.class);";
String s42 = "assert $obj$ instanceof $class$ : \"$obj$ is an instance of \" + $obj$.getClass() + \"; expected \" + $class$.class;";
String expectedResult15 = "assert queryKey instanceof GroupBySqlTypePolicy.GroupKey : \"queryKey is an instance of \" + queryKey.getClass() + \"; expected \" + GroupBySqlTypePolicy.GroupKey.class;";
@@ -361,7 +361,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" static final String TAG_BEAN_VALUE = \"\";\n" +
"}\n" +
"XmlTag beanTag = rootTag.findSubTag(Wpd.TAG_BEAN_VALUE);";
String s44 = "'Instance?.findSubTag( 'Parameter:[exprtype( *String ) ])";
String s44 = "'_Instance?.findSubTag( '_Parameter:[exprtype( *String ) ])";
String s45 = "jetbrains.fabrique.util.XmlApiUtil.findSubTag($Instance$, $Parameter$)";
String expectedResult16 = "class Wpd {\n" +
" static final String TAG_BEAN_VALUE = \"\";\n" +
@@ -398,7 +398,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String s49 = "class A {}\n" +
"class B extends A {}\n" +
"A a = new B();";
String s50 = "A 'b = new 'B:*A ();";
String s50 = "A '_b = new '_B:*A ();";
String s51 = "A $b$ = new $B$(\"$b$\");";
String expectedResult18 = "class A {}\n" +
"class B extends A {}\n" +
@@ -430,8 +430,8 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
"} catch(Exception ex) {\n" +
" aaa5();\n" +
"}\n";
String s53 = "try { 'a; } finally {\n" +
" 'b;" +
String s53 = "try { '_a; } finally {\n" +
" '_b;" +
"}";
String s54 = "$a$;";
String expectedResult19 = "aaa();\n" +
@@ -501,7 +501,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String s64 = "int x = 42;\n" +
"int y = 42; // Stuff";
String s65 = "'Type 'Variable = 'Value; // 'Comment";
String s65 = "'_Type '_Variable = '_Value; // '_Comment";
String s66 = "/**\n" +
" *$Comment$\n" +
" */\n" +
@@ -521,7 +521,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
);
String s61 = "try { 1=1; } catch(Exception e) { 1=1; } catch(Throwable t) { 2=2; }";
String s62 = "try { 'a; } catch(Exception e) { 'b; }";
String s62 = "try { '_a; } catch(Exception e) { '_b; }";
String s63 = "try { $a$; } catch(Exception1 e) { $b$; } catch(Exception2 e) { $b$; }";
String expectedResult22 = "try { 1=1; } catch(Exception1 e) { 1=1; } catch(Exception2 e) { 1=1; } catch (Throwable t) { 2=2; }";
@@ -697,10 +697,10 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
"}";
String s8 = "new Runnable() {\n" +
" public void run() {\n" +
" 'l ();\n" +
" '_l ();\n" +
" }\n" +
" private void 'l () {\n" +
" 'st{2,2};\n" +
" private void '_l () {\n" +
" '_st{2,2};\n" +
" }\n" +
"};";
String s9 = "new My() {\n" +
@@ -980,7 +980,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
options.setToReformatAccordingToStyle(true);
String s1 = "class A { public void b() {} }";
String s2 = "class 'a { 'Other* }";
String s2 = "class 'a { '_Other* }";
String s3 = "class $a$New { Logger LOG; $Other$ }";
String expectedResult = " class ANew {\n" +
" Logger LOG;\n\n" +
@@ -996,7 +996,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
);
String s4 = "class A { class C {} public void b() {} int f; }";
String s5 = "class 'a { 'Other* }";
String s5 = "class 'a { '_Other* }";
String s6 = "class $a$ { Logger LOG; $Other$ }";
String expectedResult2 = " class A {\n" +
" Logger LOG;\n\n" +
@@ -1015,7 +1015,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
);
String s7 = "class A extends B { int c; void b() {} { a = 1; } }";
String s8 = "class 'A extends B { 'Other* }";
String s8 = "class 'A extends B { '_Other* }";
String s9 = "class $A$ extends B2 { $Other$ }";
String expectedResult3 = " class A extends B2 {\n" +
" int c;\n\n" +
@@ -1036,7 +1036,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" public void b() {}\n" +
" int f;\n" +
"}";
String s11 = "class 'a { 'Other* }";
String s11 = "class 'a { '_Other* }";
String s12 = "public class $a$ {\n" +
" $Other$\n" +
"}";
@@ -1068,9 +1068,9 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
"}\n" +
"}";
String s14 = "class 'Class extends Thread {\n" +
" 'Class('ParameterType* 'ParameterName*) {\n" +
"\t super (CustomThreadGroup.getThreadGroup(), 'superarg* );\n" +
" 'Statement*;\n" +
" 'Class('_ParameterType* '_ParameterName*) {\n" +
"\t super (CustomThreadGroup.getThreadGroup(), '_superarg* );\n" +
" '_Statement*;\n" +
" }\n" +
"}";
String s15 = "class $Class$ extends CustomThread {\n" +
@@ -1100,8 +1100,8 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String s16 = "public class A {}\n" +
"final class B {}";
String s17 = "class 'A { 'Other* }";
String s17_2 = "class 'A { private Log log = LogFactory.createLog(); 'Other* }";
String s17 = "class 'A { '_Other* }";
String s17_2 = "class 'A { private Log log = LogFactory.createLog(); '_Other* }";
String s18 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
String s18_2 = "class $A$ { $Other$ }";
@@ -1116,7 +1116,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
assertEquals("Removing field",expectedResult7,actualResult);
String s19 = "public class A extends Object implements Cloneable {}\n";
String s20 = "class 'A { 'Other* }";
String s20 = "class 'A { '_Other* }";
String s21 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
actualResult = replacer.testReplace(s19,s20,s21,options);
@@ -1124,7 +1124,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
assertEquals("Extends / implements list for class",expectedResult8,actualResult);
String s22 = "public class A<T> { int Afield; }\n";
String s23 = "class 'A { 'Other* }";
String s23 = "class 'A { '_Other* }";
String s24 = "class $A$ { private Log log = LogFactory.createLog(); $Other$ }";
actualResult = replacer.testReplace(s22,s23,s24,options);
@@ -1152,8 +1152,8 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String s28 = "aaa";
String s29 = "class 'Class {\n" +
" 'Class('ParameterType 'ParameterName) {\n" +
" 'Class('ParameterName);\n" +
" 'Class('_ParameterType '_ParameterName) {\n" +
" 'Class('_ParameterName);\n" +
" }\n" +
"}";
String s30 = "class $Class$ {\n" +
@@ -1177,7 +1177,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" int c; // comment2\n" +
"}";
String s32 = "'Type 'Variable = 'Value?; //'Comment";
String s32 = "'_Type 'Variable = '_Value?; //'_Comment";
String s33 = "/**$Comment$*/\n" +
"$Type$ $Variable$ = $Value$;";
@@ -1212,7 +1212,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
"}";
String s35 = "public interface 'MessageInterface {\n" +
" public static final String 'X = 'VALUE;\n" +
" public static final String '_X = '_VALUE;\n" +
" 'blah*" +
"}";
String s36 = "public interface $MessageInterface$ {\n" +
@@ -1266,7 +1266,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" private int c = 2;\n" +
"}";
String s2 = "@Modifier(\"PackageLocal\") 'Type 'Instance = 'Init?;";
String s2 = "@Modifier(\"PackageLocal\") '_Type '_Instance = '_Init?;";
String s3 = "public $Type$ $Instance$ = $Init$;";
String expectedResult = "class A {\n" +
@@ -1348,7 +1348,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" /**\n" +
" * zzz\n" +
" */\n" +
" void f('t 'p){'s+;}\n" +
" void f('_t '_p){'_s+;}\n" +
"}";
String s3 = "class $c$ {\n" +
" /**\n" +
@@ -1408,13 +1408,13 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
"}";
String s2 = "/**\n" +
"* Created by IntelliJ IDEA.\n" +
"* User: 'USER\n" +
"* Date: 'DATE\n" +
"* Time: 'TIME\n" +
"* User: '_USER\n" +
"* Date: '_DATE\n" +
"* Time: '_TIME\n" +
"* To change this template use File | Settings | File Templates.\n" +
"*/\n" +
"class 'c {\n" +
" 'other*\n" +
" '_other*\n" +
"}";
String s3 = "/**\n" +
"* by: $USER$\n" +
@@ -1469,11 +1469,11 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
public void testClassReplacement9() throws IOException {
String s1 = loadFile("before1.java");
String s2 = "class 'A extends 'TestCaseCass:[regex( .*TestCase ) ] {\n" +
" 'OtherStatement*;\n" +
" public void 'testMethod*:[regex( test.* )] () {\n" +
String s2 = "class 'A extends '_TestCaseCass:[regex( .*TestCase ) ] {\n" +
" '_OtherStatement*;\n" +
" public void '_testMethod*:[regex( test.* )] () {\n" +
" }\n" +
" 'OtherStatement2*;\n" +
" '_OtherStatement2*;\n" +
"}";
String s3 = "class $A$ extends $TestCaseCass$ {\n" +
" $OtherStatement$;\n" +
@@ -1560,7 +1560,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String actualResult;
String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n int x;\n void m(){}\n }";
String s44 = "class 'Class implements 'Interface { 'Content* }";
String s44 = "class 'Class implements '_Interface { '_Content* }";
String s45 = "@MyAnnotation\n" +
"class $Class$ implements $Interface$ {$Content$}";
String expectedResult16 = "@MyAnnotation public @Deprecated\n" +
@@ -1579,7 +1579,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String actualResult;
String s43 = "public @Deprecated class Foo implements Comparable<Foo> {\n int x;\n void m(){}\n }";
String s44 = "class 'Class implements 'Interface {}";
String s44 = "class 'Class implements '_Interface {}";
String s45 = "@MyAnnotation\n" +
"class $Class$ implements $Interface$ {}";
String expectedResult16 = "@MyAnnotation public @Deprecated\n" +
@@ -1794,7 +1794,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" catch (final Exception e)\n" +
" { continue; }\n" +
"}";
String toFind = "try { 'TryStatement*; } catch(Exception 'ExceptionDcl) { 'CatchStatement*; }";
String toFind = "try { '_TryStatement*; } catch(Exception '_ExceptionDcl) { '_CatchStatement*; }";
String replacement = "try { $TryStatement$; }\n" + "catch(Throwable $ExceptionDcl$) { $CatchStatement$; }";
String expectedResult = "for (int i = 0; i < MIMEHelper.MIME_MAP.length; i++)\n" +
"{\n" +
@@ -1841,7 +1841,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" Math.sin(0.5);\n" +
" Math.max(1, 2);\n" +
"}}";
final String what = "Math.'m('a*)";
final String what = "Math.'m('_a*)";
final String by = "Math.$m$($a$)";
options.setToUseStaticImport(true);
@@ -1961,7 +1961,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" } catch (PersistenceException e) {\n" +
" // good\n" +
" }";
String s2 = "try { 'TryStatement; } catch('ExceptionType 'ExceptionDcl) { /* 'CommentContent */ }";
String s2 = "try { '_TryStatement; } catch('_ExceptionType '_ExceptionDcl) { /* '_CommentContent */ }";
String replacement = "try { $TryStatement$; } catch($ExceptionType$ $ExceptionDcl$) { _logger.warning(\"$CommentContent$\", $ExceptionDcl$); }";
String expected = "try { em.persist(p); } catch(PersistenceException e) { _logger.warning(\" good\", e); }";
@@ -2077,9 +2077,9 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
"a = 2;\n" +
"int b = a;\n" +
"b2 = 3;";
String s2 = "int 'a = 'i;\n" +
"'st*;\n" +
"'a = 'c;";
String s2 = "int '_a = '_i;\n" +
"'_st*;\n" +
"'_a = '_c;";
String s3 = "$st$;\n" +
"$c$ = $i$;";
@@ -2092,9 +2092,9 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
actualResult
);
String s2_2 = "int 'a = 'i;\n" +
"'st*;\n" +
"int 'c = 'a;";
String s2_2 = "int '_a = '_i;\n" +
"'_st*;\n" +
"int '_c = '_a;";
String s3_2 = "$st$;\n" +
"int $c$ = $i$;";
String expected_2 = "a = 2;\nint b = 1;\nb2 = 3;";
@@ -2123,7 +2123,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
public void testReplaceMultipleFieldsInSingleDeclaration() {
String source = "abstract class MyClass implements java.util.List {\n private String a, b;\n}";
String search = "class 'Name implements java.util.List {\n 'ClassContent*\n}";
String search = "class 'Name implements java.util.List {\n '_ClassContent*\n}";
String replace = "class $Name$ {\n $ClassContent$\n}";
String expectedResult = "abstract class MyClass {\n private String a,b;\n}";
@@ -2139,7 +2139,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
String source = "import java.io.Externalizable;\n" +
"import java.io.Serializable;\n" +
"abstract class MyClass implements Serializable, java.util.List, Externalizable {}";
String search = "class 'TestCase implements java.util.List, 'others* {\n 'MyClassContent\n}";
String search = "class 'TestCase implements java.util.List, '_others* {\n '_MyClassContent\n}";
String replace = "class $TestCase$ implements $others$ {\n $MyClassContent$\n}";
String expectedResult = "import java.io.Externalizable;\n" +
"import java.io.Serializable;\n" +
@@ -2158,7 +2158,7 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
" public void foo() {\n" +
" }\n" +
"}";
String search = "class 'Class {\n 'Content*\n}";
String search = "class 'Class {\n '_Content*\n}";
String replace = "class $Class$ {\n" +
" void x() {}\n" +
" $Content$\n" +
@@ -826,7 +826,7 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
String s10031 = "try { a(); } catch(Exception ex) {} catch(Error error) { 1=1; }\n" +
"try { a(); } catch(Exception ex) {}";
String s10032 = "try { a(); } catch('_Type+ 'Arg+) { 'Statements*; }\n";
String s10032 = "try { a(); } catch('_Type+ 'Arg+) { '_Statements*; }\n";
assertEquals(
"finally matching",
2,
@@ -2440,12 +2440,12 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
"@Foo(value2=baz4) int a3;\n" +
"}";
String s12 = "@Foo(value=baz) int 'a;)";
String s12_2 = "@Foo(value='baz:baz2 ) int 'a;)";
String s12_3 = "@Foo('value:value2 = baz3 ) int 'a;)";
String s12_4 = "@Foo('value:value2 = 'baz3:baz3 ) int 'a;)";
String s12_5 = "@Foo('value:value2 = 'baz3:baz ) int 'a;)";
String s12_6 = "@Foo('value:value2 = 'baz3 ) int 'a;)";
String s12_7 = "@Foo('value:value2 = ) int 'a;";
String s12_2 = "@Foo(value='baz:baz2 ) int '_a;)";
String s12_3 = "@Foo('value:value2 = baz3 ) int '_a;)";
String s12_4 = "@Foo('value:value2 = '_baz3:baz3 ) int '_a;)";
String s12_5 = "@Foo('value:value2 = '_baz3:baz ) int '_a;)";
String s12_6 = "@Foo('value:value2 = '_baz3 ) int '_a;)";
String s12_7 = "@Foo('value:value2 = ) int '_a;";
assertEquals("Find anno parameter value",1,findMatchesCount(s11,s12));
assertEquals("Find anno parameter value",2,findMatchesCount(s11,s12_2));
@@ -4,6 +4,7 @@ import com.intellij.structuralsearch.MalformedPatternException;
import com.intellij.structuralsearch.MatchOptions;
import com.intellij.structuralsearch.MatchVariableConstraint;
import com.intellij.structuralsearch.UnsupportedPatternException;
import com.intellij.structuralsearch.plugin.ui.Configuration;
import org.junit.Before;
import org.junit.Test;
@@ -121,6 +122,14 @@ public class StringToConstraintsTransformerTest {
assertEquals("$a$::$b$", myOptions.getSearchPattern());
}
@Test
public void testScriptEscaping() {
test("'_type 'a:[within( \"if ('_a:[regex( .*e.* )\\]) { '_st*; }\" )] = '_b;");
assertEquals("$type$ $a$ = $b$;", myOptions.getSearchPattern());
final MatchVariableConstraint constraint = myOptions.getVariableConstraint(Configuration.CONTEXT_VAR_NAME);
assertEquals("\"if ('_a:[regex( .*e.* )]) { '_st*; }\"", constraint.getWithinConstraint());
}
private void test(String pattern) {
myOptions.setSearchPattern(pattern);
StringToConstraintsTransformer.transformOldPattern(myOptions);
@@ -815,7 +815,7 @@ public class ContainerUtil extends ContainerUtilRt {
@Nullable
@Contract(pure=true)
public static <T> T find(@NotNull Iterable<? extends T> iterable, final T equalTo) {
public static <T> T find(@NotNull Iterable<? extends T> iterable, @NotNull final T equalTo) {
return find(iterable, new Condition<T>() {
@Override
public boolean value(final T object) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -31,7 +31,7 @@ import java.util.Map;
abstract class AbstractCollectionBinding extends Binding implements MultiNodeBinding {
private Map<Class, Binding> myElementBindings;
private final Class myElementType;
private final Class<?> myElementType;
private final String myTagName;
private final AbstractCollection myAnnotation;
@@ -247,7 +247,7 @@ abstract class AbstractCollectionBinding extends Binding implements MultiNodeBin
return myAnnotation == null || myAnnotation.surroundWithTag() ? getCollectionTagName(target) : null;
}
protected String getCollectionTagName(final Object target) {
protected String getCollectionTagName(Object target) {
return myTagName;
}
}
@@ -301,14 +301,17 @@ class BeanBinding extends Binding {
do {
for (Field field : currentClass.getDeclaredFields()) {
int modifiers = field.getModifiers();
//noinspection deprecation
if (!Modifier.isStatic(modifiers) &&
(field.getAnnotation(OptionTag.class) != null ||
field.getAnnotation(Tag.class) != null ||
field.getAnnotation(Attribute.class) != null ||
field.getAnnotation(Property.class) != null ||
field.getAnnotation(Text.class) != null ||
field.getAnnotation(CollectionBean.class) != null ||
(Modifier.isPublic(modifiers) &&
!Modifier.isFinal(modifiers) &&
// we don't want to allow final fields of all types, but only supported
(!Modifier.isFinal(modifiers) || Collection.class.isAssignableFrom(field.getType())) &&
!Modifier.isTransient(modifiers) &&
field.getAnnotation(Transient.class) == null))) {
accessors.add(new FieldAccessor(field));
@@ -361,7 +364,7 @@ class BeanBinding extends Binding {
return new TextBinding(accessor);
}
if (binding instanceof JDOMExternalizableStringListBinding) {
if (binding instanceof CompactCollectionBinding) {
return new AccessorBindingWrapper(accessor, binding);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -22,16 +22,13 @@ import java.lang.reflect.Type;
import java.util.*;
class CollectionBinding extends AbstractCollectionBinding {
public CollectionBinding(ParameterizedType type, final Accessor accessor) {
public CollectionBinding(ParameterizedType type, Accessor accessor) {
super(getComponentClass(type), Constants.COLLECTION, accessor);
}
private static Class getComponentClass(ParameterizedType type) {
private static Class getComponentClass(@NotNull ParameterizedType type) {
Type arg = type.getActualTypeArguments()[0];
if (arg instanceof ParameterizedType) {
return (Class)((ParameterizedType)arg).getRawType();
}
return (Class)arg;
return arg instanceof ParameterizedType ? (Class)((ParameterizedType)arg).getRawType() : (Class)arg;
}
@Override
@@ -58,7 +55,7 @@ class CollectionBinding extends AbstractCollectionBinding {
}
@Override
protected String getCollectionTagName(final Object target) {
protected String getCollectionTagName(Object target) {
if (target instanceof Set) {
return Constants.SET;
}
@@ -0,0 +1,116 @@
/*
* Copyright 2000-2015 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 com.intellij.util.xmlb;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @see com.intellij.util.xmlb.annotations.CollectionBean
*/
class CompactCollectionBinding extends Binding {
private final String name;
protected CompactCollectionBinding(@NotNull Accessor accessor) {
super(accessor);
name = myAccessor.getName();
}
@Nullable
@Override
public Object serialize(Object o, @Nullable Object context, SerializationFilter filter) {
Element result = new Element(name);
@SuppressWarnings("unchecked")
List<String> list = (List<String>)o;
if (list == null || list.isEmpty()) {
return result;
}
for (String item : list) {
result.addContent(new Element("item").setAttribute("value", item));
}
return result;
}
@Nullable
@Override
public Object deserialize(Object context, @NotNull Object node) {
@SuppressWarnings("unchecked")
List<String> list = (List<String>)context;
list.clear();
Element element = (Element)node;
if (element.getName().equals(name)) {
for (Element item : element.getChildren("item")) {
ContainerUtil.addIfNotNull(list, item.getAttributeValue("value"));
}
}
else {
// JDOMExternalizableStringList format
Element value = element.getChild("value");
if (value != null) {
value = value.getChild("list");
}
if (value != null) {
for (Element item : value.getChildren("item")) {
//noinspection SpellCheckingInspection
ContainerUtil.addIfNotNull(list, item.getAttributeValue("itemvalue"));
}
}
}
return list;
}
@Override
public boolean isBoundTo(Object node) {
if (node instanceof Element) {
Element element = (Element)node;
String elementName = element.getName();
if (isNameEqual(elementName)) {
return true;
}
else if (elementName.equals(Constants.OPTION)) {
// JDOMExternalizableStringList format
return isNameEqual(element.getAttributeValue(Constants.NAME));
}
}
return false;
}
private boolean isNameEqual(@Nullable String value) {
if (value == null) {
return false;
}
else if (value.equals(name)) {
return true;
}
else if (value.length() == (name.length() + 2) && value.startsWith("my")) {
return Character.isUpperCase(value.charAt(2)) && value.regionMatches(true, 2, name, 0, name.length());
}
else {
return false;
}
}
@Override
public Class getBoundNodeType() {
return Element.class;
}
}
@@ -1,69 +0,0 @@
/*
* Copyright 2000-2014 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 com.intellij.util.xmlb;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation")
class JDOMExternalizableStringListBinding extends Binding {
private final String myName;
protected JDOMExternalizableStringListBinding(@NotNull Accessor accessor) {
super(accessor);
myName = myAccessor.getName();
}
@Nullable
@Override
public Object serialize(Object o, @Nullable Object context, SerializationFilter filter) {
Element result = new Element(myName);
JDOMExternalizableStringList list = (JDOMExternalizableStringList)o;
if (list == null || list.isEmpty()) {
return result;
}
for (String item : list) {
result.addContent(new Element("item").setAttribute("value", item));
}
return result;
}
@Nullable
@Override
public Object deserialize(Object context, @NotNull Object node) {
JDOMExternalizableStringList list = (JDOMExternalizableStringList)context;
list.clear();
for (Element item : ((Element)node).getChildren("item")) {
ContainerUtil.addIfNotNull(list, item.getAttributeValue("value"));
}
return list;
}
@Override
public boolean isBoundTo(Object node) {
return node instanceof Element && ((Element)node).getName().equals(myName);
}
@Override
public Class getBoundNodeType() {
return Element.class;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -18,12 +18,12 @@ package com.intellij.util.xmlb;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.xmlb.annotations.CollectionBean;
import org.jdom.*;
import org.jdom.filter.Filter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Annotation;
import java.lang.ref.SoftReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -119,7 +119,8 @@ class XmlSerializerImpl {
map.put(key, binding);
try {
binding.init();
} catch (XmlSerializationException e) {
}
catch (XmlSerializationException e) {
map.remove(key);
throw e;
}
@@ -156,6 +157,12 @@ class XmlSerializerImpl {
return new PrimitiveValueBinding(aClass, accessor);
}
if (Collection.class.isAssignableFrom(aClass) && originalType instanceof ParameterizedType) {
if (accessor != null) {
CollectionBean listBean = accessor.getAnnotation(CollectionBean.class);
if (listBean != null) {
return new CompactCollectionBinding(accessor);
}
}
return new CollectionBinding((ParameterizedType)originalType, accessor);
}
if (accessor != null) {
@@ -167,7 +174,7 @@ class XmlSerializerImpl {
}
//noinspection deprecation
if (JDOMExternalizableStringList.class == aClass) {
return new JDOMExternalizableStringListBinding(accessor);
return new CompactCollectionBinding(accessor);
}
}
if (Date.class.isAssignableFrom(aClass)) {
@@ -179,21 +186,6 @@ class XmlSerializerImpl {
return new BeanBinding(aClass, accessor);
}
@Nullable
@Deprecated
@SuppressWarnings({"unchecked", "unused"})
/**
* @deprecated to remove in IDEA 15
*/
static <T> T findAnnotation(Annotation[] annotations, Class<T> aClass) {
if (annotations == null) return null;
for (Annotation annotation : annotations) {
if (aClass.isAssignableFrom(annotation.getClass())) return (T)annotation;
}
return null;
}
@Nullable
@SuppressWarnings({"unchecked"})
static <T> T convert(Object value, Class<T> type) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.xmlb.annotations;
import com.intellij.util.xmlb.Constants;
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2015 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 com.intellij.util.xmlb.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
/**
* Can read serialized JDOMExternalizableStringList, but in any case will be written in this bean format.
* It is useful for application-level config, but for project-level consider to use ConverterProvider.
*
* Currently, only string element type supported.
*/
public @interface CollectionBean {
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.xmlb.annotations.*;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
@@ -1259,6 +1260,12 @@ public class XmlSerializerTest extends TestCase {
public JDOMExternalizableStringList list = new JDOMExternalizableStringList();
}
@Tag("b")
static class Bean4 {
@CollectionBean
public final List<String> list = new SmartList<String>();
}
@SuppressWarnings("deprecation")
public void testJDOMExternalizableStringList() throws IOException, JDOMException {
Bean3 bean = new Bean3();
@@ -1274,6 +1281,39 @@ public class XmlSerializerTest extends TestCase {
"</b>", bean, new SkipDefaultsSerializationFilter());
}
public void testCollectionBean() throws IOException, JDOMException {
Bean4 bean = new Bean4();
bean.list.add("one");
bean.list.add("two");
bean.list.add("three");
doSerializerTest("<b>\n" +
" <list>\n" +
" <item value=\"one\" />\n" +
" <item value=\"two\" />\n" +
" <item value=\"three\" />\n" +
" </list>\n" +
"</b>", bean, new SkipDefaultsSerializationFilter());
}
public void testCollectionBeanReadJDOMExternalizableStringList() throws IOException, JDOMException {
@SuppressWarnings("deprecation")
JDOMExternalizableStringList list = new JDOMExternalizableStringList();
list.add("one");
list.add("two");
list.add("three");
Element value = new Element("value");
list.writeExternal(value);
Bean4 o = XmlSerializer.deserialize(new Element("state").addContent(new Element("option").setAttribute("name", "myList").addContent(value)), Bean4.class);
assertSerializer(o, "<b>\n" +
" <list>\n" +
" <item value=\"one\" />\n" +
" <item value=\"two\" />\n" +
" <item value=\"three\" />\n" +
" </list>\n" +
"</b>", "Deserialization failure", new SkipDefaultsSerializationFilter());
}
private static void checkSmartSerialization(@NotNull Bean2 bean, @NotNull String serialized) throws IOException, JDOMException {
SmartSerializer serializer = new SmartSerializer();
serializer.readExternal(bean, JDOMUtil.loadDocument(serialized).getRootElement());
@@ -25,7 +25,6 @@ import com.intellij.diff.util.WaitingBackgroundableTaskExecutor;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -34,6 +33,7 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import org.jetbrains.annotations.*;
@@ -119,12 +119,6 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
}
if (change.getBeforeRevision() instanceof FakeRevision || change.getAfterRevision() instanceof FakeRevision) {
ChangeListManager.getInstance(myProject).invokeAfterUpdate(new Runnable() {
@Override
public void run() {
refresh(); // TODO: this could cause diff init in 'hide' state
}
}, InvokeAfterUpdateMode.SILENT, "", ModalityState.current());
return new LoadingDiffRequest(ChangeDiffRequestProducer.getRequestTitle(change));
}
@@ -193,9 +187,17 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
return;
}
if (selectedChanges.contains(myCurrentChange)) return;
myCurrentChange = selectedChanges.get(0);
updateRequest();
Change selectedChange = myCurrentChange != null ? ContainerUtil.find(selectedChanges, myCurrentChange) : null;
if (selectedChange == null) {
myCurrentChange = selectedChanges.get(0);
updateRequest();
return;
}
if (myCurrentChange.getBeforeRevision() instanceof FakeRevision || myCurrentChange.getAfterRevision() instanceof FakeRevision) {
myCurrentChange = selectedChange;
updateRequest();
}
}
@Override
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.IntIntHashMap;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
@@ -102,7 +103,7 @@ public abstract class XFetchValueActionBase extends AnAction {
protected class ValueCollector {
private final List<String> values = new SmartList<String>();
private final List<Integer> indents = new SmartList<Integer>();
private final IntIntHashMap indents = new IntIntHashMap();
private final XDebuggerTree myTree;
private volatile boolean processed;
@@ -111,18 +112,18 @@ public abstract class XFetchValueActionBase extends AnAction {
}
public void add(@NotNull String value) {
add(value, 0);
values.add(value);
}
public void add(@NotNull String value, int indent) {
values.add(value);
indents.add(indent);
indents.put(values.size() - 1, indent);
}
public void finish(Project project) {
if (processed && !values.contains(null) && !project.isDisposed()) {
int minIndent = Integer.MAX_VALUE;
for (Integer indent : indents) {
for (int indent : indents.getValues()) {
minIndent = Math.min(minIndent, indent);
}
StringBuilder sb = new StringBuilder();
@@ -130,8 +131,10 @@ public abstract class XFetchValueActionBase extends AnAction {
if (i > 0) {
sb.append("\n");
}
Integer indent = indents.get(i);
StringUtil.repeatSymbol(sb, ' ', indent - minIndent);
int indent = indents.get(i);
if (indent > 0) {
StringUtil.repeatSymbol(sb, ' ', indent - minIndent);
}
sb.append(values.get(i));
}
handleInCollector(project, sb.toString(), myTree);
+1
View File
@@ -46,6 +46,7 @@
<extensionPoint name="projectResolve" interface="org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension"/>
<extensionPoint name="taskManager" interface="org.jetbrains.plugins.gradle.service.task.GradleTaskManagerExtension"/>
<extensionPoint name="resolve.contributor" interface="org.jetbrains.plugins.gradle.service.resolve.GradleMethodContextContributor"/>
<extensionPoint name="settingsControlProvider" interface="org.jetbrains.plugins.gradle.service.settings.GradleSettingsControlProvider"/>
</extensionPoints>
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
@@ -15,50 +15,14 @@
*/
package org.jetbrains.plugins.gradle.service.settings;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.settings.LocationSettingType;
import com.intellij.openapi.externalSystem.service.settings.AbstractExternalProjectSettingsControl;
import com.intellij.openapi.externalSystem.service.settings.AbstractImportFromExternalSystemControl;
import com.intellij.openapi.externalSystem.service.ui.ExternalSystemJdkComboBox;
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.openapi.externalSystem.util.PaintAwarePanel;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.TextComponentAccessor;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBRadioButton;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
import com.intellij.util.ObjectUtils;
import com.intellij.util.ui.UIUtil;
import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
import org.jetbrains.plugins.gradle.settings.DistributionType;
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.concurrent.TimeUnit;
import static com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil.USE_PROJECT_JDK;
/**
* @author Denis Zhdanov
@@ -66,354 +30,49 @@ import static com.intellij.openapi.externalSystem.service.execution.ExternalSyst
*/
public class GradleProjectSettingsControl extends AbstractExternalProjectSettingsControl<GradleProjectSettings> {
private static final long BALLOON_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(1);
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private LocationSettingType myGradleHomeSettingType = LocationSettingType.UNKNOWN;
@NotNull private final GradleInstallationManager myInstallationManager;
@SuppressWarnings("FieldCanBeLocal") // Used implicitly by reflection at disposeUIResources() and showUi()
private JLabel myGradleHomeLabel;
@SuppressWarnings("FieldCanBeLocal") // Used implicitly by reflection at disposeUIResources() and showUi()
private JLabel myGradleJdkLabel;
private ExternalSystemJdkComboBox myGradleJdkComboBox;
private TextFieldWithBrowseButton myGradleHomePathField;
private JBRadioButton myUseWrapperButton;
private JBRadioButton myUseWrapperWithVerificationButton;
private JBLabel myUseWrapperVerificationLabel;
private JBRadioButton myUseLocalDistributionButton;
private JBRadioButton myUseBundledDistributionButton;
private boolean myShowBalloonIfNecessary;
private final GradleProjectSettingsControlBuilder myBuilder;
public GradleProjectSettingsControl(@NotNull GradleProjectSettings initialSettings) {
super(initialSettings);
myInstallationManager = ServiceManager.getService(GradleInstallationManager.class);
this(GradleSettingsControlProvider.get().getProjectSettingsControlBuilder(initialSettings));
}
public GradleProjectSettingsControl(@NotNull GradleProjectSettingsControlBuilder builder) {
super(null, builder.getInitialSettings(), builder.getExternalSystemSettingsControlCustomizer());
myBuilder = builder;
}
@Override
protected void fillExtraControls(@NotNull PaintAwarePanel content, int indentLevel) {
content.setPaintCallback(new Consumer<Graphics>() {
@Override
public void consume(Graphics graphics) {
showBalloonIfNecessary();
}
});
content.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!"ancestor".equals(evt.getPropertyName())) {
return;
}
// Configure the balloon to show on initial configurable drawing.
myShowBalloonIfNecessary = evt.getNewValue() != null && evt.getOldValue() == null;
if (evt.getNewValue() == null && evt.getOldValue() != null) {
// Cancel delayed balloons when the configurable is hidden.
myAlarm.cancelAllRequests();
}
}
});
myGradleHomeLabel = new JBLabel(GradleBundle.message("gradle.settings.text.home.path"));
initGradleHome();
myGradleJdkLabel = new JBLabel(GradleBundle.message("gradle.settings.text.jvm.path"));
myGradleJdkComboBox = new ExternalSystemJdkComboBox().withoutJre();
initControls();
content.add(myUseWrapperButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myUseWrapperWithVerificationButton, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myUseWrapperVerificationLabel, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
//content.add(Box.createGlue(), ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
// Hide bundled distribution option for a while
// content.add(myUseBundledDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myUseLocalDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myGradleHomeLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myGradleHomePathField, ExternalSystemUiUtil.getFillLineConstraints(0));
content.add(myGradleJdkLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myGradleJdkComboBox, ExternalSystemUiUtil.getFillLineConstraints(0));
}
private void initControls() {
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean localDistributionEnabled = myUseLocalDistributionButton.isSelected();
myGradleHomePathField.setEnabled(localDistributionEnabled);
if (localDistributionEnabled) {
if(myGradleHomePathField.getText().isEmpty()){
deduceGradleHomeIfPossible();
} else {
if(myInstallationManager.isGradleSdkHome(myGradleHomePathField.getText())){
myGradleHomeSettingType = LocationSettingType.EXPLICIT_CORRECT;
} else {
myGradleHomeSettingType = LocationSettingType.EXPLICIT_INCORRECT;
myShowBalloonIfNecessary = true;
}
}
showBalloonIfNecessary();
}
else {
myAlarm.cancelAllRequests();
}
}
};
myUseWrapperButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.default_wrapper.configured"));
myUseWrapperButton.addActionListener(listener);
myUseWrapperWithVerificationButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.customizable_wrapper"));
myUseWrapperWithVerificationButton.addActionListener(listener);
myUseWrapperVerificationLabel = new JBLabel(GradleBundle.message("gradle.settings.text.wrapper.customization.compatibility"));
myUseWrapperVerificationLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.MINI));
myUseWrapperVerificationLabel.setIcon(UIUtil.getBalloonInformationIcon());
myUseLocalDistributionButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.local.distribution"));
myUseLocalDistributionButton.addActionListener(listener);
myUseBundledDistributionButton = new JBRadioButton(
GradleBundle.message("gradle.settings.text.use.bundled.distribution", GradleVersion.current().getVersion()));
myUseBundledDistributionButton.addActionListener(listener);
myUseBundledDistributionButton.setEnabled(false);
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(myUseWrapperButton);
buttonGroup.add(myUseWrapperWithVerificationButton);
buttonGroup.add(myUseBundledDistributionButton);
buttonGroup.add(myUseLocalDistributionButton);
}
private void initGradleHome() {
myGradleHomePathField = new TextFieldWithBrowseButton();
FileChooserDescriptor fileChooserDescriptor = GradleUtil.getGradleHomeFileChooserDescriptor();
myGradleHomePathField.addBrowseFolderListener(
"",
GradleBundle.message("gradle.settings.text.home.path"),
null,
fileChooserDescriptor,
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT,
false
);
myGradleHomePathField.getTextField().getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
myGradleHomePathField.getTextField().setForeground(LocationSettingType.EXPLICIT_CORRECT.getColor());
}
@Override
public void removeUpdate(DocumentEvent e) {
myGradleHomePathField.getTextField().setForeground(LocationSettingType.EXPLICIT_CORRECT.getColor());
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
myBuilder.createAndFillControls(content, indentLevel);
}
@Override
public boolean validate(@NotNull GradleProjectSettings settings) throws ConfigurationException {
String gradleHomePath = FileUtil.toCanonicalPath(myGradleHomePathField.getText());
if (myUseLocalDistributionButton.isSelected()) {
if (StringUtil.isEmpty(gradleHomePath)) {
myGradleHomeSettingType = LocationSettingType.UNKNOWN;
throw new ConfigurationException(GradleBundle.message("gradle.home.setting.type.explicit.empty", gradleHomePath));
}
else if (!myInstallationManager.isGradleSdkHome(new File(gradleHomePath))) {
myGradleHomeSettingType = LocationSettingType.EXPLICIT_INCORRECT;
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
throw new ConfigurationException(GradleBundle.message("gradle.home.setting.type.explicit.incorrect", gradleHomePath));
}
}
return true;
return myBuilder.validate(settings);
}
@Override
protected void applyExtraSettings(@NotNull GradleProjectSettings settings) {
String gradleHomePath = FileUtil.toCanonicalPath(myGradleHomePathField.getText());
if (StringUtil.isEmpty(gradleHomePath)) {
settings.setGradleHome(null);
}
else {
settings.setGradleHome(gradleHomePath);
GradleUtil.storeLastUsedGradleHome(gradleHomePath);
}
final String gradleJvm = FileUtil.toCanonicalPath(myGradleJdkComboBox.getSelectedValue());
settings.setGradleJvm(StringUtil.isEmpty(gradleJvm) ? null : gradleJvm);
if (myUseLocalDistributionButton.isSelected()) {
settings.setDistributionType(DistributionType.LOCAL);
} else if(myUseWrapperButton.isSelected()) {
settings.setDistributionType(DistributionType.DEFAULT_WRAPPED);
} else if(myUseWrapperWithVerificationButton.isSelected() || myUseBundledDistributionButton.isSelected()) {
settings.setDistributionType(DistributionType.WRAPPED);
}
myBuilder.apply(settings);
}
@Override
protected void updateInitialExtraSettings() {
String gradleHomePath = FileUtil.toCanonicalPath(myGradleHomePathField.getText());
getInitialSettings().setGradleHome(StringUtil.isEmpty(gradleHomePath) ? null : gradleHomePath);
final String gradleJvm = FileUtil.toCanonicalPath(myGradleJdkComboBox.getSelectedValue());
getInitialSettings().setGradleJvm(StringUtil.isEmpty(gradleJvm) ? null : gradleJvm);
if (myUseLocalDistributionButton.isSelected()) {
getInitialSettings().setDistributionType(DistributionType.LOCAL);
} else if(myUseWrapperButton.isSelected()) {
getInitialSettings().setDistributionType(DistributionType.DEFAULT_WRAPPED);
} else if(myUseWrapperWithVerificationButton.isSelected() || myUseBundledDistributionButton.isSelected()) {
getInitialSettings().setDistributionType(DistributionType.WRAPPED);
}
myBuilder.apply(getInitialSettings());
}
@Override
protected boolean isExtraSettingModified() {
DistributionType distributionType = getInitialSettings().getDistributionType();
if (myUseBundledDistributionButton.isSelected() && distributionType != DistributionType.BUNDLED) {
return true;
}
if (myUseWrapperButton.isSelected() && distributionType != DistributionType.DEFAULT_WRAPPED) {
return true;
}
if (myUseWrapperWithVerificationButton.isSelected() && distributionType != DistributionType.WRAPPED) {
return true;
}
if (myUseLocalDistributionButton.isSelected() && distributionType != DistributionType.LOCAL) {
return true;
}
if (!StringUtil.equals(myGradleJdkComboBox.getSelectedValue(), getInitialSettings().getGradleJvm())) {
return true;
}
String gradleHome = FileUtil.toCanonicalPath(myGradleHomePathField.getText());
if (StringUtil.isEmpty(gradleHome)) {
return !StringUtil.isEmpty(getInitialSettings().getGradleHome());
}
else {
return !gradleHome.equals(getInitialSettings().getGradleHome());
}
return myBuilder.isModified(getInitialSettings());
}
@Override
protected void resetExtraSettings(boolean isDefaultModuleCreation) {
String gradleHome = getInitialSettings().getGradleHome();
myGradleHomePathField.setText(gradleHome == null ? "" : gradleHome);
myGradleHomePathField.getTextField().setForeground(LocationSettingType.EXPLICIT_CORRECT.getColor());
resetGradleJdkComboBox(getProject());
updateWrapperControls(getInitialSettings().getExternalProjectPath(), isDefaultModuleCreation);
if (!myUseLocalDistributionButton.isSelected()) {
myGradleHomePathField.setEnabled(false);
return;
}
if (StringUtil.isEmpty(gradleHome)) {
myGradleHomeSettingType = LocationSettingType.UNKNOWN;
deduceGradleHomeIfPossible();
}
else {
myGradleHomeSettingType = myInstallationManager.isGradleSdkHome(new File(gradleHome)) ?
LocationSettingType.EXPLICIT_CORRECT :
LocationSettingType.EXPLICIT_INCORRECT;
myAlarm.cancelAllRequests();
if (myGradleHomeSettingType == LocationSettingType.EXPLICIT_INCORRECT &&
getInitialSettings().getDistributionType() == DistributionType.LOCAL) {
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
}
}
myBuilder.reset(getProject(), getInitialSettings(), isDefaultModuleCreation);
}
public void updateWrapperControls(@Nullable String linkedProjectPath, boolean isDefaultModuleCreation) {
if(StringUtil.isEmpty(linkedProjectPath) && !isDefaultModuleCreation) {
myUseLocalDistributionButton.setSelected(true);
myGradleHomePathField.setEnabled(true);
return;
}
final boolean isGradleDefaultWrapperFilesExist = GradleUtil.isGradleDefaultWrapperFilesExist(linkedProjectPath);
if (isGradleDefaultWrapperFilesExist || isDefaultModuleCreation) {
myUseWrapperButton.setEnabled(true);
myUseWrapperButton.setSelected(true);
myGradleHomePathField.setEnabled(false);
myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.default_wrapper.configured"));
} else {
myUseWrapperButton.setEnabled(false);
myUseLocalDistributionButton.setSelected(true);
myGradleHomePathField.setEnabled(true);
myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.default_wrapper.not_configured"));
}
if(getInitialSettings().getDistributionType() == null) {
return;
}
switch (getInitialSettings().getDistributionType()) {
case LOCAL:
myGradleHomePathField.setEnabled(true);
myUseLocalDistributionButton.setSelected(true);
break;
case DEFAULT_WRAPPED:
myGradleHomePathField.setEnabled(false);
myUseWrapperButton.setSelected(true);
myUseWrapperButton.setEnabled(true);
break;
case WRAPPED:
myGradleHomePathField.setEnabled(false);
myUseWrapperWithVerificationButton.setSelected(true);
break;
case BUNDLED:
myGradleHomePathField.setEnabled(false);
myUseBundledDistributionButton.setSelected(true);
break;
}
}
/**
* Updates GUI of the gradle configurable in order to show deduced path to gradle (if possible).
*/
private void deduceGradleHomeIfPossible() {
File gradleHome = myInstallationManager.getAutodetectedGradleHome();
if (gradleHome == null) {
new DelayedBalloonInfo(MessageType.WARNING, LocationSettingType.UNKNOWN, BALLOON_DELAY_MILLIS).run();
return;
}
myGradleHomeSettingType = LocationSettingType.DEDUCED;
new DelayedBalloonInfo(MessageType.INFO, LocationSettingType.DEDUCED, BALLOON_DELAY_MILLIS).run();
myGradleHomePathField.setText(gradleHome.getPath());
myGradleHomePathField.getTextField().setForeground(LocationSettingType.DEDUCED.getColor());
}
void showBalloonIfNecessary() {
if (!myShowBalloonIfNecessary || !myGradleHomePathField.isEnabled()) {
return;
}
myShowBalloonIfNecessary = false;
MessageType messageType = null;
switch (myGradleHomeSettingType) {
case DEDUCED:
messageType = MessageType.INFO;
break;
case EXPLICIT_INCORRECT:
case UNKNOWN:
messageType = MessageType.ERROR;
break;
default:
}
if (messageType != null) {
new DelayedBalloonInfo(messageType, myGradleHomeSettingType, BALLOON_DELAY_MILLIS).run();
}
public void update(@Nullable String linkedProjectPath, boolean isDefaultModuleCreation) {
myBuilder.update(linkedProjectPath, getInitialSettings(), isDefaultModuleCreation);
}
/**
@@ -421,47 +80,12 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting
*/
public void setCurrentProject(@Nullable Project project) {
super.setCurrentProject(project);
resetGradleJdkComboBox(project);
myBuilder.reset(getProject(), getInitialSettings(), false);
}
private void resetGradleJdkComboBox(@Nullable final Project project) {
final String gradleJvm = getInitialSettings().getGradleJvm();
myGradleJdkComboBox.setProject(project);
final String sdkItem = ObjectUtils.nullizeByCondition(gradleJvm, new Condition<String>() {
@Override
public boolean value(String s) {
return (project == null && StringUtil.equals(USE_PROJECT_JDK, s)) || StringUtil.isEmpty(s);
}
});
myGradleJdkComboBox.refreshData(sdkItem);
}
private class DelayedBalloonInfo implements Runnable {
private final MessageType myMessageType;
private final String myText;
private final long myTriggerTime;
DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull LocationSettingType settingType, long delayMillis) {
myMessageType = messageType;
myText = settingType.getDescription(GradleConstants.SYSTEM_ID);
myTriggerTime = System.currentTimeMillis() + delayMillis;
}
@Override
public void run() {
long diff = myTriggerTime - System.currentTimeMillis();
if (diff > 0) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(this, diff);
return;
}
if (myGradleHomePathField == null || !myGradleHomePathField.isShowing()) {
// Don't schedule the balloon if the configurable is hidden.
return;
}
ExternalSystemUiUtil.showBalloon(myGradleHomePathField, myMessageType, myText);
}
@Override
public void disposeUIResources() {
super.disposeUIResources();
myBuilder.disposeUIResources();
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2015 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.plugins.gradle.service.settings;
import com.intellij.openapi.externalSystem.service.settings.ExternalSystemSettingsControlCustomizer;
import com.intellij.openapi.externalSystem.util.PaintAwarePanel;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
/**
* @author Vladislav.Soroka
* @since 2/24/2015
*/
public interface GradleProjectSettingsControlBuilder {
GradleProjectSettings getInitialSettings();
IdeaGradleProjectSettingsControlBuilder addGradleHomeComponents(PaintAwarePanel content, int indentLevel);
IdeaGradleProjectSettingsControlBuilder addGradleJdkComponents(PaintAwarePanel content, int indentLevel);
IdeaGradleProjectSettingsControlBuilder addGradleChooserComponents(PaintAwarePanel content, int indentLevel);
void disposeUIResources();
boolean validate(GradleProjectSettings settings) throws ConfigurationException;
void apply(GradleProjectSettings settings);
boolean isModified(GradleProjectSettings settings);
void reset(Project project, GradleProjectSettings settings, boolean isDefaultModuleCreation);
void createAndFillControls(PaintAwarePanel content, int indentLevel);
void update(String linkedProjectPath, GradleProjectSettings settings, boolean isDefaultModuleCreation);
@Nullable
ExternalSystemSettingsControlCustomizer getExternalSystemSettingsControlCustomizer();
}
@@ -0,0 +1,64 @@
/*
* Copyright 2000-2015 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.plugins.gradle.service.settings;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
/**
* @author Vladislav.Soroka
* @since 2/24/2015
*/
public abstract class GradleSettingsControlProvider {
private static final ExtensionPointName<GradleSettingsControlProvider> EP_NAME =
ExtensionPointName.create("org.jetbrains.plugins.gradle.settingsControlProvider");
public abstract String getPlatformPrefix();
public abstract GradleProjectSettingsControlBuilder getProjectSettingsControlBuilder(@NotNull GradleProjectSettings initialSettings);
@NotNull
public static GradleSettingsControlProvider get() {
GradleSettingsControlProvider result = null;
if (!PlatformUtils.isIntelliJ()) {
final String platformPrefix = PlatformUtils.getPlatformPrefix();
for (GradleSettingsControlProvider provider : EP_NAME.getExtensions()) {
if (StringUtil.equals(platformPrefix, provider.getPlatformPrefix())) {
assert result == null : "Multiple GradleSettingsControlProvider extensions found";
result = provider;
}
}
}
return ObjectUtils.notNull(result, new GradleSettingsControlProvider() {
@Override
public String getPlatformPrefix() {
return null;
}
@Override
public GradleProjectSettingsControlBuilder getProjectSettingsControlBuilder(@NotNull GradleProjectSettings initialSettings) {
return new IdeaGradleProjectSettingsControlBuilder(initialSettings)
// Hide bundled distribution option for a while
.dropUseBundledDistributionButton();
}
});
}
}
@@ -0,0 +1,604 @@
/*
* Copyright 2000-2015 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.plugins.gradle.service.settings;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.model.settings.LocationSettingType;
import com.intellij.openapi.externalSystem.service.settings.ExternalSystemSettingsControlCustomizer;
import com.intellij.openapi.externalSystem.service.ui.ExternalSystemJdkComboBox;
import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil;
import com.intellij.openapi.externalSystem.util.PaintAwarePanel;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.TextComponentAccessor;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBRadioButton;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
import com.intellij.util.ObjectUtils;
import com.intellij.util.ui.UIUtil;
import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
import org.jetbrains.plugins.gradle.settings.DistributionType;
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleConstants;
import org.jetbrains.plugins.gradle.util.GradleUtil;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.concurrent.TimeUnit;
import static com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil.USE_PROJECT_JDK;
/**
* @author Vladislav.Soroka
* @since 2/24/2015
*/
public class IdeaGradleProjectSettingsControlBuilder implements GradleProjectSettingsControlBuilder {
private static final long BALLOON_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(1);
@NotNull
private final GradleInstallationManager myInstallationManager;
@NotNull
private final GradleProjectSettings myInitialSettings;
@NotNull
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull
private LocationSettingType myGradleHomeSettingType = LocationSettingType.UNKNOWN;
private boolean myShowBalloonIfNecessary;
private ActionListener myActionListener;
private boolean dropUseAutoImportBox;
private boolean dropCreateEmptyContentRootDirectoriesBox;
@SuppressWarnings("FieldCanBeLocal") // Used implicitly by reflection at disposeUIResources() and showUi()
@Nullable
private JLabel myGradleHomeLabel;
@Nullable
private TextFieldWithBrowseButton myGradleHomePathField;
private boolean dropGradleHomePathComponents;
@SuppressWarnings("FieldCanBeLocal") // Used implicitly by reflection at disposeUIResources() and showUi()
@Nullable
private JLabel myGradleJdkLabel;
@Nullable
private ExternalSystemJdkComboBox myGradleJdkComboBox;
private boolean dropGradleJdkComponents;
@Nullable
private JBRadioButton myUseWrapperButton;
private boolean dropUseWrapperButton;
@Nullable
private JBRadioButton myUseWrapperWithVerificationButton;
@SuppressWarnings("FieldCanBeLocal") // Used implicitly by reflection at disposeUIResources() and showUi()
@Nullable
private JBLabel myUseWrapperVerificationLabel;
private boolean dropCustomizableWrapperButton;
@Nullable
private JBRadioButton myUseLocalDistributionButton;
private boolean dropUseLocalDistributionButton;
@Nullable
private JBRadioButton myUseBundledDistributionButton;
private boolean dropUseBundledDistributionButton;
public IdeaGradleProjectSettingsControlBuilder(@NotNull GradleProjectSettings initialSettings) {
myInstallationManager = ServiceManager.getService(GradleInstallationManager.class);
myInitialSettings = initialSettings;
myActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (myGradleHomePathField == null) return;
boolean localDistributionEnabled = myUseLocalDistributionButton != null && myUseLocalDistributionButton.isSelected();
myGradleHomePathField.setEnabled(localDistributionEnabled);
if (localDistributionEnabled) {
if (myGradleHomePathField.getText().isEmpty()) {
deduceGradleHomeIfPossible();
}
else {
if (myInstallationManager.isGradleSdkHome(myGradleHomePathField.getText())) {
myGradleHomeSettingType = LocationSettingType.EXPLICIT_CORRECT;
}
else {
myGradleHomeSettingType = LocationSettingType.EXPLICIT_INCORRECT;
myShowBalloonIfNecessary = true;
}
}
showBalloonIfNecessary();
}
else {
myAlarm.cancelAllRequests();
}
}
};
}
public IdeaGradleProjectSettingsControlBuilder dropGradleJdkComponents() {
dropGradleJdkComponents = true;
return this;
}
public IdeaGradleProjectSettingsControlBuilder dropUseWrapperButton() {
dropUseWrapperButton = true;
return this;
}
public IdeaGradleProjectSettingsControlBuilder dropGradleHomePathComponents() {
dropGradleHomePathComponents = true;
return this;
}
public IdeaGradleProjectSettingsControlBuilder dropCustomizableWrapperButton() {
dropCustomizableWrapperButton = true;
return this;
}
public IdeaGradleProjectSettingsControlBuilder dropUseLocalDistributionButton() {
dropUseLocalDistributionButton = true;
return this;
}
public IdeaGradleProjectSettingsControlBuilder dropUseBundledDistributionButton() {
dropUseBundledDistributionButton = true;
return this;
}
public IdeaGradleProjectSettingsControlBuilder dropUseAutoImportBox() {
dropUseAutoImportBox = true;
return this;
}
public IdeaGradleProjectSettingsControlBuilder dropCreateEmptyContentRootDirectoriesBox() {
dropCreateEmptyContentRootDirectoriesBox = true;
return this;
}
@NotNull
public GradleProjectSettings getInitialSettings() {
return myInitialSettings;
}
@Override
public ExternalSystemSettingsControlCustomizer getExternalSystemSettingsControlCustomizer() {
return new ExternalSystemSettingsControlCustomizer(dropUseAutoImportBox, dropCreateEmptyContentRootDirectoriesBox);
}
@Override
public void createAndFillControls(PaintAwarePanel content, int indentLevel) {
content.setPaintCallback(new Consumer<Graphics>() {
@Override
public void consume(Graphics graphics) {
showBalloonIfNecessary();
}
});
content.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!"ancestor".equals(evt.getPropertyName())) {
return;
}
// Configure the balloon to show on initial configurable drawing.
myShowBalloonIfNecessary = evt.getNewValue() != null && evt.getOldValue() == null;
if (evt.getNewValue() == null && evt.getOldValue() != null) {
// Cancel delayed balloons when the configurable is hidden.
myAlarm.cancelAllRequests();
}
}
});
addGradleChooserComponents(content, indentLevel);
addGradleHomeComponents(content, indentLevel);
addGradleJdkComponents(content, indentLevel);
}
@Override
public void disposeUIResources() {
ExternalSystemUiUtil.disposeUi(this);
}
/**
* Updates GUI of the gradle configurable in order to show deduced path to gradle (if possible).
*/
private void deduceGradleHomeIfPossible() {
if (myGradleHomePathField == null) return;
File gradleHome = myInstallationManager.getAutodetectedGradleHome();
if (gradleHome == null) {
new DelayedBalloonInfo(MessageType.WARNING, LocationSettingType.UNKNOWN, BALLOON_DELAY_MILLIS).run();
return;
}
myGradleHomeSettingType = LocationSettingType.DEDUCED;
new DelayedBalloonInfo(MessageType.INFO, LocationSettingType.DEDUCED, BALLOON_DELAY_MILLIS).run();
myGradleHomePathField.setText(gradleHome.getPath());
myGradleHomePathField.getTextField().setForeground(LocationSettingType.DEDUCED.getColor());
}
@Override
public IdeaGradleProjectSettingsControlBuilder addGradleJdkComponents(PaintAwarePanel content, int indentLevel) {
if(!dropGradleJdkComponents) {
myGradleJdkLabel = new JBLabel(GradleBundle.message("gradle.settings.text.jvm.path"));
myGradleJdkComboBox = new ExternalSystemJdkComboBox().withoutJre();
content.add(myGradleJdkLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myGradleJdkComboBox, ExternalSystemUiUtil.getFillLineConstraints(0));
}
return this;
}
@Override
public IdeaGradleProjectSettingsControlBuilder addGradleChooserComponents(PaintAwarePanel content, int indentLevel) {
ButtonGroup buttonGroup = new ButtonGroup();
if(!dropUseWrapperButton) {
myUseWrapperButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.default_wrapper.configured"));
myUseWrapperButton.addActionListener(myActionListener);
buttonGroup.add(myUseWrapperButton);
content.add(myUseWrapperButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
}
if(!dropCustomizableWrapperButton) {
myUseWrapperWithVerificationButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.customizable_wrapper"));
myUseWrapperWithVerificationButton.addActionListener(myActionListener);
myUseWrapperVerificationLabel = new JBLabel(GradleBundle.message("gradle.settings.text.wrapper.customization.compatibility"));
myUseWrapperVerificationLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.MINI));
myUseWrapperVerificationLabel.setIcon(UIUtil.getBalloonInformationIcon());
buttonGroup.add(myUseWrapperWithVerificationButton);
content.add(myUseWrapperWithVerificationButton, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myUseWrapperVerificationLabel, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
}
if(!dropUseLocalDistributionButton) {
myUseLocalDistributionButton = new JBRadioButton(GradleBundle.message("gradle.settings.text.use.local.distribution"));
myUseLocalDistributionButton.addActionListener(myActionListener);
buttonGroup.add(myUseLocalDistributionButton);
content.add(myUseLocalDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
}
if(!dropUseBundledDistributionButton) {
myUseBundledDistributionButton = new JBRadioButton(
GradleBundle.message("gradle.settings.text.use.bundled.distribution", GradleVersion.current().getVersion()));
myUseBundledDistributionButton.addActionListener(myActionListener);
buttonGroup.add(myUseBundledDistributionButton);
//content.add(Box.createGlue(), ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myUseBundledDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
}
return this;
}
@Override
public boolean validate(GradleProjectSettings settings) throws ConfigurationException {
if (myGradleHomePathField == null) return true;
String gradleHomePath = FileUtil.toCanonicalPath(myGradleHomePathField.getText());
if (myUseLocalDistributionButton != null && myUseLocalDistributionButton.isSelected()) {
if (StringUtil.isEmpty(gradleHomePath)) {
myGradleHomeSettingType = LocationSettingType.UNKNOWN;
throw new ConfigurationException(GradleBundle.message("gradle.home.setting.type.explicit.empty", gradleHomePath));
}
else if (!myInstallationManager.isGradleSdkHome(new File(gradleHomePath))) {
myGradleHomeSettingType = LocationSettingType.EXPLICIT_INCORRECT;
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
throw new ConfigurationException(GradleBundle.message("gradle.home.setting.type.explicit.incorrect", gradleHomePath));
}
}
return true;
}
@Override
public void apply(GradleProjectSettings settings) {
if (myGradleHomePathField != null) {
String gradleHomePath = FileUtil.toCanonicalPath(myGradleHomePathField.getText());
if (StringUtil.isEmpty(gradleHomePath)) {
settings.setGradleHome(null);
}
else {
settings.setGradleHome(gradleHomePath);
GradleUtil.storeLastUsedGradleHome(gradleHomePath);
}
}
if (myGradleJdkComboBox != null) {
final String gradleJvm = FileUtil.toCanonicalPath(myGradleJdkComboBox.getSelectedValue());
settings.setGradleJvm(StringUtil.isEmpty(gradleJvm) ? null : gradleJvm);
}
if (myUseLocalDistributionButton != null && myUseLocalDistributionButton.isSelected()) {
settings.setDistributionType(DistributionType.LOCAL);
}
else if (myUseWrapperButton != null && myUseWrapperButton.isSelected()) {
settings.setDistributionType(DistributionType.DEFAULT_WRAPPED);
}
else if ((myUseWrapperWithVerificationButton != null && myUseWrapperWithVerificationButton.isSelected()) ||
(myUseBundledDistributionButton != null && myUseBundledDistributionButton.isSelected())) {
settings.setDistributionType(DistributionType.WRAPPED);
}
}
@Override
public boolean isModified(GradleProjectSettings settings) {
DistributionType distributionType = settings.getDistributionType();
if (myUseBundledDistributionButton != null &&
myUseBundledDistributionButton.isSelected() &&
distributionType != DistributionType.BUNDLED) {
return true;
}
if (myUseWrapperButton != null && myUseWrapperButton.isSelected() && distributionType != DistributionType.DEFAULT_WRAPPED) {
return true;
}
if (myUseWrapperWithVerificationButton != null &&
myUseWrapperWithVerificationButton.isSelected() &&
distributionType != DistributionType.WRAPPED) {
return true;
}
if (myUseLocalDistributionButton != null && myUseLocalDistributionButton.isSelected() && distributionType != DistributionType.LOCAL) {
return true;
}
if (myGradleJdkComboBox != null && !StringUtil.equals(myGradleJdkComboBox.getSelectedValue(), settings.getGradleJvm())) {
return true;
}
if (myGradleHomePathField == null) return false;
String gradleHome = FileUtil.toCanonicalPath(myGradleHomePathField.getText());
if (StringUtil.isEmpty(gradleHome)) {
return !StringUtil.isEmpty(settings.getGradleHome());
}
else {
return !gradleHome.equals(settings.getGradleHome());
}
}
@Override
public void reset(Project project, GradleProjectSettings settings, boolean isDefaultModuleCreation) {
String gradleHome = settings.getGradleHome();
if (myGradleHomePathField != null) {
myGradleHomePathField.setText(gradleHome == null ? "" : gradleHome);
myGradleHomePathField.getTextField().setForeground(LocationSettingType.EXPLICIT_CORRECT.getColor());
}
resetGradleJdkComboBox(project, settings);
resetWrapperControls(settings.getExternalProjectPath(), settings, isDefaultModuleCreation);
if (myUseLocalDistributionButton != null && !myUseLocalDistributionButton.isSelected()) {
myGradleHomePathField.setEnabled(false);
return;
}
if (StringUtil.isEmpty(gradleHome)) {
myGradleHomeSettingType = LocationSettingType.UNKNOWN;
deduceGradleHomeIfPossible();
}
else {
myGradleHomeSettingType = myInstallationManager.isGradleSdkHome(new File(gradleHome)) ?
LocationSettingType.EXPLICIT_CORRECT :
LocationSettingType.EXPLICIT_INCORRECT;
myAlarm.cancelAllRequests();
if (myGradleHomeSettingType == LocationSettingType.EXPLICIT_INCORRECT &&
settings.getDistributionType() == DistributionType.LOCAL) {
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
}
}
}
@Override
public void update(String linkedProjectPath, GradleProjectSettings settings, boolean isDefaultModuleCreation) {
resetWrapperControls(linkedProjectPath, settings, isDefaultModuleCreation);
}
@Override
public IdeaGradleProjectSettingsControlBuilder addGradleHomeComponents(PaintAwarePanel content, int indentLevel) {
if(dropGradleHomePathComponents) return this;
myGradleHomeLabel = new JBLabel(GradleBundle.message("gradle.settings.text.home.path"));
myGradleHomePathField = new TextFieldWithBrowseButton();
myGradleHomePathField.addBrowseFolderListener(
"",
GradleBundle.message("gradle.settings.text.home.path"),
null,
GradleUtil.getGradleHomeFileChooserDescriptor(),
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT,
false
);
myGradleHomePathField.getTextField().getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
myGradleHomePathField.getTextField().setForeground(LocationSettingType.EXPLICIT_CORRECT.getColor());
}
@Override
public void removeUpdate(DocumentEvent e) {
myGradleHomePathField.getTextField().setForeground(LocationSettingType.EXPLICIT_CORRECT.getColor());
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
content.add(myGradleHomeLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myGradleHomePathField, ExternalSystemUiUtil.getFillLineConstraints(0));
return this;
}
private void resetGradleJdkComboBox(@Nullable final Project project, GradleProjectSettings settings) {
if (myGradleJdkComboBox == null) return;
final String gradleJvm = settings.getGradleJvm();
myGradleJdkComboBox.setProject(project);
final String sdkItem = ObjectUtils.nullizeByCondition(gradleJvm, new Condition<String>() {
@Override
public boolean value(String s) {
return (project == null && StringUtil.equals(USE_PROJECT_JDK, s)) || StringUtil.isEmpty(s);
}
});
myGradleJdkComboBox.refreshData(sdkItem);
}
private void resetWrapperControls(String linkedProjectPath, @NotNull GradleProjectSettings settings, boolean isDefaultModuleCreation) {
if (StringUtil.isEmpty(linkedProjectPath) && !isDefaultModuleCreation) {
if (myUseLocalDistributionButton != null) {
myUseLocalDistributionButton.setSelected(true);
}
if (myGradleHomePathField != null) {
myGradleHomePathField.setEnabled(true);
}
return;
}
final boolean isGradleDefaultWrapperFilesExist = GradleUtil.isGradleDefaultWrapperFilesExist(linkedProjectPath);
if (myUseWrapperButton != null && (isGradleDefaultWrapperFilesExist || isDefaultModuleCreation)) {
myUseWrapperButton.setEnabled(true);
myUseWrapperButton.setSelected(true);
if (myGradleHomePathField != null) {
myGradleHomePathField.setEnabled(false);
}
myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.default_wrapper.configured"));
}
else {
if (myUseWrapperButton != null) {
myUseWrapperButton.setEnabled(false);
myUseWrapperButton.setText(GradleBundle.message("gradle.settings.text.use.default_wrapper.not_configured"));
}
if (myUseLocalDistributionButton != null) {
myUseLocalDistributionButton.setSelected(true);
}
if (myGradleHomePathField != null) {
myGradleHomePathField.setEnabled(true);
}
}
if (settings.getDistributionType() == null) {
return;
}
switch (settings.getDistributionType()) {
case LOCAL:
if (myGradleHomePathField != null) {
myGradleHomePathField.setEnabled(true);
}
if (myUseLocalDistributionButton != null) {
myUseLocalDistributionButton.setSelected(true);
}
break;
case DEFAULT_WRAPPED:
if (isGradleDefaultWrapperFilesExist) {
if (myGradleHomePathField != null) {
myGradleHomePathField.setEnabled(false);
}
if (myUseWrapperButton != null) {
myUseWrapperButton.setSelected(true);
myUseWrapperButton.setEnabled(true);
}
}
break;
case WRAPPED:
if (myGradleHomePathField != null) {
myGradleHomePathField.setEnabled(false);
}
if (myUseWrapperWithVerificationButton != null) {
myUseWrapperWithVerificationButton.setSelected(true);
}
break;
case BUNDLED:
if (myGradleHomePathField != null) {
myGradleHomePathField.setEnabled(false);
}
if (myUseBundledDistributionButton != null) {
myUseBundledDistributionButton.setSelected(true);
}
break;
}
}
void showBalloonIfNecessary() {
if (!myShowBalloonIfNecessary || (myGradleHomePathField != null && !myGradleHomePathField.isEnabled())) {
return;
}
myShowBalloonIfNecessary = false;
MessageType messageType = null;
switch (myGradleHomeSettingType) {
case DEDUCED:
messageType = MessageType.INFO;
break;
case EXPLICIT_INCORRECT:
case UNKNOWN:
messageType = MessageType.ERROR;
break;
default:
}
if (messageType != null) {
new DelayedBalloonInfo(messageType, myGradleHomeSettingType, BALLOON_DELAY_MILLIS).run();
}
}
private class DelayedBalloonInfo implements Runnable {
private final MessageType myMessageType;
private final String myText;
private final long myTriggerTime;
DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull LocationSettingType settingType, long delayMillis) {
myMessageType = messageType;
myText = settingType.getDescription(GradleConstants.SYSTEM_ID);
myTriggerTime = System.currentTimeMillis() + delayMillis;
}
@Override
public void run() {
long diff = myTriggerTime - System.currentTimeMillis();
if (diff > 0) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(this, diff);
return;
}
if (myGradleHomePathField == null || !myGradleHomePathField.isShowing()) {
// Don't schedule the balloon if the configurable is hidden.
return;
}
ExternalSystemUiUtil.showBalloon(myGradleHomePathField, myMessageType, myText);
}
}
}
@@ -52,9 +52,7 @@ public class ImportFromGradleControl
@NotNull
@Override
protected ExternalSystemSettingsControl<GradleProjectSettings> createProjectSettingsControl(@NotNull GradleProjectSettings settings) {
GradleProjectSettingsControl settingsControl = new GradleProjectSettingsControl(settings);
settingsControl.hideUseAutoImportBox();
return settingsControl;
return new GradleProjectSettingsControl(settings);
}
@Nullable
@@ -65,7 +63,7 @@ public class ImportFromGradleControl
@Override
protected void onLinkedProjectPathChange(@NotNull String path) {
((GradleProjectSettingsControl)getProjectSettingsControl()).updateWrapperControls(path, false);
((GradleProjectSettingsControl)getProjectSettingsControl()).update(path, false);
}
@Override
@@ -55,7 +55,6 @@ public class PyConsoleParser extends PyParser{
StatementParsing stmt_parser = context.getStatementParser();
builder.setTokenTypeRemapper(stmt_parser); // must be done before touching the caching lexer with eof() call.
builder.setDebugMode(true);
while (!builder.eof()) {
stmt_parser.parseStatement(context.emptyParsingScope());
}
@@ -37,7 +37,10 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.remote.RemoteProcessHandlerBase;
@@ -52,7 +55,6 @@ import com.intellij.xdebugger.frame.XValueChildrenList;
import com.intellij.xdebugger.impl.XSourcePositionImpl;
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
import com.jetbrains.python.PythonFileType;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.console.PythonDebugLanguageConsoleView;
import com.jetbrains.python.console.pydev.PydevCompletionVariant;
import com.jetbrains.python.debugger.pydev.*;
@@ -801,7 +803,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
@Nullable
public XSourcePosition getCurrentFrameSourcePosition() {
private XSourcePosition getCurrentFrameSourcePosition() {
try {
PyStackFrame frame = currentFrame();
@@ -862,21 +864,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
return null;
}
VirtualFile virtualFile = currentPosition.getFile();
final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
if (document == null) {
return null;
}
final FileViewProvider viewProvider = PsiManager.getInstance(getProject()).findViewProvider(virtualFile);
if (viewProvider == null) {
return null;
}
final PsiFile file = viewProvider.getPsi(PythonLanguage.getInstance());
if (file == null) {
return null;
}
return file;
return PsiManager.getInstance(getProject()).findFile(currentPosition.getFile());
}
@@ -18,12 +18,15 @@ package com.jetbrains.python.refactoring.classes.membersManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.listeners.RefactoringEventData;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.util.Function;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
@@ -98,4 +101,27 @@ public abstract class PyMembersRefactoringBaseProcessor extends BaseRefactoringP
MembersManager.moveAllMembers(myMembersToMove, myFrom, destinations.toArray(new PyClass[destinations.size()]));
PyClassRefactoringUtil.optimizeImports(myFrom.getContainingFile()); // To remove unneeded imports
}
@Nullable
@Override
protected RefactoringEventData getBeforeData() {
RefactoringEventData data = new RefactoringEventData();
data.addElement(myFrom);
data.addMembers(myMembersToMove.toArray(new PyMemberInfo[myMembersToMove.size()]), new Function<PyMemberInfo, PsiElement>() {
@Override
public PsiElement fun(PyMemberInfo info) {
return info.getMember();
}
});
return data;
}
@Nullable
@Override
protected RefactoringEventData getAfterData(UsageInfo[] usages) {
final RefactoringEventData data = new RefactoringEventData();
data.addElements(myTo);
return data;
}
}
@@ -57,4 +57,10 @@ class PyPullUpProcessor extends PyMembersRefactoringBaseProcessor {
public String getCommentReferencesText(final int usagesCount, final int filesCount) {
return getCodeReferencesText(usagesCount, filesCount);
}
@Nullable
@Override
protected String getRefactoringId() {
return "refactoring.python.pull.up";
}
}
@@ -75,4 +75,10 @@ public class PyPushDownProcessor extends PyMembersRefactoringBaseProcessor {
protected String getCommandName() {
return PyPushDownHandler.REFACTORING_NAME;
}
@Nullable
@Override
protected String getRefactoringId() {
return "refactoring.python.push.down";
}
}
@@ -74,6 +74,7 @@ public class XmlEmmetParser extends EmmetParser {
put("object", "param");
put("map", "area");
}};
private boolean isHtml;
public XmlEmmetParser(List<ZenCodingToken> tokens,
CustomTemplateCallback callback,
@@ -84,6 +85,7 @@ public class XmlEmmetParser extends EmmetParser {
if (surroundWithTemplate && parentTag != null && context.getNode().getElementType() == XmlTokenType.XML_START_TAG_START) {
parentTag = PsiTreeUtil.getParentOfType(parentTag, XmlTag.class);
}
isHtml = generator.isHtml(callback);
if (parentTag != null) {
hasTagContext = true;
tagLevel.push(parentTag.getName());
@@ -210,7 +212,7 @@ public class XmlEmmetParser extends EmmetParser {
@Nullable
private String getDefaultTemplateKey() {
return ZenCodingUtil.isHtml(myCallback) ? suggestTagName() : null;
return isHtml ? suggestTagName() : null;
}
@Nullable
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.template.emmet.generators;
import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.template.CustomTemplateCallback;
import com.intellij.codeInsight.template.emmet.ZenCodingTemplate;
import com.intellij.codeInsight.template.emmet.ZenCodingUtil;
import com.intellij.codeInsight.template.emmet.tokens.TemplateToken;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import com.intellij.diagnostic.AttachmentFactory;
@@ -124,4 +125,9 @@ public abstract class XmlZenCodingGenerator extends ZenCodingGenerator {
public void disableEmmet() {
EmmetOptions.getInstance().setEmmetEnabled(false);
}
@Override
public boolean isHtml(@NotNull CustomTemplateCallback callback) {
return ZenCodingUtil.isHtml(callback);
}
}
@@ -148,6 +148,10 @@ public abstract class ZenCodingGenerator {
return false;
}
public boolean isHtml(@NotNull CustomTemplateCallback callback) {
return false;
}
public void disableEmmet() {
}
}
@@ -49,6 +49,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.*;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
@@ -276,6 +277,8 @@ public class GenerationNode extends UserDataHolderBase {
/*assert generator == null || generator instanceof XmlZenCodingGenerator :
"The generator cannot process TemplateToken because it doesn't inherit XmlZenCodingGenerator";*/
ZenCodingGenerator zenCodingGenerator = ObjectUtils.notNull(generator, XmlZenCodingGeneratorImpl.INSTANCE);
Map<String, String> attributes = token.getAttributes();
TemplateImpl template = token.getTemplate();
assert template != null;
@@ -307,7 +310,7 @@ public class GenerationNode extends UserDataHolderBase {
}
}
XmlTag tag1 = hasChildren ? expandEmptyTagIfNecessary(tag) : tag;
setAttributeValues(tag1, attributes, callback);
setAttributeValues(tag1, attributes, callback, zenCodingGenerator.isHtml(callback));
XmlFile physicalFile = (XmlFile)fileFactory.createFileFromText(HTMLLanguage.INSTANCE, tag1.getContainingFile().getText());
VirtualFile vFile = physicalFile.getVirtualFile();
if (vFile != null) {
@@ -315,7 +318,6 @@ public class GenerationNode extends UserDataHolderBase {
}
token.setFile(physicalFile);
}
ZenCodingGenerator zenCodingGenerator = generator != null ? generator : XmlZenCodingGeneratorImpl.INSTANCE;
template = zenCodingGenerator.generateTemplate(token, hasChildren, callback.getContext());
removeVariablesWhichHasNoSegment(template);
return template;
@@ -445,7 +447,10 @@ public class GenerationNode extends UserDataHolderBase {
return predefinedValues;
}
private void setAttributeValues(@NotNull XmlTag tag, @NotNull final Map<String, String> attributes, CustomTemplateCallback callback) {
private void setAttributeValues(@NotNull XmlTag tag,
@NotNull final Map<String, String> attributes,
@NotNull CustomTemplateCallback callback,
boolean isHtml) {
// default and implied attributes
final String defaultAttributeValue = attributes.get(XmlEmmetParser.DEFAULT_ATTRIBUTE_NAME);
if (defaultAttributeValue != null) {
@@ -495,7 +500,7 @@ public class GenerationNode extends UserDataHolderBase {
myContainsSurroundedTextMarker = true;
}
if (isBooleanAttribute(attributeValue, xmlAttribute, callback)) {
if (isHtml && isBooleanAttribute(attributeValue, xmlAttribute, callback)) {
if (HtmlUtil.isShortNotationOfBooleanAttributePreferred()) {
if (xmlAttributeValueElement != null) {
final PsiElement prevSibling = xmlAttributeValueElement.getPrevSibling();
@@ -536,7 +541,7 @@ public class GenerationNode extends UserDataHolderBase {
if (XmlEmmetParser.BOOLEAN_ATTRIBUTE_VALUE.equals(attributeValue)) {
return true;
}
if (ZenCodingUtil.isHtml(callback) && StringUtil.isEmpty(attributeValue)) {
if (StringUtil.isEmpty(attributeValue)) {
final XmlAttributeDescriptor descriptor = xmlAttribute.getDescriptor();
return descriptor != null && HtmlUtil.isBooleanAttribute(descriptor, callback.getContext());
}