diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index a100fc013fd3..60bece10bfc9 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -496,8 +496,6 @@ def layout_core(String home, String target) { module("core-impl") module("boot") module("extensions") - module("indexing-api") - module("indexing-impl") module("java-psi-api") module("java-psi-impl") } diff --git a/images/src/org/intellij/images/options/impl/Options.form b/images/src/org/intellij/images/options/impl/Options.form index 72269776f4ab..197d1acf687c 100644 --- a/images/src/org/intellij/images/options/impl/Options.form +++ b/images/src/org/intellij/images/options/impl/Options.form @@ -19,7 +19,7 @@ - + @@ -202,7 +202,7 @@ - + diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java index 473bb38d6f5f..e3c299a55d79 100644 --- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java +++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java @@ -857,6 +857,10 @@ public class AsmCodeGenerator { } pushBorderProperties(container, generator, borderTitle, componentLocal); + if (Boolean.valueOf(System.getProperty("idea.is.internal")).booleanValue()) { + container.getDelegeeClientProperties().put(ourBorderFactoryClientProperty, "com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"); + } + Type borderFactoryType = ourBorderFactoryType; StringDescriptor borderFactoryValue = (StringDescriptor)container.getDelegeeClientProperties().get(ourBorderFactoryClientProperty); if (borderFactoryValue != null && borderFactoryValue.getValue().length() != 0) { diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java index 5c57b8383f66..6ffe1062d18c 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java @@ -59,6 +59,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.io.File; import java.util.*; @@ -169,6 +170,26 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements return myModuleBytecodeTarget; } + public void setBytecodeTargetLevel(Module module, String level) { + final String previous; + if (StringUtil.isEmpty(level)) { + previous = myModuleBytecodeTarget.remove(module.getName()); + } + else { + previous = myModuleBytecodeTarget.put(module.getName(), level); + } + if (!Comparing.equal(previous, level)) { + final Project project = module.getProject(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (!project.isDisposed()) { + CompileServerManager.getInstance().sendReloadRequest(project); + } + } + }); + } + } + @Override @Nullable public String getBytecodeTargetLevel(Module module) { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 697ea1fba91a..f8dfcb2928c8 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -2316,9 +2316,6 @@ public class CompileDriver { private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) { try { - if (useOutOfProcessBuild()) { - return true; - } final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/; final List modulesWithoutOutputPathSpecified = new ArrayList(); boolean isProjectCompilePathSpecified = true; diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form index e1aa6ed463f5..ff0123f71f2a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form @@ -7,7 +7,7 @@ - + diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form index d6963cf3ed6d..07874d19282a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form @@ -7,7 +7,7 @@ - + diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOptionsPanel.form index cf2cfb167190..23055ee7a80b 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOptionsPanel.form +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOptionsPanel.form @@ -7,7 +7,7 @@ - + diff --git a/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsConfigurable.java index 0d1feeb3b754..d686fe2d8e18 100644 --- a/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsConfigurable.java +++ b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsConfigurable.java @@ -168,6 +168,7 @@ public class AnnotationProcessorsConfigurable implements SearchableConfigurable, mainPanel.add(noteMessage, new GridBagConstraints(0, 4, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); mainPanel.add(warning, new GridBagConstraints(0, 5, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0)); mainPanel.add(myModulesTable, new GridBagConstraints(0, 6, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0)); + //mainPanel.add(new AnnotationProcessorsPanel(myProject), new GridBagConstraints(0, 7, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0)); myRbClasspath.addItemListener(new ItemListener() { diff --git a/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java new file mode 100644 index 000000000000..f8d4ad8ec68d --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java @@ -0,0 +1,305 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.compiler.options; + +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.ShortcutSet; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidatorEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.AnActionButton; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.ToolbarDecorator; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.components.JBList; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.ui.EditableTreeModel; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.*; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +@SuppressWarnings({"unchecked", "UseOfObsoleteCollectionType"}) +public class AnnotationProcessorsPanel extends JPanel { + private final Map> profiles = new HashMap>(); + private static final String DEFAULT_PROFILE = "Default"; + private final Project myProject; + private final Tree myTree; + private JPanel myContentPanel; + + public AnnotationProcessorsPanel(Project project) { + super(new BorderLayout()); + myProject = project; + loadProfiles(); + myTree = new Tree(new MyTreeModel()); + myTree.setRootVisible(false); + final JPanel treePanel = + ToolbarDecorator.createDecorator(myTree).addExtraAction(new AnActionButton("Move to", IconLoader.getIcon("/actions/nextfile.png")) { + @Override + public void actionPerformed(AnActionEvent e) { + final MyModuleNode node = (MyModuleNode)myTree.getSelectionPath().getLastPathComponent(); + final TreePath[] selectedNodes = myTree.getSelectionPaths(); + final String key = ((MyProfileNode)node.getParent()).myKey; + final List profileNames = new ArrayList(); + profileNames.add(DEFAULT_PROFILE); + profileNames.addAll(profiles.keySet()); + profileNames.remove(key); + final JBList list = new JBList(profileNames); + final JBPopup popup = JBPopupFactory.getInstance().createListPopupBuilder(list) + .setTitle("Move to") + .setItemChoosenCallback(new Runnable() { + @Override + public void run() { + final Object value = list.getSelectedValue(); + if (value instanceof String) { + final Module toSelect = (Module)node.getUserObject(); + if (selectedNodes != null) { + for (TreePath selectedNode : selectedNodes) { + final Object n = selectedNode.getLastPathComponent(); + + if (n instanceof MyModuleNode) { + Module module = (Module)((MyModuleNode)n).getUserObject(); + if (!DEFAULT_PROFILE.equals(key)) { + profiles.get(key).remove(module); + } + if (!DEFAULT_PROFILE.equals(value)) { + profiles.get(value).add(module); + } + } + } + } + + final MyRootNode root = (MyRootNode)myTree.getModel().getRoot(); + root.sync(); + final DefaultMutableTreeNode node = TreeUtil.findNodeWithObject(root, toSelect); + if (node != null) { + TreeUtil.selectNode(myTree, node); + } + } + } + }) + .createPopup(); + RelativePoint point = e.getInputEvent() instanceof MouseEvent ? getPreferredPopupPoint() : TreeUtil.getPointForSelection(myTree); + popup.show(point); + } + + @Override + public ShortcutSet getShortcut() { + return ActionManager.getInstance().getAction("Move").getShortcutSet(); + } + + @Override + public boolean isEnabled() { + return myTree.getSelectionPath() != null + && myTree.getSelectionPath().getLastPathComponent() instanceof MyModuleNode + && !profiles.isEmpty(); + } + }).createPanel(); + add(treePanel, BorderLayout.WEST); + myTree.setCellRenderer(new MyCellRenderer()); + ((MyRootNode)myTree.getModel().getRoot()).sync(); + myContentPanel = new JPanel(new BorderLayout()); + myTree.addTreeSelectionListener(new TreeSelectionListener() { + String currentProfile = null; + @Override + public void valueChanged(TreeSelectionEvent e) { + final TreePath path = myTree.getSelectionPath(); + if (path != null) { + Object node = path.getLastPathComponent(); + if (node instanceof MyModuleNode) { + node = ((MyModuleNode)node).getParent(); + } + if (node instanceof MyProfileNode) { + if (!StringUtil.equals(currentProfile, ((MyProfileNode)node).myKey)) { + currentProfile = ((MyProfileNode)node).myKey; + myContentPanel.removeAll(); + myContentPanel.add(getComponentForProfile(currentProfile), BorderLayout.CENTER); + revalidate(); + repaint(); + } + } + } + } + }); + add(myContentPanel, BorderLayout.CENTER); + } + + + private JComponent getComponentForProfile(String profile) { + //TODO[jeka] correct panel + return new JLabel(profile, SwingConstants.CENTER); + } + + private static void expand(JTree tree) { + int oldRowCount = 0; + do { + int rowCount = tree.getRowCount(); + if (rowCount == oldRowCount) break; + oldRowCount = rowCount; + for (int i = 0; i < rowCount; i++) { + tree.expandRow(i); + } + } + while (true); + } + + private void loadProfiles() { + //TODO[jeka] init profiles map + } + + private class MyTreeModel extends DefaultTreeModel implements EditableTreeModel{ + public MyTreeModel() { + super(new MyRootNode()); + } + + @Override + public TreePath addNode(TreePath parentOrNeighbour) { + final String profile = Messages.showInputDialog(myProject, "Profile name", "Create new profile", null, "", new InputValidatorEx() { + @Override + public boolean checkInput(String inputString) { + return !DEFAULT_PROFILE.equals(inputString) && !profiles.containsKey(inputString) && !StringUtil.isEmpty(inputString); + } + + @Override + public boolean canClose(String inputString) { + return checkInput(inputString); + } + + @Override + public String getErrorText(String inputString) { + if (checkInput(inputString)) return null; + return StringUtil.isEmpty(inputString) ? "Profile name shouldn't be empty" + : "Profile " + inputString + " already exists"; + } + }); + if (profile != null) { + profiles.put(profile, new ArrayList()); + } + ((SyncWithMap)getRoot()).sync(); + final DefaultMutableTreeNode object = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)getRoot(), profile); + if (object != null) { + TreeUtil.selectNode(myTree, object); + } + return null; + } + + @Override + public void removeNode(TreePath parent) { + } + + @Override + public void moveNodeTo(TreePath parentOrNeighbour) { + } + + } + + + private class MyRootNode extends DefaultMutableTreeNode implements SyncWithMap { + @Override + public SyncWithMap sync() { + final Vector newKids = new Vector(); + for (String key : profiles.keySet()) { + newKids.add(new MyProfileNode(key, this).sync()); + } + newKids.add(new MyProfileNode(DEFAULT_PROFILE, this).sync()); + children = newKids; + ((DefaultTreeModel)myTree.getModel()).reload(); + expand(myTree); + return this; + } + } + + private interface SyncWithMap { + SyncWithMap sync(); + } + + private class MyProfileNode extends DefaultMutableTreeNode implements SyncWithMap { + private final String myKey; + + public MyProfileNode(String key, MyRootNode parent) { + super(key); + setParent(parent); + myKey = key; + } + + @Override + public SyncWithMap sync() { + final List nodeModules; + if (DEFAULT_PROFILE.equals(myKey)) { + final Module[] allModules = ModuleManager.getInstance(myProject).getSortedModules(); + nodeModules = new ArrayList(Arrays.asList(allModules)); + for (List modules : profiles.values()) { + for (Module module : modules) { + nodeModules.remove(module); + } + } + } else { + nodeModules = profiles.get(myKey); + } + final Vector vector = new Vector(); + for (Module module : nodeModules) { + vector.add(new MyModuleNode(module, this)); + } + children = vector; + return this; + } + } + + private class MyModuleNode extends DefaultMutableTreeNode { + public MyModuleNode(Module module, MyProfileNode parent) { + super(module); + setParent(parent); + setAllowsChildren(false); + } + } + + private class MyCellRenderer extends ColoredTreeCellRenderer { + @Override + public void customizeCellRenderer(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + if (value instanceof MyProfileNode) { + append(((MyProfileNode)value).myKey); + } else if (value instanceof MyModuleNode) { + final Module module = (Module)((MyModuleNode)value).getUserObject(); + setIcon(IconLoader.getIcon("/nodes/ModuleClosed.png")); + append(module.getName()); + } + } + } +} diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 0efa25f378ac..5a0ba7439fb2 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -58,6 +58,8 @@ import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.util.Alarm; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.net.NetUtils; +import gnu.trove.THashSet; +import gnu.trove.TObjectHashingStrategy; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.*; import org.jboss.netty.channel.group.ChannelGroup; @@ -76,8 +78,7 @@ import org.jetbrains.jps.cmdline.BuildMain; import org.jetbrains.jps.server.ClasspathBootstrap; import org.jetbrains.jps.server.Server; -import javax.tools.JavaCompiler; -import javax.tools.ToolProvider; +import javax.tools.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -525,7 +526,7 @@ public class BuildManager implements ApplicationComponent{ } final String defaultCharset = EncodingManager.getInstance().getDefaultCharsetName(); - if (defaultCharset != null) { + if (!StringUtil.isEmpty(defaultCharset)) { cmdBuilder.setGlobalEncoding(defaultCharset); } @@ -845,8 +846,8 @@ public class BuildManager implements ApplicationComponent{ private static class ProjectData { final SequentialTaskExecutor taskQueue; - private final Set myChanged = new HashSet(); - private final Set myDeleted = new HashSet(); + private final Set myChanged = new THashSet(PathHashingStrategy.INSTANCE); + private final Set myDeleted = new THashSet(PathHashingStrategy.INSTANCE); private long myNextEventOrdinal = 0L; private boolean myNeedRescan = true; @@ -891,6 +892,20 @@ public class BuildManager implements ApplicationComponent{ myChanged.clear(); myDeleted.clear(); } + + static class PathHashingStrategy implements TObjectHashingStrategy { + static final PathHashingStrategy INSTANCE = new PathHashingStrategy(); + + @Override + public int computeHashCode(String path) { + return FileUtil.pathHashCode(path); + } + + @Override + public boolean equals(String path1, String path2) { + return FileUtil.pathsEqual(path1, path2); + } + } } } diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java index f2b8d46c24ea..12e5d3354995 100644 --- a/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java +++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java @@ -33,6 +33,8 @@ public abstract class CompilerConfiguration { @Nullable public abstract String getBytecodeTargetLevel(Module module); + public abstract void setBytecodeTargetLevel(Module module, String level); + public static CompilerConfiguration getInstance(Project project) { return project.getComponent(CompilerConfiguration.class); } @@ -72,5 +74,4 @@ public abstract class CompilerConfiguration { public abstract boolean isAnnotationProcessingEnabled(Module module); public abstract String getGeneratedSourceDirName(Module module); - } \ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java index bec0848383fb..053f4448e1d2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java @@ -79,7 +79,7 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory { return null; } - if (parameters.getInvocationCount() <= 1 && JavaCompletionUtil.containsMethodCalls(expression)) { + if (parameters.getInvocationCount() <= 1 && JavaCompletionUtil.mayHaveSideEffects(expression)) { final CompletionService service = CompletionService.getCompletionService(); if (service.getAdvertisementText() == null && parameters.getInvocationCount() < 2) { service.setAdvertisementText("Invoke completion once more to see runtime type variants"); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index 33cf0e16f211..675ba7211a7a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -33,9 +33,9 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Key; -import com.intellij.ui.popup.util.ItemWrapper; -import com.intellij.ui.popup.util.SplitterItem; import com.intellij.xdebugger.AbstractDebuggerSession; +import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import com.intellij.xdebugger.impl.DebuggerSupport; import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler; @@ -213,6 +213,11 @@ public class JavaDebuggerSupport extends DebuggerSupport { return result.toArray(new AnAction[result.size()]); } + @Override + public void provideBreakpointsGroupingRules(Collection rules) { + rules.add(new XBreakpointGroupingByCategoryRule()); + } + @Override public void addListener(final BreakpointsListener listener, Project project) { final MyBreakpointManagerListener listener1 = new MyBreakpointManagerListener(listener); @@ -254,13 +259,10 @@ public class JavaDebuggerSupport extends DebuggerSupport { } @Override - public void provideBreakpointItems(Project project, Collection items) { + public void provideBreakpointItems(Project project, Collection items) { for (BreakpointFactory breakpointFactory : BreakpointFactory.getBreakpointFactories()) { Key category = breakpointFactory.getBreakpointCategory(); Breakpoint[] breakpoints = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().getBreakpoints(category); - if (breakpoints.length > 0) { - items.add(new SplitterItem(breakpointFactory.getDisplayName())); - } for (Breakpoint breakpoint : breakpoints) { items.add(breakpointFactory.createBreakpointItem(breakpoint)); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java new file mode 100644 index 000000000000..bfb59e0a412b --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui; + +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointFactory; +import com.intellij.openapi.util.Key; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * Created with IntelliJ IDEA. + * User: zajac + * Date: 23.05.12 + * Time: 16:22 + * To change this template use File | Settings | File Templates. + */ +public class XBreakpointCategoryGroup extends XBreakpointGroup { + private Key myCategory; + private Icon myIcon; + private final String myName; + + public XBreakpointCategoryGroup(BreakpointFactory factory) { + myCategory = factory.getBreakpointCategory(); + myIcon = factory.getIcon(); + final String name = factory.getDisplayName(); + myName = name != null ? name : "UNKNOWN"; + } + + public Key getCategory() { + return myCategory; + } + + @Override + public Icon getIcon(boolean isOpen) { + return myIcon; + } + + @NotNull + @Override + public String getName() { + return myName; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java new file mode 100644 index 000000000000..477417f54ee7 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui; + +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.breakpoints.BreakpointFactory; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** +* Created with IntelliJ IDEA. +* User: zajac +* Date: 23.05.12 +* Time: 16:24 +* To change this template use File | Settings | File Templates. +*/ +class XBreakpointGroupingByCategoryRule extends XBreakpointGroupingRule { + XBreakpointGroupingByCategoryRule() { + super("XBreakpointGroupingByCategoryRule", "Type"); + } + + @Override + public XBreakpointCategoryGroup getGroup(@NotNull B b, @NotNull Collection groups) { + if (b instanceof Breakpoint) { + final Breakpoint breakpoint = (Breakpoint)b; + for (XBreakpointCategoryGroup group : groups) { + if (group.getCategory().equals(breakpoint.getCategory())) { + return group; + } + } + final BreakpointFactory factory = BreakpointFactory.getInstance(breakpoint.getCategory()); + if (factory != null) { + return new XBreakpointCategoryGroup(factory); + } + } + return null; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java index 74febadb6647..a186926b531b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java @@ -18,9 +18,9 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.SourcePosition; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.popup.util.DetailView; import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; @@ -43,12 +43,11 @@ class JavaBreakpointItem extends BreakpointItem { } @Override - public void setupRenderer(ColoredListCellRenderer renderer, Project project, boolean selected) { - renderer.setIcon(myBreakpoint.getIcon()); - renderer.append(myBreakpoint.getShortName()); + protected void setupGenericRenderer(SimpleColoredComponent renderer) { + //renderer.setIcon(myBreakpoint.getIcon()); + renderer.append(myBreakpoint.getShortName(), isEnabled() ? SimpleTextAttributes.REGULAR_ATTRIBUTES : SimpleTextAttributes.GRAY_ATTRIBUTES); } - @Override public String speedSearchText() { return myBreakpoint.getDisplayName(); diff --git a/java/idea-ui/src/com/intellij/openapi/project/impl/convertors/Convertor34.java b/java/idea-ui/src/com/intellij/openapi/project/impl/convertors/Convertor34.java index cdf6eb16b8ce..7a0fb722bd88 100644 --- a/java/idea-ui/src/com/intellij/openapi/project/impl/convertors/Convertor34.java +++ b/java/idea-ui/src/com/intellij/openapi/project/impl/convertors/Convertor34.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; import java.io.BufferedWriter; import java.io.File; @@ -51,7 +52,7 @@ public class Convertor34 { private static final String JAVA_DOC_ROOTS_CANNOT_BE_CONVERTED = ProjectBundle.message("project.convert.javadoc.paths.error"); private static final String MULTIPLE_OUTPUT_PATHS = ProjectBundle.message("project.convert.multiple.output.paths.error"); - public static void execute(Element root, String filePath, ArrayList conversionProblems) { + public static void execute(Element root, String filePath, @Nullable ArrayList conversionProblems) { if (filePath == null) return; if (conversionProblems == null) { diff --git a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form index 05d0e4fc2e72..4527440fd6c7 100644 --- a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form +++ b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form @@ -30,7 +30,7 @@ - + @@ -174,7 +174,7 @@ - + @@ -191,7 +191,7 @@ - + @@ -224,7 +224,7 @@ - + @@ -263,7 +263,7 @@ - + diff --git a/java/java-impl/src/com/intellij/application/options/JavadocOptionsProvider.form b/java/java-impl/src/com/intellij/application/options/JavadocOptionsProvider.form index e0dfae8ec5fa..2c2d830e1ec5 100644 --- a/java/java-impl/src/com/intellij/application/options/JavadocOptionsProvider.form +++ b/java/java-impl/src/com/intellij/application/options/JavadocOptionsProvider.form @@ -15,7 +15,7 @@ - + diff --git a/java/java-impl/src/com/intellij/application/options/editor/JavaAutoImportOptions.form b/java/java-impl/src/com/intellij/application/options/editor/JavaAutoImportOptions.form index 871be0bad92c..0c61b43980d3 100644 --- a/java/java-impl/src/com/intellij/application/options/editor/JavaAutoImportOptions.form +++ b/java/java-impl/src/com/intellij/application/options/editor/JavaAutoImportOptions.form @@ -7,7 +7,7 @@ - + diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 6cc5e983fc69..d96b05aaf471 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -77,6 +77,19 @@ public class ConstructorInsertHandler implements InsertHandler 0 && ((PsiTypeLookupItem)delegate).calcGenerics(position, context).isEmpty() && context.getCompletionChar() != '('; + + if (context.getDocument().getTextLength() > context.getTailOffset() && + context.getDocument().getCharsSequence().charAt(context.getTailOffset()) == '<') { + PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getTailOffset(), PsiJavaCodeReferenceElement.class, false); + if (ref != null) { + PsiReferenceParameterList parameterList = ref.getParameterList(); + if (parameterList != null && context.getTailOffset() == parameterList.getTextRange().getStartOffset()) { + context.getDocument().deleteString(parameterList.getTextRange().getStartOffset(), parameterList.getTextRange().getEndOffset()); + context.commitDocument(); + } + } + } + delegate.handleInsert(context); PostprocessReformattingAspect.getInstance(context.getProject()).doPostponedFormatting(context.getFile().getViewProvider()); } @@ -85,6 +98,7 @@ public class ConstructorInsertHandler implements InsertHandler afterNegativeStats = new ArrayList(); if (!smart) { - ContainerUtil.addIfNotNull(afterNegativeStats, preferStatics(position)); + ContainerUtil.addIfNotNull(afterNegativeStats, preferStatics(position, expectedTypes)); } afterNegativeStats.add(new PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(type, position)); ContainerUtil.addIfNotNull(afterNegativeStats, recursion(parameters, expectedTypes)); @@ -126,7 +126,7 @@ public class JavaCompletionSorting { } @Nullable - private static LookupElementWeigher preferStatics(PsiElement position) { + private static LookupElementWeigher preferStatics(PsiElement position, final ExpectedTypeInfo[] infos) { if (PsiTreeUtil.getParentOfType(position, PsiDocComment.class) != null) { return null; } @@ -149,7 +149,7 @@ public class JavaCompletionSorting { if (o instanceof PsiKeyword) return -3; if (!(o instanceof PsiMember)) return 0; - if (((PsiMember)o).hasModifierProperty(PsiModifier.STATIC)) { + if (((PsiMember)o).hasModifierProperty(PsiModifier.STATIC) && !hasNonVoid(infos)) { if (o instanceof PsiMethod) return -5; if (o instanceof PsiField) return -4; } @@ -179,14 +179,7 @@ public class JavaCompletionSorting { } } - boolean hasNonVoid = false; - for (ExpectedTypeInfo info : expectedInfos) { - if (!PsiType.VOID.equals(info.getType())) { - hasNonVoid = true; - } - } - - if (hasNonVoid) { + if (hasNonVoid(expectedInfos)) { if (item.getObject() instanceof PsiKeyword) { String keyword = ((PsiKeyword)item.getObject()).getText(); if (PsiKeyword.NEW.equals(keyword) || PsiKeyword.NULL.equals(keyword)) { @@ -201,6 +194,16 @@ public class JavaCompletionSorting { return ExpectedTypeMatching.normal; } + private static boolean hasNonVoid(ExpectedTypeInfo[] expectedInfos) { + boolean hasNonVoid = false; + for (ExpectedTypeInfo info : expectedInfos) { + if (!PsiType.VOID.equals(info.getType())) { + hasNonVoid = true; + } + } + return hasNonVoid; + } + @Nullable private static String getLookupObjectName(Object o) { if (o instanceof PsiVariable) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java index d05c520a1a67..9d0b5d02e854 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java @@ -62,17 +62,13 @@ public class JavaCompletionStatistician extends CompletionStatistician{ if (o instanceof PsiMember) { final boolean isClass = o instanceof PsiClass; if (qualifierType != null) { - if (type == CompletionType.SMART) { - String context; - if (isClass) { - context = JavaStatisticsManager.getAfterNewKey(qualifierType); - } else { - context = JavaStatisticsManager.getMemberUseKey1(qualifierType); - } - return new StatisticsInfo(context, JavaStatisticsManager.getMemberUseKey2((PsiMember)o)); + String context; + if (isClass) { + context = JavaStatisticsManager.getAfterNewKey(qualifierType); + } else { + context = JavaStatisticsManager.getMemberUseKey1(qualifierType); } - if (!isClass && type == CompletionType.BASIC) return JavaStatisticsManager.createInfo(qualifierType, (PsiMember)o); - return StatisticsInfo.EMPTY; + return new StatisticsInfo(context, JavaStatisticsManager.getMemberUseKey2((PsiMember)o)); } if (isClass) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index a97e1316b6ed..2e168b6291ab 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -677,18 +677,19 @@ public class JavaCompletionUtil { return ret; } - @Nullable - static PsiElement getQualifier(final PsiElement element) { - return element instanceof PsiJavaCodeReferenceElement ? ((PsiJavaCodeReferenceElement)element).getQualifier() : null; - } - - public static boolean containsMethodCalls(@Nullable final PsiElement qualifier) { - if (qualifier == null) return false; - if (qualifier instanceof PsiMethodCallExpression || qualifier instanceof PsiNewExpression) return true; - if (qualifier instanceof PsiArrayAccessExpression) { - return containsMethodCalls(((PsiArrayAccessExpression)qualifier).getArrayExpression()); + public static boolean mayHaveSideEffects(@Nullable final PsiElement element) { + if (element == null) return false; + if (element instanceof PsiMethodCallExpression || element instanceof PsiNewExpression) return true; + if (element instanceof PsiTypeCastExpression) { + return mayHaveSideEffects(((PsiTypeCastExpression)element).getOperand()); } - return containsMethodCalls(getQualifier(qualifier)); + if (element instanceof PsiArrayAccessExpression) { + return mayHaveSideEffects(((PsiArrayAccessExpression)element).getArrayExpression()); + } + if (element instanceof PsiJavaCodeReferenceElement) { + return mayHaveSideEffects(((PsiJavaCodeReferenceElement)element).getQualifier()); + } + return true; } public static void insertClassReference(@NotNull PsiClass psiClass, @NotNull PsiFile file, int offset) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java index 7c1a3b877601..d64ab398b42a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java @@ -21,6 +21,7 @@ import com.intellij.codeInsight.lookup.LookupElementWeigher; import com.intellij.psi.*; import com.intellij.psi.filters.getters.MembersGetter; import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import java.util.Set; @@ -30,11 +31,13 @@ import java.util.Set; */ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupElementWeigher { private final CompletionType myCompletionType; + private final PsiElement myPosition; private final Set myNonInitializedFields; public PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(CompletionType completionType, PsiElement position) { super("local"); myCompletionType = completionType; + myPosition = position; myNonInitializedFields = JavaCompletionProcessor.getNonInitializedFields(position); } @@ -60,7 +63,10 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle if (object instanceof PsiKeyword) { String keyword = ((PsiKeyword)object).getText(); - if (PsiKeyword.RETURN.equals(keyword) || PsiKeyword.ELSE.equals(keyword) || PsiKeyword.FINALLY.equals(keyword)) { + if (PsiKeyword.RETURN.equals(keyword) && isLastStatement(PsiTreeUtil.getParentOfType(myPosition, PsiStatement.class))) { + return MyResult.probableKeyword; + } + if (PsiKeyword.ELSE.equals(keyword) || PsiKeyword.FINALLY.equals(keyword)) { return MyResult.probableKeyword; } } @@ -118,4 +124,12 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends LookupEle return MyResult.normal; } + + private static boolean isLastStatement(PsiStatement statement) { + if (statement == null || !(statement.getParent() instanceof PsiCodeBlock)) { + return true; + } + PsiStatement[] siblings = ((PsiCodeBlock)statement.getParent()).getStatements(); + return statement == siblings[siblings.length - 1]; + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index 454fcf02d7b1..b164555b8576 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -274,7 +274,9 @@ public class ReferenceExpressionCompletionContributor { } if (itemType == null) return; - final PsiElement qualifier = JavaCompletionUtil.getQualifier(reference.getElement()); + final PsiElement element1 = reference.getElement(); + final PsiElement qualifier = + element1 instanceof PsiJavaCodeReferenceElement ? ((PsiJavaCodeReferenceElement)element1).getQualifier() : null; final PsiType expectedType = parameters.getExpectedType(); if (!OBJECT_METHOD_PATTERN.accepts(object) || allowGetClass(object, parameters)) { if (parameters.getParameters().getInvocationCount() >= 3 || !itemType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { @@ -398,7 +400,7 @@ public class ReferenceExpressionCompletionContributor { } final String bracketSpace = getSpace(CodeStyleSettingsManager.getSettings(element.getProject()).SPACE_WITHIN_BRACKETS); - if (object instanceof PsiVariable && !JavaCompletionUtil.containsMethodCalls(qualifier)) { + if (object instanceof PsiVariable && !JavaCompletionUtil.mayHaveSideEffects(qualifier)) { final PsiVariable variable = (PsiVariable)object; addToArrayConversion(element, prefix, "new " + componentType.getCanonicalText() + diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java new file mode 100644 index 000000000000..cbc4dc935246 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.daemon.impl; + +import com.intellij.codeHighlighting.Pass; +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.openapi.editor.markup.GutterIconRenderer; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.FunctionUtil; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Danila Ponomarenko + */ +public class RecursiveCallLineMarkerProvider implements LineMarkerProvider, DumbAware { + private static final Icon RECURSIVE_METHOD_ICON = IconLoader.getIcon("/gutter/recursiveMethod.png"); + + @Override + public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) { + return null; //do nothing + } + + @Override + public void collectSlowLineMarkers(@NotNull List elements, @NotNull Collection result) { + final Set statements = new HashSet(); + + for (PsiElement element : elements) { + if (element instanceof PsiMethodCallExpression) { + final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element; + final PsiStatement statement = PsiTreeUtil.getParentOfType(methodCall, PsiStatement.class, true, PsiMethod.class); + if (!statements.contains(statement) && isRecursiveMethodCall(methodCall)) { + statements.add(statement); + result.add(new RecursiveMethodCallMarkerInfo(methodCall)); + } + } + } + } + + private static boolean isRecursiveMethodCall(@NotNull PsiMethodCallExpression methodCall) { + final PsiMethod referencedMethod = methodCall.resolveMethod(); + + if (referencedMethod == null || !referencedMethod.isValid() || !methodCall.isValid()) { + return false; + } + + final PsiFile methodCallFile = methodCall.getContainingFile(); + final PsiFile methodFile = referencedMethod.getContainingFile(); + + if (methodCallFile == null || methodFile == null || !methodCallFile.equals(methodFile)) { + return false; + } + + final TextRange rmRange = referencedMethod.getTextRange(); + final int mcOffset = methodCall.getTextRange().getStartOffset(); + return rmRange != null && rmRange.contains(mcOffset); + } + + private static class RecursiveMethodCallMarkerInfo extends LineMarkerInfo { + private RecursiveMethodCallMarkerInfo(@NotNull PsiMethodCallExpression methodCall) { + super(methodCall, + methodCall.getTextRange(), + RECURSIVE_METHOD_ICON, + Pass.UPDATE_OVERRIDEN_MARKERS, + FunctionUtil.constant("Recursive method call"), + null, + GutterIconRenderer.Alignment.RIGHT + ); + } + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index 3a9857459cdc..1626942bd07b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -390,7 +390,7 @@ public class GenericsHighlightUtil { if (extendFrom == null) return null; HighlightInfo errorResult = null; if (!extendFrom.isInterface() && referenceElements.length != 0 && element != referenceElements[0]) { - final String description = HighlightClassUtil.INTERFACE_EXPECTED; + String description = JavaErrorMessages.message("interface.expected"); errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, element, description); PsiClassType type = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory().createType(extendFrom, resolveResult.getSubstitutor()); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java index f980b7e3e172..535aee6ea37b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java @@ -60,9 +60,6 @@ import java.util.HashSet; import java.util.List; public class HighlightClassUtil { - public static final String INTERFACE_EXPECTED = JavaErrorMessages.message("interface.expected"); - public static final String NO_INTERFACE_EXPECTED = JavaErrorMessages.message("no.interface.expected"); - private static final String STATIC_DECLARATION_IN_INNER_CLASS = JavaErrorMessages.message("static.declaration.in.inner.class"); private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance(); /** @@ -280,9 +277,8 @@ public class HighlightClassUtil { if (PsiUtil.isCompileTimeConstant(field)) { return null; } - HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, - keyword, - STATIC_DECLARATION_IN_INNER_CLASS); + String message = JavaErrorMessages.message("static.declaration.in.inner.class"); + HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, keyword, message); IntentionAction fix1 = QUICK_FIX_FACTORY.createModifierListFix(field, PsiModifier.STATIC, false, false); QuickFixAction.registerQuickFixAction(errorResult, fix1); IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(field.getContainingClass(), PsiModifier.STATIC, true, false); @@ -297,9 +293,8 @@ public class HighlightClassUtil { } PsiMethod method = (PsiMethod)keyword.getParent().getParent(); if (PsiUtilCore.hasErrorElementChild(method)) return null; - HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, - keyword, - STATIC_DECLARATION_IN_INNER_CLASS); + String message = JavaErrorMessages.message("static.declaration.in.inner.class"); + HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, keyword, message); IntentionAction fix1 = QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.STATIC, false, false); QuickFixAction.registerQuickFixAction(errorResult, fix1); IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix((PsiClass)keyword.getParent().getParent().getParent(), PsiModifier.STATIC, true, false); @@ -314,9 +309,8 @@ public class HighlightClassUtil { } PsiClassInitializer initializer = (PsiClassInitializer)keyword.getParent().getParent(); if (PsiUtilCore.hasErrorElementChild(initializer)) return null; - HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, - keyword, - STATIC_DECLARATION_IN_INNER_CLASS); + String message = JavaErrorMessages.message("static.declaration.in.inner.class"); + HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, keyword, message); IntentionAction fix1 = QUICK_FIX_FACTORY.createModifierListFix(initializer, PsiModifier.STATIC, false, false); QuickFixAction.registerQuickFixAction(errorResult, fix1); PsiClass owner = (PsiClass)keyword.getParent().getParent().getParent(); @@ -364,7 +358,8 @@ public class HighlightClassUtil { if (textRange == null) { textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass); } - HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, STATIC_DECLARATION_IN_INNER_CLASS); + String message = JavaErrorMessages.message("static.declaration.in.inner.class"); + HighlightInfo errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, message); if (context != keyword) { IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(aClass, PsiModifier.STATIC, false, false); QuickFixAction.registerQuickFixAction(errorResult, fix); @@ -425,9 +420,8 @@ public class HighlightClassUtil { HighlightInfo errorResult = null; PsiClass extendFrom = (PsiClass)resolveResult.getElement(); if (extendFrom.isInterface() != mustBeInterface) { - errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, - ref, - mustBeInterface ? INTERFACE_EXPECTED : NO_INTERFACE_EXPECTED); + String message = JavaErrorMessages.message(mustBeInterface ? "interface.expected" : "no.interface.expected"); + errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, ref, message); PsiClassType type = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory().createType(ref); QuickFixAction.registerQuickFixAction(errorResult, new ChangeExtendsToImplementsFix(aClass, type)); @@ -640,7 +634,8 @@ public class HighlightClassUtil { } - public static HighlightInfo checkQualifiedNewOfStaticClass(PsiNewExpression expression) { + @Nullable + public static HighlightInfo checkQualifiedNew(PsiNewExpression expression) { PsiExpression qualifier = expression.getQualifier(); if (qualifier == null) return null; PsiType type = expression.getType(); @@ -652,18 +647,28 @@ public class HighlightClassUtil { return info; } PsiClass aClass = PsiUtil.resolveClassInType(type); - if (aClass != null && aClass.hasModifierProperty(PsiModifier.STATIC)) { - HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, - expression, - JavaErrorMessages.message("qualified.new.of.static.class")); - if (!aClass.isEnum()) { - IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(aClass, PsiModifier.STATIC, false, false); - QuickFixAction.registerQuickFixAction(info, fix); + HighlightInfo info = null; + if (aClass != null) { + if (aClass.hasModifierProperty(PsiModifier.STATIC)) { + info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, + expression, + JavaErrorMessages.message("qualified.new.of.static.class")); + if (!aClass.isEnum()) { + IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(aClass, PsiModifier.STATIC, false, false); + QuickFixAction.registerQuickFixAction(info, fix); + } + + } else if (aClass instanceof PsiAnonymousClass) { + final PsiClass baseClass = PsiUtil.resolveClassInType(((PsiAnonymousClass)aClass).getBaseClassType()); + if (baseClass != null && baseClass.isInterface()) { + info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, + expression, + "Anonymous class implements interface; cannot have qualifier for new"); + } } QuickFixAction.registerQuickFixAction(info, new RemoveNewQualifierFix(expression, aClass)); - return info; } - return null; + return info; } @@ -840,8 +845,9 @@ public class HighlightClassUtil { } PsiModifierListOwner staticParent = PsiUtil.getEnclosingStaticElement(place, outerClass); if (staticParent != null) { - String description = JavaErrorMessages.message("cannot.be.referenced.from.static.context", - outerClass == null ? "" : HighlightUtil.formatClass(outerClass) + "." + PsiKeyword.THIS); + String element = outerClass == null ? "" : HighlightUtil.formatClass(outerClass) + "." + + (place instanceof PsiSuperExpression ? PsiKeyword.SUPER : PsiKeyword.THIS); + String description = JavaErrorMessages.message("cannot.be.referenced.from.static.context", element); HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, elementToHighlight, description); // make context not static or referenced class static IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(staticParent, PsiModifier.STATIC, false, false); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 399082d491c6..d124608b2ad3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -838,14 +838,19 @@ public class HighlightMethodUtil { return null; } - + @Nullable static HighlightInfo checkMethodCanHaveBody(PsiMethod method) { if (method.getBody() == null) return null; PsiClass aClass = method.getContainingClass(); String message = null; if (aClass != null && aClass.isInterface()) { - message = JavaErrorMessages.message("interface.methods.cannot.have.body"); + if (!PsiUtil.isExtensionMethod(method)) { + message = JavaErrorMessages.message("interface.methods.cannot.have.body"); + } + else { + return HighlightUtil.checkExtensionMethodsFeature(method); + } } else if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { message = JavaErrorMessages.message("abstract.methods.cannot.have.a.body"); @@ -853,21 +858,19 @@ public class HighlightMethodUtil { else if (method.hasModifierProperty(PsiModifier.NATIVE)) { message = JavaErrorMessages.message("native.methods.cannot.have.a.body"); } + if (message == null) return null; - if (message != null) { - TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method); - HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, message); - QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method)); - if (method.hasModifierProperty(PsiModifier.ABSTRACT) && aClass != null && !aClass.isInterface()) { - IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.ABSTRACT, false, false); - QuickFixAction.registerQuickFixAction(info, fix); - } - return info; + TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method); + HighlightInfo info = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, textRange, message); + QuickFixAction.registerQuickFixAction(info, new DeleteMethodBodyFix(method)); + if (method.hasModifierProperty(PsiModifier.ABSTRACT) && aClass != null && !aClass.isInterface()) { + IntentionAction fix = QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.ABSTRACT, false, false); + QuickFixAction.registerQuickFixAction(info, fix); } - return null; + return info; } - + @Nullable static HighlightInfo checkConstructorCallMustBeFirstStatement(PsiReferenceExpression expression) { PsiElement methodCall = expression.getParent(); if (!HighlightUtil.isSuperOrThisMethodCall(methodCall)) return null; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 3a54ada2c167..ac3a5df3c7ad 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -78,7 +78,7 @@ public class HighlightUtil { private static final Map> ourClassInitializerIncompatibleModifiers; private static final Set ourConstructorNotAllowedModifiers; - @NonNls private static final String SERIAL_VERSION_UID_FIELD_NAME = "serialVersionUID"; + @NonNls public static final String SERIAL_VERSION_UID_FIELD_NAME = "serialVersionUID"; @NonNls private static final String SERIAL_PERSISTENT_FIELDS_FIELD_NAME = "serialPersistentFields"; private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance(); @@ -1328,14 +1328,13 @@ public class HighlightUtil { } if (aClass == null) return null; if (qualifier != null && aClass.isInterface()) { - return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, qualifier, HighlightClassUtil.NO_INTERFACE_EXPECTED); + return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, qualifier, JavaErrorMessages.message("no.interface.expected")); } if (!HighlightClassUtil.hasEnclosingInstanceInScope(aClass, expr, false)) { return HighlightClassUtil.reportIllegalEnclosingUsage(expr, null, aClass, expr); } return null; - } static String buildProblemWithStaticDescription(PsiElement refElement) { @@ -2481,7 +2480,8 @@ public class HighlightUtil { VARARGS(LanguageLevel.JDK_1_5, "feature.varargs"), DIAMOND_TYPES(LanguageLevel.JDK_1_7, "feature.diamond.types"), MULTI_CATCH(LanguageLevel.JDK_1_7, "feature.multi.catch"), - TRY_WITH_RESOURCES(LanguageLevel.JDK_1_7, "feature.try.with.resources"); + TRY_WITH_RESOURCES(LanguageLevel.JDK_1_7, "feature.try.with.resources"), + EXTENSION_METHODS(LanguageLevel.JDK_1_8, "feature.extension.methods"); private final LanguageLevel level; private final String key; @@ -2544,4 +2544,9 @@ public class HighlightUtil { public static HighlightInfo checkTryWithResourcesFeature(final PsiResourceVariable resourceVariable) { return checkFeature(resourceVariable.getParent(), Feature.TRY_WITH_RESOURCES); } + + @Nullable + public static HighlightInfo checkExtensionMethodsFeature(final PsiMethod method) { + return checkFeature(method, Feature.EXTENSION_METHODS); + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index dbe30be7f944..4de3dad216db 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -698,7 +698,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh @Override public void visitNewExpression(PsiNewExpression expression) { myHolder.add(HighlightUtil.checkUnhandledExceptions(expression, null)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkAnonymousInheritFinal(expression)); - if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNewOfStaticClass(expression)); + if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkQualifiedNew(expression)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(expression)); if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkTypeParameterInstantiation(expression)); try { diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java index 939b55ac9ff5..e183c5d8e9da 100644 --- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java +++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java @@ -16,6 +16,7 @@ package com.intellij.codeInsight.folding.impl; import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import com.intellij.codeInsight.folding.JavaCodeFoldingSettings; import com.intellij.codeInsight.generation.OverrideImplementUtil; import com.intellij.lang.ASTNode; @@ -43,7 +44,6 @@ import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Function; -import com.intellij.util.ObjectUtils; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -565,9 +565,15 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar } } - private static boolean hasOnlyOneMethod(@NotNull PsiAnonymousClass anonymousClass) { - if (anonymousClass.getFields().length != 0) { - return false; + private static boolean hasOnlyOneMethod(@NotNull PsiAnonymousClass anonymousClass, boolean checkResolve) { + PsiField[] fields = anonymousClass.getFields(); + if (fields.length != 0) { + if (fields.length == 1 && HighlightUtil.SERIAL_VERSION_UID_FIELD_NAME.equals(fields[0].getName()) && + fields[0].hasModifierProperty(PsiModifier.STATIC)) { + //ok + } else { + return false; + } } if (anonymousClass.getInitializers().length != 0) { return false; @@ -576,7 +582,20 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar return false; } - return anonymousClass.getMethods().length == 1; + if (anonymousClass.getMethods().length != 1) { + return false; + } + + if (checkResolve) { + PsiReferenceList throwsList = anonymousClass.getMethods()[0].getThrowsList(); + for (PsiClassType type : throwsList.getReferencedTypes()) { + if (type.resolve() == null) { + return false; + } + } + } + + return true; } private boolean addClosureFolding(final PsiClass aClass, final Document document, final List foldElements, @@ -594,7 +613,7 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar final PsiExpressionList argumentList = expression.getArgumentList(); if (argumentList != null && argumentList.getExpressions().length == 0) { final PsiMethod[] methods = anonymousClass.getMethods(); - if (hasOnlyOneMethod(anonymousClass) && (quick || seemsLikeLambda(anonymousClass.getBaseClassType().resolve()))) { + if (hasOnlyOneMethod(anonymousClass, !quick) && (quick || seemsLikeLambda(anonymousClass.getBaseClassType().resolve()))) { final PsiMethod method = methods[0]; final PsiCodeBlock body = method.getBody(); if (body != null) { @@ -626,35 +645,13 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar if (lastLineEnd > 0 && seq.charAt(lastLineEnd) == '\n') lastLineEnd--; if (lastLineEnd < firstLineStart) return false; - final String baseClassName = quick ? - anonymousClass.getBaseClassReference().getReferenceName() : - ObjectUtils.assertNotNull(anonymousClass.getBaseClassType().resolve()).getName(); - if (lastLineEnd >= seq.length() || firstLineStart >= seq.length() || firstLineStart < 0) { - LOG.error("llE=" + lastLineEnd + "; fLS=" + firstLineStart + "; len=" + seq.length() + "rE=" + rangeEnd + "; class=" + - baseClassName); - } - final String params = StringUtil.join(method.getParameterList().getParameters(), new Function() { @Override public String fun(final PsiParameter psiParameter) { - String typeName; - if (quick) { - PsiTypeElement typeElement = psiParameter.getTypeElement(); - assert typeElement != null; - typeName = typeElement.getText(); - } - else { - typeName = psiParameter.getType().getPresentableText(); - } - int genStart = typeName.indexOf('<'); - int genEnd = typeName.lastIndexOf('>'); - if (genStart > 0 && genEnd > 0) { - typeName = typeName.substring(0, genStart) + typeName.substring(genEnd + 1); - } - return typeName + " " + psiParameter.getName(); + return psiParameter.getName(); } }, ", "); - @NonNls final String lambdas = baseClassName + "(" + params + ") {"; + @NonNls final String lambdas = "{" + params + " =>"; final int closureStart = expression.getTextRange().getStartOffset(); final int closureEnd = expression.getTextRange().getEndOffset(); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterSetterHandlerBase.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterSetterHandlerBase.java index 8874a983e58a..0bda4000366b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterSetterHandlerBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateGetterSetterHandlerBase.java @@ -35,7 +35,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -abstract class GenerateGetterSetterHandlerBase extends GenerateMembersHandlerBase { +public abstract class GenerateGetterSetterHandlerBase extends GenerateMembersHandlerBase { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.GenerateGetterSetterHandlerBase"); static { @@ -44,7 +44,7 @@ abstract class GenerateGetterSetterHandlerBase extends GenerateMembersHandlerBas public Collection fun(PsiClass s) { if (s.getLanguage() != StdLanguages.JAVA) return Collections.emptyList(); final List result = new ArrayList(); - for(PsiField field: s.getFields()) { + for (PsiField field : s.getFields()) { if (!(field instanceof PsiEnumConstant)) { result.add(new PsiFieldMember(field)); } @@ -75,6 +75,11 @@ abstract class GenerateGetterSetterHandlerBase extends GenerateMembersHandlerBas protected abstract String getNothingFoundMessage(); protected abstract String getNothingAcceptedMessage(); + public boolean canBeAppliedTo(PsiClass targetClass) { + final ClassMember[] allMembers = getAllOriginalMembers(targetClass); + return allMembers != null && allMembers.length != 0; + } + @Nullable protected ClassMember[] getAllOriginalMembers(final PsiClass aClass) { final List list = GenerateAccessorProviderRegistrar.getEncapsulatableClassMembers(aClass); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index 337db3857199..7d372661b0e5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -270,16 +270,13 @@ public class GenerateMembersUtil { final PsiType parameterType = parameter.getType(); PsiType substituted = substituteType(substitutor, parameterType); @NonNls String paramName = parameter.getName(); - final String[] baseSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, parameterType).names; - boolean isBaseNameGenerated = false; - for (String s : baseSuggestions) { - if (s.equals(paramName)) { - isBaseNameGenerated = true; - break; - } + boolean isBaseNameGenerated = true; + final boolean isSubstituted = substituted.equals(parameterType); + if (!isSubstituted && isBaseNameGenerated(codeStyleManager, TypeConversionUtil.erasure(parameterType), paramName)) { + isBaseNameGenerated = false; } - - if (paramName == null || isBaseNameGenerated && !substituted.equals(parameterType)) { + + if (paramName == null || isBaseNameGenerated && !isSubstituted && isBaseNameGenerated(codeStyleManager, parameterType, paramName)) { Pair pair = m.get(substituted); if (pair != null) { paramName = pair.first + pair.second; @@ -339,6 +336,18 @@ public class GenerateMembersUtil { } } + private static boolean isBaseNameGenerated(JavaCodeStyleManager codeStyleManager, PsiType parameterType, String paramName) { + final String[] baseSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, parameterType).names; + boolean isBaseNameGenerated = false; + for (String s : baseSuggestions) { + if (s.equals(paramName)) { + isBaseNameGenerated = true; + break; + } + } + return isBaseNameGenerated; + } + private static void processAnnotations(Project project, PsiModifierList modifierList, GlobalSearchScope moduleScope) { final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final Set toRemove = new HashSet(); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/JavaImplementMethodsHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/JavaImplementMethodsHandler.java index 3202c82f9648..554aa5151cf0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/JavaImplementMethodsHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/JavaImplementMethodsHandler.java @@ -34,7 +34,7 @@ public class JavaImplementMethodsHandler implements LanguageCodeInsightActionHan } PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, false); - return aClass != null; + return aClass != null && !OverrideImplementUtil.getMethodSignaturesToImplement(aClass).isEmpty(); } public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) { diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideMethodsHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideMethodsHandler.java index 24ce4d40af4a..5e3745b78f7c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideMethodsHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideMethodsHandler.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.generation; +import com.intellij.codeInsight.hint.HintManager; import com.intellij.lang.LanguageCodeInsightActionHandler; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -28,14 +29,23 @@ import org.jetbrains.annotations.NotNull; */ public class JavaOverrideMethodsHandler implements LanguageCodeInsightActionHandler { public boolean isValidFor(final Editor editor, final PsiFile file) { - return file instanceof PsiJavaFile && OverrideImplementUtil.getContextClass(file.getProject(), editor, file, true) != null; + if (!(file instanceof PsiJavaFile)) { + return false; + } + + PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, true); + return aClass != null && !OverrideImplementUtil.getMethodSignaturesToOverride(aClass).isEmpty(); } public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) { PsiClass aClass = OverrideImplementUtil.getContextClass(project, editor, file, true); - if (aClass != null) { - OverrideImplementUtil.chooseAndOverrideMethods(project, editor, aClass); + if (aClass == null) return; + + if (OverrideImplementUtil.getMethodSignaturesToOverride(aClass).isEmpty()) { + HintManager.getInstance().showErrorHint(editor, "No methods to override have been found"); + return; } + OverrideImplementUtil.chooseAndOverrideMethods(project, editor, aClass); } public boolean startInWriteAction() { diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAction.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAction.java index 672633a528f3..08063cdff16c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAction.java @@ -21,10 +21,9 @@ import com.intellij.codeInsight.generation.GenerateGetterHandler; * Action group which contains Generate... actions * Available in the Java code editor context only * @author Alexey Kudravtsev - */ -public class GenerateGetterAction extends BaseGenerateAction { + */ +public class GenerateGetterAction extends GenerateGetterSetterBaseAction { public GenerateGetterAction() { super(new GenerateGetterHandler()); } - } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAndSetterAction.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAndSetterAction.java index 7bdc0ccf979a..5b565cc249a4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAndSetterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterAndSetterAction.java @@ -22,9 +22,8 @@ import com.intellij.codeInsight.generation.GenerateGetterAndSetterHandler; * Available in the Java code editor context only * @author Alexey Kudravtsev */ -public class GenerateGetterAndSetterAction extends BaseGenerateAction { +public class GenerateGetterAndSetterAction extends GenerateGetterSetterBaseAction { public GenerateGetterAndSetterAction() { super(new GenerateGetterAndSetterHandler()); } - } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterSetterBaseAction.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterSetterBaseAction.java new file mode 100644 index 000000000000..e6056d84fad4 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateGetterSetterBaseAction.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.generation.actions; + +import com.intellij.codeInsight.generation.GenerateGetterSetterHandlerBase; +import com.intellij.psi.PsiClass; + +/** + * Action group which contains Generate... actions + * Available in the Java code editor context only + * @author Danila Ponomarenko + */ +public abstract class GenerateGetterSetterBaseAction extends BaseGenerateAction { + public GenerateGetterSetterBaseAction(GenerateGetterSetterHandlerBase handler) { + super(handler); + } + + @Override + protected boolean isValidForClass(PsiClass targetClass) { + final GenerateGetterSetterHandlerBase handler = (GenerateGetterSetterHandlerBase)getHandler(); + return handler.canBeAppliedTo(targetClass); + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSetterAction.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSetterAction.java index eebbc72b24f8..240befe1637e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSetterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSetterAction.java @@ -22,7 +22,7 @@ import com.intellij.codeInsight.generation.GenerateSetterHandler; * Available in the Java code editor context only * @author Alexey Kudravtsev */ -public class GenerateSetterAction extends BaseGenerateAction { +public class GenerateSetterAction extends GenerateGetterSetterBaseAction { public GenerateSetterAction() { super(new GenerateSetterHandler()); } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index f51ac1972979..51e886a9d872 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -1075,38 +1075,33 @@ class ControlFlowAnalyzer extends JavaElementVisitor { startElement(expression); DfaValue dfaValue = myFactory.create(expression); - if (dfaValue != null) { - addInstruction(new PushInstruction(dfaValue, expression)); - } - else { - PsiExpression condition = expression.getCondition(); + PsiExpression condition = expression.getCondition(); - PsiExpression thenExpression = expression.getThenExpression(); - PsiExpression elseExpression = expression.getElseExpression(); + PsiExpression thenExpression = expression.getThenExpression(); + PsiExpression elseExpression = expression.getElseExpression(); - final int elseOffset = elseExpression == null ? getEndOffset(expression) - 1 : getStartOffset(elseExpression); - if (thenExpression != null) { - condition.accept(this); - generateBoxingUnboxingInstructionFor(condition, PsiType.BOOLEAN); - PsiType type = expression.getType(); - addInstruction(new ConditionalGotoInstruction(elseOffset, true, condition)); - thenExpression.accept(this); - generateBoxingUnboxingInstructionFor(thenExpression,type); + final int elseOffset = elseExpression == null ? getEndOffset(expression) - 1 : getStartOffset(elseExpression); + if (thenExpression != null) { + condition.accept(this); + generateBoxingUnboxingInstructionFor(condition, PsiType.BOOLEAN); + PsiType type = expression.getType(); + addInstruction(new ConditionalGotoInstruction(elseOffset, true, condition)); + thenExpression.accept(this); + generateBoxingUnboxingInstructionFor(thenExpression,type); - addInstruction(new GotoInstruction(getEndOffset(expression))); + addInstruction(new GotoInstruction(getEndOffset(expression))); - if (elseExpression != null) { - elseExpression.accept(this); - generateBoxingUnboxingInstructionFor(elseExpression,type); - } - else { - pushUnknown(); - } + if (elseExpression != null) { + elseExpression.accept(this); + generateBoxingUnboxingInstructionFor(elseExpression,type); } else { pushUnknown(); } } + else { + pushUnknown(); + } finishElement(expression); } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index af8ccfdd5b82..718fc2c8b861 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -725,12 +725,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState { if (!myHasDirtyFields) return; myHasDirtyFields = false; - DfaVariableValue[] fields = runner.getFields(); - for (DfaVariableValue field : fields) { - boolean resetNullability = isNotNull(field); + for (DfaVariableValue field : runner.getFields()) { flushVariable(field); - if (resetNullability) { - } getVariableState(field).setNullable(false); } } diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java index d4d740f832b7..02dff3f737f1 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java @@ -30,6 +30,7 @@ import com.intellij.analysis.AnalysisScope; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.*; @@ -266,7 +267,7 @@ public class UnusedDeclarationInspection extends FilteringInspectionTool { private static boolean isSerializationImplicitlyUsedField(PsiField field) { @NonNls final String name = field.getName(); - if (!"serialVersionUID".equals(name) && !"serialPersistentFields".equals(name)) return false; + if (!HighlightUtil.SERIAL_VERSION_UID_FIELD_NAME.equals(name) && !"serialPersistentFields".equals(name)) return false; if (!field.hasModifierProperty(PsiModifier.STATIC)) return false; PsiClass aClass = field.getContainingClass(); return aClass == null || isSerializable(aClass, null); diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index 8da301fb80c6..c1ab84ce0bb0 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -125,13 +125,13 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { if (node == null) { return true; } + final IElementType type = node.getElementType(); - if (type == JavaDocTokenType.DOC_TAG_VALUE_TOKEN) { + if (type == JavaDocElementType.DOC_TAG_VALUE_ELEMENT) { return PsiTreeUtil.getParentOfType(parent, PsiDocMethodOrFieldRef.class) != null; } - return type == JavaDocElementType.DOC_COMMENT || type == JavaDocElementType.DOC_TAG - || type == JavaDocElementType.DOC_INLINE_TAG; + return type == JavaDocElementType.DOC_COMMENT || type == JavaDocElementType.DOC_TAG || type == JavaDocElementType.DOC_INLINE_TAG; } private void init(final ASTNode child) { @@ -1096,9 +1096,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { else if (myRole1 == ChildRole.OPERATION_SIGN) { createSpaceInCode(mySettings.SPACE_AROUND_UNARY_OPERATOR); } - else if (myChild1.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN - && myChild2.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN) - { + else if ((myType1 == JavaDocTokenType.DOC_TAG_VALUE_TOKEN || myType1 == JavaDocElementType.DOC_TAG_VALUE_ELEMENT) && + (myType2 == JavaDocTokenType.DOC_TAG_VALUE_TOKEN || myType2 == JavaDocElementType.DOC_TAG_VALUE_ELEMENT)) { createSpaceInCode(true); } else if (myRole1 == ChildRole.COMMA) { @@ -1516,7 +1515,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { } @Override public void visitDocTag(PsiDocTag tag) { - if (myChild1.getElementType() == JavaDocTokenType.DOC_TAG_NAME && myChild2.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN) { + if (myType1 == JavaDocTokenType.DOC_TAG_NAME && myType2 == JavaDocElementType.DOC_TAG_VALUE_ELEMENT) { myResult = Spacing.createSpacing(1, 1, 0, false, 0); } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaASTFactory.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaASTFactory.java index 9549f72b7ed1..20f7ab1e2f44 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaASTFactory.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaASTFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,9 @@ import com.intellij.psi.tree.IElementType; * @author max */ public class JavaASTFactory extends CoreJavaASTFactory { - @Override public CompositeElement createComposite(final IElementType type) { - if (type == DOC_TAG_VALUE_TOKEN) { + if (type == DOC_TAG_VALUE_ELEMENT) { return new PsiDocTagValueImpl(); } diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java index a6f6ba762f61..278a04df5c65 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java @@ -318,7 +318,9 @@ public final class PsiUtil extends PsiUtilCore { @PsiModifier.ModifierConstant @Nullable public static String getAccessModifier(int accessLevel) { - return accessLevel > accessModifiers.length ? null : accessModifiers[accessLevel - 1]; + @SuppressWarnings("UnnecessaryLocalVariable") @PsiModifier.ModifierConstant + final String modifier = accessLevel > accessModifiers.length ? null : accessModifiers[accessLevel - 1]; + return modifier; } private static final String[] accessModifiers = { @@ -952,4 +954,12 @@ public final class PsiUtil extends PsiUtilCore { public static boolean isIgnoredName(@Nullable final String name) { return "ignore".equals(name) || "ignored".equals(name); } + + public static boolean isExtensionMethod(@Nullable final PsiMethod method) { + if (method == null) return false; + final PsiCodeBlock body = method.getBody(); + if (body == null) return false; + final PsiElement previous = PsiTreeUtil.skipSiblingsBackward(body, PsiComment.class, PsiWhiteSpace.class); + return isJavaToken(previous, JavaTokenType.DEFAULT_KEYWORD); + } } diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/JavadocParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/JavadocParser.java index b72e4a88d0d5..78abd7fd19e5 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/JavadocParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/JavadocParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -147,7 +147,7 @@ public class JavadocParser { final PsiBuilder.Marker tagValue = builder.mark(); builder.remapCurrentToken(JavaDocElementType.DOC_REFERENCE_HOLDER); builder.advanceLexer(); - tagValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN); + tagValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT); } else if (!isInline && tagName != null && tagName.equals(PARAM_TAG)) { parseSimpleTagValue(builder, true); @@ -187,7 +187,7 @@ public class JavadocParser { else { final PsiBuilder.Marker tagValue = builder.mark(); builder.advanceLexer(); - tagValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN); + tagValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT); } } @@ -217,7 +217,7 @@ public class JavadocParser { } } else if (tokenType == JavaDocTokenType.DOC_TAG_VALUE_RPAREN) { - subValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN); + subValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT); builder.advanceLexer(); refStart.done(JavaDocElementType.DOC_METHOD_OR_FIELD_REF); return; @@ -227,7 +227,7 @@ public class JavadocParser { } } - subValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN); + subValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT); } refStart.done(JavaDocElementType.DOC_METHOD_OR_FIELD_REF); @@ -238,7 +238,7 @@ public class JavadocParser { while (TAG_VALUES_SET.contains(getTokenType(builder))) { builder.advanceLexer(); } - tagValue.done(parameter ? JavaDocElementType.DOC_PARAMETER_REF : JavaDocTokenType.DOC_TAG_VALUE_TOKEN); + tagValue.done(parameter ? JavaDocElementType.DOC_PARAMETER_REF : JavaDocElementType.DOC_TAG_VALUE_ELEMENT); } @Nullable diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java index 20c54525a333..76e0672fbb79 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java @@ -264,13 +264,31 @@ public class PsiSuperMethodImplUtil { PsiMethod superMethod = superSignatureHierarchical.getMethod(); PsiClass superClass = superMethod.getContainingClass(); PsiClass containingClass = hierarchicalMethodSignature.getMethod().getContainingClass(); - return !superMethod.isConstructor() - && !aClass.equals(superClass) - && PsiUtil.isAccessible(superMethod, aClass, aClass) - && MethodSignatureUtil.isSubsignature(superSignatureHierarchical, hierarchicalMethodSignature) - && superClass != null - && (containingClass != null && containingClass.isInterface() == superClass.isInterface() || superClass.isInterface() || "java.lang.Object".equals(superClass.getQualifiedName())) - ; + if (!superMethod.isConstructor()) { + if (!aClass.equals(superClass)) { + if (PsiUtil.isAccessible(superMethod, aClass, aClass)) { + if (MethodSignatureUtil.isSubsignature(superSignatureHierarchical, hierarchicalMethodSignature)) { + if (superClass != null) { + if (superClass.isInterface() || + "java.lang.Object".equals(superClass.getQualifiedName())) { + return true; + } + + if (containingClass != null) { + if (!containingClass.isInterface()) { + return true; + } + + if (!aClass.isInterface() && !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true)) { + return true; + } + } + } + } + } + } + } + return false; } private static HierarchicalMethodSignatureImpl copy(HierarchicalMethodSignature hi) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java index 46d734d549bd..342f4bbbdc6c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ package com.intellij.psi.impl.cache; * @author max */ public interface ModifierFlags { -// ---- The group equal to corresponding in ClsUtil.ACC_* int PUBLIC_MASK = 0x0001; int PRIVATE_MASK = 0x0002; int PROTECTED_MASK = 0x0004; @@ -31,9 +30,8 @@ public interface ModifierFlags { int TRANSIENT_MASK = 0x0080; int NATIVE_MASK = 0x0100; int INTERFACE_MASK = 0x0200; + int DEFENDER_MASK = 0x0200; int ABSTRACT_MASK = 0x0400; -// ---- End of the group equal to corresponding in ClsUtil.ACC_* - int STRICTFP_MASK = 0x0800; int PACKAGE_LOCAL_MASK = 0x1000; int DEPRECATED_MASK = 0x2000; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java index 677c9a002a82..b3f90b70dfd6 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,12 +30,8 @@ import com.intellij.psi.tree.IElementType; import com.intellij.util.CharTable; import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; /** * @author max @@ -123,7 +119,7 @@ public class RecordUtil { else if (parent instanceof PsiMethodStub) { if (grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) { alreadyPublic = true; - alreadyAbstract = true; + alreadyAbstract = !((PsiMethodStub)parent).isDefender(); } } else if (parent instanceof PsiFieldStub) { @@ -143,27 +139,37 @@ public class RecordUtil { for (final LighterASTNode child : tree.getChildren(modList)) { final IElementType type = child.getTokenType(); - if(type == JavaTokenType.PUBLIC_KEYWORD) { + if (type == JavaTokenType.PUBLIC_KEYWORD) { alreadyPublic = true; - } else if(type == JavaTokenType.PRIVATE_KEYWORD) { + } + else if (type == JavaTokenType.PRIVATE_KEYWORD) { packed |= ModifierFlags.PRIVATE_MASK; - } else if(type == JavaTokenType.PROTECTED_KEYWORD) { + } + else if (type == JavaTokenType.PROTECTED_KEYWORD) { packed |= ModifierFlags.PROTECTED_MASK; - } else if(type == JavaTokenType.ABSTRACT_KEYWORD) { - alreadyAbstract =true; - } else if (type == JavaTokenType.FINAL_KEYWORD) { + } + else if (type == JavaTokenType.ABSTRACT_KEYWORD) { + alreadyAbstract = true; + } + else if (type == JavaTokenType.FINAL_KEYWORD) { alreadyFinal = true; - } else if (type == JavaTokenType.STATIC_KEYWORD) { + } + else if (type == JavaTokenType.STATIC_KEYWORD) { alreadyStatic = true; - } else if(type == JavaTokenType.NATIVE_KEYWORD) { + } + else if (type == JavaTokenType.NATIVE_KEYWORD) { packed |= ModifierFlags.NATIVE_MASK; - } else if (type == JavaTokenType.SYNCHRONIZED_KEYWORD) { + } + else if (type == JavaTokenType.SYNCHRONIZED_KEYWORD) { packed |= ModifierFlags.SYNCHRONIZED_MASK; - } else if (type == JavaTokenType.TRANSIENT_KEYWORD) { + } + else if (type == JavaTokenType.TRANSIENT_KEYWORD) { packed |= ModifierFlags.TRANSIENT_MASK; - } else if (type == JavaTokenType.VOLATILE_KEYWORD) { + } + else if (type == JavaTokenType.VOLATILE_KEYWORD) { packed |= ModifierFlags.VOLATILE_MASK; - } else if (type == JavaTokenType.STRICTFP_KEYWORD) { + } + else if (type == JavaTokenType.STRICTFP_KEYWORD) { packed |= ModifierFlags.STRICTFP_MASK; } } @@ -175,8 +181,7 @@ public class RecordUtil { if ((packed & ModifierFlags.PRIVATE_MASK) == 0 && (packed & ModifierFlags.PROTECTED_MASK) == 0 && - (packed & ModifierFlags.PUBLIC_MASK) == 0 - ) { + (packed & ModifierFlags.PUBLIC_MASK) == 0) { packed |= ModifierFlags.PACKAGE_LOCAL_MASK; } @@ -217,62 +222,6 @@ public class RecordUtil { return (ourModifierNameToFlagMap.get(psiModifier) & packed) != 0; } - @SuppressWarnings({"unchecked"}) - private static final Set[] SET_INSTANCES = new Set[8 * 4]; - - private static final String[] VISIBILITY_MODIFIERS = {null, PsiModifier.PUBLIC, PsiModifier.PRIVATE, PsiModifier.PROTECTED}; - - private static final int[] MODIFIER_MAP = {0, 1, 2, -1, 3, -1, -1, -1, -1}; - - static { - SET_INSTANCES[0] = Collections.emptySet(); - for (int i = 1; i < 4; i++) { - SET_INSTANCES[i << 3] = Collections.singleton(VISIBILITY_MODIFIERS[i]); - } - - for (int i = 1; i < 8; i++) { - int attr = i << 3; - - Set set = new LinkedHashSet(); - if ((attr & ModifierFlags.STATIC_MASK) != 0) set.add(PsiModifier.STATIC); - if ((attr & ModifierFlags.FINAL_MASK) != 0) set.add(PsiModifier.FINAL); - if ((attr & (4 << 3)) != 0) set.add(PsiModifier.ABSTRACT); - - if (set.size() == 1) set = Collections.singleton(set.iterator().next()); - - SET_INSTANCES[i] = set; - - for (int k = 1; k < 4; k++) { - Set setWithModifier = new LinkedHashSet(); - setWithModifier.add(VISIBILITY_MODIFIERS[k]); - setWithModifier.addAll(set); - assert setWithModifier.size() > 1; - - SET_INSTANCES[(k << 3) + i] = setWithModifier; - } - } - } - - public static Set getModifierSet(int modifiers) { - assert (modifiers & ~(ModifierFlags.PUBLIC_MASK | ModifierFlags.PRIVATE_MASK | ModifierFlags.PROTECTED_MASK | - ModifierFlags.FINAL_MASK | ModifierFlags.ABSTRACT_MASK | ModifierFlags.STATIC_MASK)) == 0; - - int visibilityModifierIndex = MODIFIER_MAP[modifiers & 7]; - int index = ((modifiers >>> 3) & 3) + ((modifiers & ModifierFlags.ABSTRACT_MASK) >>> 8); - if (visibilityModifierIndex != -1) { - return SET_INSTANCES[index + (visibilityModifierIndex << 3)]; - } - - Set res = new LinkedHashSet(); - if ((modifiers & ModifierFlags.PUBLIC_MASK) != 0) res.add(PsiModifier.PUBLIC); - if ((modifiers & ModifierFlags.PRIVATE_MASK) != 0) res.add(PsiModifier.PRIVATE); - if ((modifiers & ModifierFlags.PROTECTED_MASK) != 0) res.add(PsiModifier.PROTECTED); - - res.addAll(SET_INSTANCES[index]); - - return res; - } - public static String intern(final CharTable table, final LighterASTNode node) { assert node instanceof LighterASTTokenNode; return table.intern(((LighterASTTokenNode)node).getText()).toString(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java index 8ba604ac0ba6..1185d9fe9263 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java @@ -58,6 +58,10 @@ public class StubBuildingVisitor extends ClassVisitor { public static final String FLOAT_NEGATIVE_INF = "-1.0f / 0.0"; public static final String FLOAT_NAN = "0.0f / 0.0"; + @NonNls private static final String SYNTHETIC_CLASS_INIT_METHOD = ""; + @NonNls private static final String SYNTHETIC_INIT_METHOD = ""; + + private static final int ACC_DEFENDER = Opcodes.ACC_INTERFACE; // todo[r.sh] use right constant once ASM gets Java 8 support private final InnerClassSourceStrategy myInnersStrategy; private final StubElement myParent; @@ -65,8 +69,6 @@ public class StubBuildingVisitor extends ClassVisitor { private final T mySource; private PsiModifierListStub myModList; private PsiClassStub myResult; - @NonNls private static final String SYNTHETIC_CLINIT_METHOD = ""; - @NonNls private static final String SYNTHETIC_INIT_METHOD = ""; private JavaLexer myLexer; public StubBuildingVisitor(final T classSource, InnerClassSourceStrategy innersStrategy, final StubElement parent, final int access) { @@ -174,20 +176,25 @@ public class StubBuildingVisitor extends ClassVisitor { return convertedSuper; } + // for lexer, so need not to be precise private static LanguageLevel convertFromVersion(final int version) { - if (version == Opcodes.V1_1 || version == Opcodes.V1_2 || version == Opcodes.V1_3) { - return LanguageLevel.JDK_1_3; - } + switch (version) { + case Opcodes.V1_1: + case Opcodes.V1_2: + case Opcodes.V1_3: + return LanguageLevel.JDK_1_3; - if (version == Opcodes.V1_4) { - return LanguageLevel.JDK_1_4; - } + case Opcodes.V1_4: + return LanguageLevel.JDK_1_4; - if (version == Opcodes.V1_5 || version == Opcodes.V1_6) { - return LanguageLevel.JDK_1_5; - } + case Opcodes.V1_5: + case Opcodes.V1_6: + case Opcodes.V1_7: + return LanguageLevel.JDK_1_5; - return LanguageLevel.HIGHEST; + default: + return LanguageLevel.HIGHEST; + } } private static int packCommonFlags(final int access) { @@ -357,16 +364,17 @@ public class StubBuildingVisitor extends ClassVisitor { // However Scala compiler erroneously generates ACC_BRIDGE instead of ACC_SYNTHETIC flag for in-trait implementation delegation. See IDEA-78649 if (isSynthetic) return null; - if (SYNTHETIC_CLINIT_METHOD.equals(name)) return null; + if (SYNTHETIC_CLASS_INIT_METHOD.equals(name)) return null; boolean isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0; boolean isConstructor = SYNTHETIC_INIT_METHOD.equals(name); boolean isVarargs = (access & Opcodes.ACC_VARARGS) != 0; boolean isAnnotationMethod = myResult.isAnnotationType(); + boolean isDefender = (access & ACC_DEFENDER) != 0; if (!isConstructor && !isCorrectName(name)) return null; - final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnnotationMethod, isVarargs, isDeprecated, false); + final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnnotationMethod, isVarargs, isDeprecated, false, isDefender); String canonicalMethodName = isConstructor ? myResult.getName() : name; final List args = new ArrayList(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java index 966832d67bf6..562128f464a8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,7 @@ public abstract class JavaMethodElementType extends JavaStubElementType { boolean isConstructor(); boolean isVarArgs(); boolean isAnnotationMethod(); + boolean isDefender(); @Nullable String getDefaultValueText(); @NotNull TypeInfo getReturnTypeText(boolean doResolve); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java index 81420296c9dd..f076c8a273e0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS private static final int ANNOTATION = 0x04; private static final int DEPRECATED = 0x08; private static final int DEPRECATED_ANNOTATION = 0x10; + private static final int DEFENDER = 0x20; public PsiMethodStubImpl(final StubElement parent, @@ -88,6 +89,11 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS return isAnnotationMethod(myFlags); } + @Override + public boolean isDefender() { + return (myFlags & DEFENDER) != 0; + } + public static boolean isAnnotationMethod(final byte flags) { return (flags & ANNOTATION) != 0; } @@ -145,13 +151,19 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS myDefaultValueText = StringRef.fromString(defaultValueText); } - public static byte packFlags(boolean isConstructor, boolean isAnnotationMethod, boolean isVarargs, boolean isDeprecated, boolean hasDeprecatedAnnotation) { + public static byte packFlags(boolean isConstructor, + boolean isAnnotationMethod, + boolean isVarargs, + boolean isDeprecated, + boolean hasDeprecatedAnnotation, + boolean isDefender) { byte flags = 0; if (isConstructor) flags |= CONSTRUCTOR; if (isAnnotationMethod) flags |= ANNOTATION; if (isVarargs) flags |= VARARGS; if (isDeprecated) flags |= DEPRECATED; if (hasDeprecatedAnnotation) flags |= DEPRECATED_ANNOTATION; + if (isDefender) flags |= DEFENDER; return flags; } @@ -179,6 +191,10 @@ public class PsiMethodStubImpl extends StubBase implements PsiMethodS builder.append(" default=").append(defaultValue); } + if (isDefender()) { + builder.append(" default {}"); + } + builder.append("]"); return builder.toString(); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java index b20b16b5c7d6..97cc4bed2543 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ import java.io.IOException; * @author max */ public class JavaFileElementType extends ILightStubFileElementType { - public static final int STUB_VERSION = 9; + public static final int STUB_VERSION = 10; public JavaFileElementType() { super("java.FILE", JavaLanguage.INSTANCE); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index c4e790fa9485..f69fdf7127ea 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,7 +99,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme i == JavaElementType.THIS_EXPRESSION || i == JavaElementType.SUPER_EXPRESSION || i == JavaDocElementType.DOC_METHOD_OR_FIELD_REF || - i == JavaDocTokenType.DOC_TAG_VALUE_TOKEN || + i == JavaDocElementType.DOC_TAG_VALUE_ELEMENT || i == JavaElementType.REFERENCE_PARAMETER_LIST || i == JavaElementType.ANNOTATION) { if (isQualified()) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java index 17b56ed2c050..f2ecc6853e3b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; @@ -151,7 +152,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement return false; } if (type == JavaTokenType.ABSTRACT_KEYWORD) { - return true; + return !PsiUtil.isExtensionMethod((PsiMethod)parent); } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/CorePsiDocTagValueImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/CorePsiDocTagValueImpl.java index bf790cb612cc..d79afae2c1cc 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/CorePsiDocTagValueImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/CorePsiDocTagValueImpl.java @@ -21,6 +21,7 @@ import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.impl.source.tree.JavaDocElementType; import com.intellij.psi.javadoc.PsiDocTagValue; import org.jetbrains.annotations.NotNull; @@ -29,7 +30,7 @@ import org.jetbrains.annotations.NotNull; */ public class CorePsiDocTagValueImpl extends CompositePsiElement implements PsiDocTagValue { public CorePsiDocTagValueImpl() { - super(JavaDocTokenType.DOC_TAG_VALUE_TOKEN); + super(JavaDocElementType.DOC_TAG_VALUE_ELEMENT); } @Override @@ -47,6 +48,7 @@ public class CorePsiDocTagValueImpl extends CompositePsiElement implements PsiDo if (child.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_COMMA) { return ChildRole.COMMA; } + return super.getChildRole(child); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java index 4fb485baf727..36f7c61047f5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocParamRef.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,7 @@ package com.intellij.psi.impl.source.javadoc; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; -import com.intellij.psi.impl.source.Constants; -import com.intellij.psi.impl.source.tree.CompositePsiElement; -import com.intellij.psi.impl.source.tree.Factory; -import com.intellij.psi.impl.source.tree.LeafElement; -import com.intellij.psi.impl.source.tree.SharedImplUtil; +import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; @@ -43,9 +39,8 @@ import java.util.Set; * @author mike */ public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValue { - public PsiDocParamRef() { - super(Constants.DOC_PARAMETER_REF); + super(JavaDocElementType.DOC_PARAMETER_REF); } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java index ae89a54207ee..9f2b59ec5538 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocTagImpl.java @@ -16,13 +16,9 @@ package com.intellij.psi.impl.source.javadoc; import com.intellij.lang.ASTNode; -import com.intellij.psi.JavaElementVisitor; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementVisitor; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.Constants; -import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.CompositePsiElement; @@ -37,9 +33,10 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Constants { - private static final TokenSet VALUE_BIT_SET = TokenSet.create( - JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF, - DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER); + private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create( + DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF); + private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create( + DOC_TAG_VALUE_TOKEN, JAVA_CODE_REFERENCE, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER)); public PsiDocTagImpl() { super(DOC_TAG); @@ -47,17 +44,17 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con @Override public PsiDocComment getContainingComment() { - return (PsiDocComment)SourceTreeToPsiMap.treeElementToPsi(getTreeParent()); + return (PsiDocComment)getParent(); } @Override public PsiElement getNameElement() { - return findChildByRoleAsPsiElement(ChildRole.DOC_TAG_NAME); + return findPsiChildByType(DOC_TAG_NAME); } @Override public PsiDocTagValue getValueElement() { - return (PsiDocTagValue)findChildByRoleAsPsiElement(ChildRole.DOC_TAG_VALUE); + return (PsiDocTagValue)findPsiChildByType(TAG_VALUE_BIT_SET); } @Override @@ -65,6 +62,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElement.ARRAY_FACTORY); } + @NotNull @Override public String getName() { if (getNameElement() == null) return ""; @@ -79,7 +77,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con @Override public int getChildRole(ASTNode child) { - assert (child.getTreeParent() == this); + assert child.getTreeParent() == this : child.getTreeParent(); IElementType i = child.getElementType(); if (i == DOC_TAG_NAME) { return ChildRole.DOC_TAG_NAME; @@ -90,10 +88,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con else if (i == DOC_COMMENT_LEADING_ASTERISKS) { return ChildRole.DOC_COMMENT_ASTERISKS; } - else if (i == DOC_TAG_VALUE_TOKEN) { - return ChildRole.DOC_TAG_VALUE; - } - else if (i == DOC_METHOD_OR_FIELD_REF || i == DOC_PARAMETER_REF) { + else if (TAG_VALUE_BIT_SET.contains(i)) { return ChildRole.DOC_TAG_VALUE; } else { @@ -104,7 +99,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con @Override @NotNull public PsiReference[] getReferences() { - return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiDocTag.class); + return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS); } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java similarity index 81% rename from java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java rename to java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java index 5e6e534a1f78..38466a5f6cb1 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiInlineDocTagImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.psi.impl.source.tree.java; +package com.intellij.psi.impl.source.javadoc; import com.intellij.lang.ASTNode; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; @@ -36,11 +35,10 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlineDocTag, Constants { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiInlineDocTagImpl"); - - private static final TokenSet VALUE_BIT_SET = TokenSet.create( - JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_METHOD_OR_FIELD_REF, DOC_COMMENT_DATA, DOC_INLINE_TAG, - DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER); + private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create( + DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF); + private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create( + JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER)); public PsiInlineDocTagImpl() { super(DOC_INLINE_TAG); @@ -57,7 +55,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin @Override public PsiElement getNameElement() { - return findChildByRoleAsPsiElement(ChildRole.DOC_TAG_NAME); + return findPsiChildByType(DOC_TAG_NAME); } @Override @@ -67,7 +65,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin @Override public PsiDocTagValue getValueElement() { - return (PsiDocTagValue)findChildByRoleAsPsiElement(ChildRole.DOC_TAG_VALUE); + return (PsiDocTagValue)findPsiChildByType(TAG_VALUE_BIT_SET); } @Override @@ -79,7 +77,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin @Override public int getChildRole(ASTNode child) { - LOG.assertTrue(child.getTreeParent() == this); + assert child.getTreeParent() == this : child.getTreeParent(); IElementType i = child.getElementType(); if (i == DOC_TAG_NAME) { return ChildRole.DOC_TAG_NAME; @@ -93,10 +91,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin else if (i == DOC_INLINE_TAG_END) { return ChildRole.DOC_INLINE_TAG_END; } - else if (i == DOC_TAG_VALUE_TOKEN) { - return ChildRole.DOC_TAG_VALUE; - } - else if (i == DOC_METHOD_OR_FIELD_REF) { + else if (TAG_VALUE_BIT_SET.contains(i)) { return ChildRole.DOC_TAG_VALUE; } else { @@ -124,4 +119,4 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin PsiImplUtil.setName(getNameElement(), name); return this; } -} \ No newline at end of file +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/CoreJavaASTFactory.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/CoreJavaASTFactory.java index c9b6e5552676..dc7b6e576871 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/CoreJavaASTFactory.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/CoreJavaASTFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,7 @@ public class CoreJavaASTFactory extends ASTFactory implements Constants { return new PsiJavaTokenImpl(type, text); } else if (type instanceof IJavaDocElementType) { + assert type != DOC_TAG_VALUE_ELEMENT; return new PsiDocTokenImpl(type, text); } @@ -57,7 +58,7 @@ public class CoreJavaASTFactory extends ASTFactory implements Constants { @Override public CompositeElement createComposite(IElementType type) { - if (type == DOC_TAG_VALUE_TOKEN) { + if (type == DOC_TAG_VALUE_ELEMENT) { return new CorePsiDocTagValueImpl(); } return null; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaDocElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaDocElementType.java index 4c4776cb1653..71df6027483e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaDocElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaDocElementType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ import com.intellij.psi.impl.source.javadoc.PsiDocCommentImpl; import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef; import com.intellij.psi.impl.source.javadoc.PsiDocParamRef; import com.intellij.psi.impl.source.javadoc.PsiDocTagImpl; -import com.intellij.psi.impl.source.tree.java.PsiInlineDocTagImpl; +import com.intellij.psi.impl.source.javadoc.PsiInlineDocTagImpl; import com.intellij.psi.tree.*; import com.intellij.psi.tree.java.IJavaDocElementType; import com.intellij.util.ReflectionUtil; @@ -70,6 +70,7 @@ public interface JavaDocElementType { IElementType DOC_INLINE_TAG = new JavaDocCompositeElementType("DOC_INLINE_TAG", PsiInlineDocTagImpl.class); IElementType DOC_METHOD_OR_FIELD_REF = new JavaDocCompositeElementType("DOC_METHOD_OR_FIELD_REF", PsiDocMethodOrFieldRef.class); IElementType DOC_PARAMETER_REF = new JavaDocCompositeElementType("DOC_PARAMETER_REF", PsiDocParamRef.class); + IElementType DOC_TAG_VALUE_ELEMENT = new IJavaDocElementType("DOC_TAG_VALUE_ELEMENT"); ILazyParseableElementType DOC_REFERENCE_HOLDER = new JavaDocLazyElementType("DOC_REFERENCE_HOLDER") { private final JavaParserUtil.ParserWrapper myParser = new JavaParserUtil.ParserWrapper() { @@ -135,6 +136,6 @@ public interface JavaDocElementType { }; TokenSet ALL_JAVADOC_ELEMENTS = TokenSet.create( - DOC_TAG, DOC_INLINE_TAG, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF, DOC_REFERENCE_HOLDER, DOC_TYPE_HOLDER, DOC_COMMENT - ); + DOC_TAG, DOC_INLINE_TAG, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF, DOC_TAG_VALUE_ELEMENT, + DOC_REFERENCE_HOLDER, DOC_TYPE_HOLDER, DOC_COMMENT); } diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index cbbf40de4ceb..3aae6ea3712b 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -349,6 +349,7 @@ feature.static.imports=Static imports feature.for.each=For-each loops feature.varargs=Variable arity methods feature.diamond.types=Diamond types -feature.try.with.resources=Try-with-resources feature.multi.catch=Multi-catches +feature.try.with.resources=Try-with-resources +feature.extension.methods=Extension methods insufficient.language.level={0} are not supported at this language level diff --git a/java/java-tests/testData/codeInsight/completion/normal/OverwriteGenericsAfterNew.java b/java/java-tests/testData/codeInsight/completion/normal/OverwriteGenericsAfterNew.java new file mode 100644 index 000000000000..e37957a17320 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/OverwriteGenericsAfterNew.java @@ -0,0 +1,6 @@ +class Bar { + { + Koo hs = new Ko(); + } +} +class Koo {} diff --git a/java/java-tests/testData/codeInsight/completion/normal/OverwriteGenericsAfterNew_after.java b/java/java-tests/testData/codeInsight/completion/normal/OverwriteGenericsAfterNew_after.java new file mode 100644 index 000000000000..9cd9c1b90b94 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/OverwriteGenericsAfterNew_after.java @@ -0,0 +1,6 @@ +class Bar { + { + Koo hs = new Koo(); + } +} +class Koo {} diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferReturnBeforeStatement.java b/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferReturnBeforeStatement.java new file mode 100644 index 000000000000..181d4481c5cc --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferReturnBeforeStatement.java @@ -0,0 +1,7 @@ +class Util { + void foo(int reaction, boolean rezet) { + re + System.out.println(); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/PreferBetterMatchingConstantToMethods.java b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferBetterMatchingConstantToMethods.java new file mode 100644 index 000000000000..456e747a3d5d --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferBetterMatchingConstantToMethods.java @@ -0,0 +1,10 @@ +class Foo { + String s = Util.se +} + +class Util { + public static final String serial = "serialVersionUID"; + + public static Runnable superExpressionInIllegalContext() {} + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/MethodCalls.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/MethodCalls.java index 74175a7a882c..183e8d01211d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/MethodCalls.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/MethodCalls.java @@ -1,3 +1,19 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + // illegal method calls class A { @@ -48,14 +64,12 @@ class CX { class c { - c() { + c() {} - } class inner { class ininner {} } - static void f() { new inner(); } @@ -88,21 +102,20 @@ class DCC { } public DCC(int i, int z) { - DCC(i); + DCC(i); } void f() { DCC(1); new DCC(1); } - { - java.toString(); - } - + { + java.toString(); + } } class ThisExpression { static String foo() { System.out.println(this); - return this.toString(); + return super.toString(); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/QualifiedNew.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/QualifiedNew.java index 28ed2c23d5e9..b832b91dd747 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/QualifiedNew.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/QualifiedNew.java @@ -17,3 +17,16 @@ class b extends A { static class c {} } + +class WithAnonym { + interface I { + } + class Inner{} +} + +class WithAnonymInheritor extends WithAnonym { + { + this.new I() {}; + this.new Inner() {}; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/UnsupportedFeatures.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/UnsupportedFeatures.java index 9701b4b373b2..0aa0409aa34d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/UnsupportedFeatures.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/UnsupportedFeatures.java @@ -38,4 +38,8 @@ class UnsupportedFeatures { try (Reader r = new FileReader("/dev/null")) { } } + + interface I { + void m() default { } + } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java new file mode 100644 index 000000000000..909d08a364b9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/ExtensionMethods.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class C { + interface I { + void m() default { } + } + + void test() { + new I(){}.m(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterInterfaceAndAbstractClass.java b/java/java-tests/testData/codeInsight/overrideImplement/afterInterfaceAndAbstractClass.java new file mode 100644 index 000000000000..b90134bce991 --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/afterInterfaceAndAbstractClass.java @@ -0,0 +1,16 @@ +abstract class A { + public abstract D foo(); +} + +interface B { + F foo(); +} + +class C extends A implements B { + public F foo() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } +} + +class D {} +class F extends D {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterTypeParam.java b/java/java-tests/testData/codeInsight/overrideImplement/afterTypeParam.java new file mode 100644 index 000000000000..bcc6df490039 --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/afterTypeParam.java @@ -0,0 +1,9 @@ +interface Function { + void fun(Function function); +} + +class Bar extends Function{ + public void fun(Function function) { + //To change body of implemented methods use File | Settings | File Templates. + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeInterfaceAndAbstractClass.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeInterfaceAndAbstractClass.java new file mode 100644 index 000000000000..74b4f0a7bced --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeInterfaceAndAbstractClass.java @@ -0,0 +1,14 @@ +abstract class A { + public abstract D foo(); +} + +interface B { + F foo(); +} + +class C extends A implements B { + +} + +class D {} +class F extends D {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeTypeParam.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeTypeParam.java new file mode 100644 index 000000000000..02f91f6855b8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeTypeParam.java @@ -0,0 +1,7 @@ +interface Function { + void fun(Function function); +} + +class Bar extends Function{ + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/StringTernaryAlwaysTrue.java b/java/java-tests/testData/inspection/dataFlow/fixture/StringTernaryAlwaysTrue.java new file mode 100644 index 000000000000..93255d9a79b8 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/StringTernaryAlwaysTrue.java @@ -0,0 +1,12 @@ +class Foo { + public void foo() { + final boolean flag = true; + + bar(flag ? "a" : "b", + flag ? new String[]{"aa"} : new String[]{"bb"} + ); + } + + void bar(String b, String[] a) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/Exception0.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/Exception0.txt index 9254cba2a145..b3935666fc28 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/Exception0.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/Exception0.txt @@ -25,7 +25,7 @@ PsiJavaFile:Exception0.java PsiDocTag:@throws PsiDocToken:DOC_TAG_NAME('@throws') PsiWhiteSpace(' ') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_REFERENCE_HOLDER) PsiJavaCodeReferenceElement:java.lang.Exception PsiJavaCodeReferenceElement:java.lang diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag1.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag1.txt index 983c2c305f61..1975d6a75cf5 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag1.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag1.txt @@ -15,7 +15,7 @@ PsiJavaFile:InlineTag1.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('somefunc') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:String PsiJavaCodeReferenceElement:String diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag2.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag2.txt index 9bba0d6bc228..9165b8960367 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag2.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag2.txt @@ -15,7 +15,7 @@ PsiJavaFile:InlineTag2.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('somefunc') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:String PsiJavaCodeReferenceElement:String diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag3.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag3.txt index e74ee40b22bd..fb591f4269c2 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag3.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/InlineTag3.txt @@ -15,7 +15,7 @@ PsiJavaFile:InlineTag3.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('somefunc') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:String PsiJavaCodeReferenceElement:String diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag1.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag1.txt index b1bae863f3b4..d7f6a22bf259 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag1.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag1.txt @@ -30,7 +30,7 @@ PsiJavaFile:LinkPlainTag1.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('equals') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:java.lang.Object PsiJavaCodeReferenceElement:java.lang.Object diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag2.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag2.txt index ba779cc5e45a..79e2ec31d002 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag2.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkPlainTag2.txt @@ -10,7 +10,7 @@ PsiJavaFile:LinkPlainTag2.java PsiDocTag:@linkplain PsiDocToken:DOC_TAG_NAME('@linkplain') PsiWhiteSpace(' ') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_TOKEN('java.lang.String') PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('equals') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag1.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag1.txt index 588adbae3d2e..f5fde4f3d333 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag1.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag1.txt @@ -30,7 +30,7 @@ PsiJavaFile:LinkTag1.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('equals') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:java.lang.Object PsiJavaCodeReferenceElement:java.lang.Object diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag2.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag2.txt index 5bb0d66a89f3..af4cf7d2b185 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag2.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag2.txt @@ -10,7 +10,7 @@ PsiJavaFile:LinkTag2.java PsiDocTag:@link PsiDocToken:DOC_TAG_NAME('@link') PsiWhiteSpace(' ') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_TOKEN('java.lang.String') PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('equals') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag3.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag3.txt index 8a8940b8e0b3..b1ea51c9d1af 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag3.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag3.txt @@ -17,7 +17,7 @@ PsiJavaFile:LinkTag3.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('foo') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_RPAREN(')') PsiDocToken:DOC_INLINE_TAG_END('}') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag4.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag4.txt index 93a0946316fc..a08d012cd2f2 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag4.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag4.txt @@ -16,7 +16,7 @@ PsiJavaFile:LinkTag4.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('foo') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_RPAREN(')') PsiDocToken:DOC_INLINE_TAG_END('}') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag5.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag5.txt index 6fe4b9bb0d46..6aeebb155f30 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag5.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag5.txt @@ -15,7 +15,7 @@ PsiJavaFile:LinkTag5.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('foo') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_RPAREN(')') PsiDocToken:DOC_INLINE_TAG_END('}') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag6.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag6.txt index 24d4ab93bb89..1cc176462b4e 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag6.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/LinkTag6.txt @@ -15,7 +15,7 @@ PsiJavaFile:LinkTag6.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('foo') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_RPAREN(')') PsiDocToken:DOC_INLINE_TAG_END('}') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag10.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag10.txt index 94bc09223507..95b2f7f607a3 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag10.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag10.txt @@ -29,7 +29,7 @@ PsiJavaFile:SeeTag10.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('equals') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:java.lang.Object PsiJavaCodeReferenceElement:java.lang.Object diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag11.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag11.txt index fec603ea5b39..f58d76b72fd8 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag11.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag11.txt @@ -29,7 +29,7 @@ PsiJavaFile:SeeTag11.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('wait') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_RPAREN(')') PsiWhiteSpace('\n ') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag12.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag12.txt index 6ef08071804c..ac4dd62c07d2 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag12.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag12.txt @@ -14,7 +14,7 @@ PsiJavaFile:SeeTag12.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('wait') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_RPAREN(')') PsiWhiteSpace('\n ') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag14.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag14.txt index 9d930ec9c238..08f90474c3a7 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag14.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag14.txt @@ -29,7 +29,7 @@ PsiJavaFile:SeeTag14.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('append') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:char[] PsiTypeElement:char diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag15.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag15.txt index a535a82cc44f..fa79b853c1a4 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag15.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag15.txt @@ -29,7 +29,7 @@ PsiJavaFile:SeeTag15.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('append') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:java.lang.Object PsiJavaCodeReferenceElement:java.lang.Object diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag16.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag16.txt index d7f1d3d5157a..3d1fa26a8169 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag16.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag16.txt @@ -19,7 +19,7 @@ PsiJavaFile:SeeTag16.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('equals') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:int PsiKeyword:int('int') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag3.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag3.txt index a2a28c9a945a..f018c5af50c1 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag3.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag3.txt @@ -19,7 +19,7 @@ PsiJavaFile:SeeTag3.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('equals') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:Object PsiJavaCodeReferenceElement:Object diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag5.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag5.txt index 977e65124359..9903e7c37d6b 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag5.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag5.txt @@ -29,7 +29,7 @@ PsiJavaFile:SeeTag5.java PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#') PsiDocToken:DOC_TAG_VALUE_TOKEN('wait') PsiDocToken:DOC_TAG_VALUE_LPAREN('(') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiElement(DOC_TYPE_HOLDER) PsiTypeElement:long PsiKeyword:long('long') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag9.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag9.txt index 75968a87205e..7b2b10a6a7ce 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag9.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/SeeTag9.txt @@ -15,16 +15,16 @@ PsiJavaFile:SeeTag9.java PsiIdentifier:equals('equals') PsiReferenceParameterList - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_LPAREN('(') PsiElement(DOC_REFERENCE_HOLDER) PsiKeyword:long('long') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_COMMA(',') PsiWhiteSpace(' ') PsiElement(DOC_REFERENCE_HOLDER) PsiKeyword:long('long') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_RPAREN(')') PsiWhiteSpace('\n ') PsiDocToken:DOC_COMMENT_END('*/') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/Tag2.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/Tag2.txt index 45c260fa5f51..83308bc7bd6b 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/Tag2.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/Tag2.txt @@ -23,7 +23,7 @@ PsiJavaFile:Tag2.java PsiDocTag:@return PsiDocToken:DOC_TAG_NAME('@return') PsiWhiteSpace(' ') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_TOKEN('value') PsiWhiteSpace(' ') PsiDocToken:DOC_COMMENT_DATA('value') diff --git a/java/java-tests/testData/psi/parser-full/javadocParsing/Tag5.txt b/java/java-tests/testData/psi/parser-full/javadocParsing/Tag5.txt index eb44d58a94e9..c6a9b80b47b6 100644 --- a/java/java-tests/testData/psi/parser-full/javadocParsing/Tag5.txt +++ b/java/java-tests/testData/psi/parser-full/javadocParsing/Tag5.txt @@ -10,7 +10,7 @@ PsiJavaFile:Tag5.java PsiDocTag:@ejb:bean PsiDocToken:DOC_TAG_NAME('@ejb:bean') PsiWhiteSpace(' ') - PsiElement(DOC_TAG_VALUE_TOKEN) + PsiElement(DOC_TAG_VALUE_ELEMENT) PsiDocToken:DOC_TAG_VALUE_TOKEN('this') PsiWhiteSpace(' ') PsiDocToken:DOC_COMMENT_DATA('is an EJB ') diff --git a/java/java-tests/testData/psi/parser-partial/declarations/Extension.txt b/java/java-tests/testData/psi/parser-partial/declarations/Extension.txt index fe4e23c8ec36..8e876a4d19a3 100644 --- a/java/java-tests/testData/psi/parser-partial/declarations/Extension.txt +++ b/java/java-tests/testData/psi/parser-partial/declarations/Extension.txt @@ -13,8 +13,14 @@ PsiJavaFile:Extension.java PsiParameterList:() PsiJavaToken:LPARENTH('(') PsiJavaToken:RPARENTH(')') + PsiWhiteSpace(' ') PsiReferenceList - + PsiKeyword:throws('throws') + PsiWhiteSpace(' ') + PsiJavaCodeReferenceElement:E + PsiIdentifier:E('E') + PsiReferenceParameterList + PsiWhiteSpace(' ') PsiKeyword:default('default') PsiWhiteSpace(' ') diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java index 6b0408dbbee7..3d0a160e8094 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java @@ -35,6 +35,8 @@ public class OverrideImplementTest extends LightCodeInsightTestCase { public void testSubstitutionInTypeParametersList() throws Exception { doTest(false); } public void testTestMissed() throws Exception { doTest(false); } public void testWildcard() throws Exception { doTest(false); } + public void testTypeParam() throws Exception { doTest(false); } + public void testInterfaceAndAbstractClass() throws Exception { doTest(false); } public void testLongFinalParameterList() throws Exception { CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(getProject()).clone(); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy index a3c6273a587a..df62e225be87 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy @@ -8,11 +8,11 @@ package com.intellij.codeInsight.completion; import com.intellij.JavaTestUtil import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.codeInsight.lookup.LookupElementPresentation import com.intellij.codeInsight.lookup.impl.LookupImpl import com.intellij.ide.ui.UISettings import com.intellij.psi.PsiClass import com.intellij.psi.PsiMethod -import com.intellij.codeInsight.lookup.LookupElementPresentation public class NormalCompletionOrderingTest extends CompletionSortingTestCase { private static final String BASE_PATH = "/codeInsight/completion/normalSorting"; @@ -87,7 +87,7 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { final String path = getTestName(false) + ".java"; myFixture.configureByFile(path); myFixture.complete(CompletionType.BASIC, 2); - assertPreferredItems(0, "booleanMethod", "voidMethod", "registerNatives", "BOOLEAN", "AN_OBJECT"); + assertPreferredItems(0, "BOOLEAN", "booleanMethod", "AN_OBJECT", "voidMethod", "registerNatives"); } public void testDispreferDeclared() throws Throwable { @@ -314,4 +314,20 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { checkPreferredItems 0, 'noo', 'new', 'null', 'noo2', 'notify', 'notifyAll' } + public void testPreferBetterMatchingConstantToMethods() { + checkPreferredItems 0, 'serial', 'superExpressionInIllegalContext' + } + + public void testJComponentAddNewWithStats() throws Throwable { + final LookupImpl lookup = invokeCompletion("/../smartTypeSorting/JComponentAddNew.java"); + assertPreferredItems(0, "FooBean3", "JComponent", "Component"); + incUseCount(lookup, 2); //Component + assertPreferredItems(0, "Component", "FooBean3", "JComponent"); + } + + public void testDispreferReturnBeforeStatement() { + checkPreferredItems 0, 'reaction', 'rezet', 'return' + } + + } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index 90bf9bb2877a..bde8a4883d74 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -1339,6 +1339,7 @@ public class ListUtils { public void testInterfaceImplementationNoCast() { doTest() } public void testStaticallyImportedMethodsBeforeExpression() { doTest() } public void testInnerChainedReturnType() { doTest() } + public void testOverwriteGenericsAfterNew() { doTest('\n') } private CommonCodeStyleSettings getCodeStyleSettings() { return CodeStyleSettingsManager.getSettings(getProject()).getCommonSettings(JavaLanguage.INSTANCE); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java index 8165329c5130..acb08fd82d81 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java @@ -57,126 +57,36 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { }; } - public void testAllJava15Features() throws Exception { - doTest(false, false); - } - - public void testEnumSyntheticMethods() throws Exception { - doTest(false, false); - } - - public void testDuplicateAnnotations() throws Exception { - doTest(false, false); - } - - public void testSwitchByString() throws Exception { - doTest(false, false); - } - - public void testSwitchByInaccessibleEnum() throws Exception { - doTest(false, false); - } - - public void testDiamondPos1() throws Exception { - doTest(false, false); - } - - public void testDiamondPos2() throws Exception { - doTest(false, false); - } - - public void testDiamondPos3() throws Exception { - doTest(false, false); - } - - public void testDiamondPos4() throws Exception { - doTest(false, false); - } - - public void testDiamondPos5() throws Exception { - doTest(false, false); - } - - - public void testDiamondPos6() throws Exception { - doTest(false, false); - } - - public void testDiamondPos7() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg15() throws Exception { - doTest(false, false); - } - - public void testDiamondPos9() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg1() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg2() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg3() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg4() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg5() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg6() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg7() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg8() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg9() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg10() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg11() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg12() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg13() throws Exception { - doTest(false, false); - } - - public void testDiamondNeg14() throws Exception { - doTest(false, false); - } - - public void testDiamondMisc() throws Exception { - doTest(false, false); - } - - public void testHighlightInaccessibleFromClassModifierList() throws Exception { - doTest(false, false); - } + public void testAllJava15Features() throws Exception { doTest(false, false); } + public void testEnumSyntheticMethods() throws Exception { doTest(false, false); } + public void testDuplicateAnnotations() throws Exception { doTest(false, false); } + public void testSwitchByString() throws Exception { doTest(false, false); } + public void testSwitchByInaccessibleEnum() throws Exception { doTest(false, false); } + public void testDiamondPos1() throws Exception { doTest(false, false); } + public void testDiamondPos2() throws Exception { doTest(false, false); } + public void testDiamondPos3() throws Exception { doTest(false, false); } + public void testDiamondPos4() throws Exception { doTest(false, false); } + public void testDiamondPos5() throws Exception { doTest(false, false); } + public void testDiamondPos6() throws Exception { doTest(false, false); } + public void testDiamondPos7() throws Exception { doTest(false, false); } + public void testDiamondNeg15() throws Exception { doTest(false, false); } + public void testDiamondPos9() throws Exception { doTest(false, false); } + public void testDiamondNeg1() throws Exception { doTest(false, false); } + public void testDiamondNeg2() throws Exception { doTest(false, false); } + public void testDiamondNeg3() throws Exception { doTest(false, false); } + public void testDiamondNeg4() throws Exception { doTest(false, false); } + public void testDiamondNeg5() throws Exception { doTest(false, false); } + public void testDiamondNeg6() throws Exception { doTest(false, false); } + public void testDiamondNeg7() throws Exception { doTest(false, false); } + public void testDiamondNeg8() throws Exception { doTest(false, false); } + public void testDiamondNeg9() throws Exception { doTest(false, false); } + public void testDiamondNeg10() throws Exception { doTest(false, false); } + public void testDiamondNeg11() throws Exception { doTest(false, false); } + public void testDiamondNeg12() throws Exception { doTest(false, false); } + public void testDiamondNeg13() throws Exception { doTest(false, false); } + public void testDiamondNeg14() throws Exception { doTest(false, false); } + public void testDiamondMisc() throws Exception { doTest(false, false); } + public void testHighlightInaccessibleFromClassModifierList() throws Exception { doTest(false, false); } public void testDynamicallyAddIgnoredAnnotations() throws Exception { ExtensionPoint point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL); @@ -242,46 +152,21 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { } } - public void testNumericLiterals() throws Exception { - doTest(false, false); - } - - public void testMultiCatch() throws Exception { - doTest(false, false); - } - - public void testTryWithResources() throws Exception { - doTest(false, false); - } + public void testNumericLiterals() throws Exception { doTest(false, false); } + public void testMultiCatch() throws Exception { doTest(false, false); } + public void testTryWithResources() throws Exception { doTest(false, false); } public void testTryWithResourcesWarn() throws Exception { enableInspectionTool(new DefUseInspection()); doTest(true, false); } - public void testSafeVarargsApplicability() throws Exception { - doTest(true, false); - } - - public void testUncheckedGenericsArrayCreation() throws Exception { - doTest(true, false); - } - - public void testPreciseRethrow() throws Exception { - doTest(false, false); - } - - public void testImprovedCatchAnalysis() throws Exception { - doTest(true, false); - } - - public void testJavacQuirks() throws Exception { - doTest(true, false); - } - - public void testPolymorphicTypeCast() throws Exception { - doTest(true, false); - } + public void testSafeVarargsApplicability() throws Exception { doTest(true, false); } + public void testUncheckedGenericsArrayCreation() throws Exception { doTest(true, false); } + public void testPreciseRethrow() throws Exception { doTest(false, false); } + public void testImprovedCatchAnalysis() throws Exception { doTest(true, false); } + public void testJavacQuirks() throws Exception { doTest(true, false); } + public void testPolymorphicTypeCast() throws Exception { doTest(true, false); } public void testErasureClashConfusion() throws Exception { enableInspectionTool(new UnusedDeclarationInspection()); @@ -293,16 +178,9 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { doTest(true, false); } - public void testSuperBound() throws Exception { - doTest(false, false); - } - - public void testExtendsBound() throws Exception { - doTest(false, false); - } - + public void testSuperBound() throws Exception { doTest(false, false); } + public void testExtendsBound() throws Exception { doTest(false, false); } public void testIDEA84533() throws Exception { doTest(false, false); } - - public void testClassLiteral() throws Exception { doTest(false, false);} + public void testClassLiteral() throws Exception { doTest(false, false); } + public void testExtensionMethods() throws Exception { doTest(false, false); } } - diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index fe161e00f75c..20830a89f107 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -174,6 +174,7 @@ class Test { class Test { void test() { new Runnable() { + static final long serialVersionUID = 42L; public void run() { System.out.println(); } @@ -195,6 +196,23 @@ class Test { assert closureStartFold } + public void "test no closure folding when the method throws an unresolved exception"() { + def text = """\ +class Test { + void test() { new Runnable() { + public void run() throws Asadfsdafdfasd { + System.out.println(); + } + }; + } +} +""" + + configure text + def foldingModel = myFixture.editor.foldingModel as FoldingModelImpl + assert !foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable")) + } + public void testFindInFolding() { def text = """\ class Test { diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java index b8c5012f562e..768679bdb501 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java @@ -62,5 +62,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas public void testIDEA84489() throws Throwable { doTest(); } public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); } + public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); } } diff --git a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java index a1b6b4290124..f9c7f5db6571 100644 --- a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java +++ b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/DeclarationParserTest.java @@ -81,7 +81,7 @@ public class DeclarationParserTest extends JavaParsingTestCase { public void testMethodNormal1() { doParserTest("{ void f(); }", false, false); } public void testSemicolons() { doParserTest("{ void f() {}; void g() {}; }", false, false); } public void testUnclosed0() { doParserTest("{ void f() }", false, false); } - public void testExtension() { doParserTest("{ int f() default { return 42; } }", false, false); } + public void testExtension() { doParserTest("{ int f() throws E default { return 42; } }", false, false); } public void testUnclosed1() { doParserTest("{ void f( }", false, false); } public void testUnclosed2() { doParserTest("{ void f()\n void g(); }", false, false); } public void testUnclosed3() { doParserTest("{ void f(int a }", false, false); } diff --git a/java/java-tests/testSrc/com/intellij/project/convertors/Convertor34Test.java b/java/java-tests/testSrc/com/intellij/project/convertors/Convertor34Test.java index 4c2ae160d381..92170d1c6635 100644 --- a/java/java-tests/testSrc/com/intellij/project/convertors/Convertor34Test.java +++ b/java/java-tests/testSrc/com/intellij/project/convertors/Convertor34Test.java @@ -1,27 +1,46 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.project.convertors; import com.intellij.application.options.PathMacrosImpl; +import com.intellij.ide.highlighter.ModuleFileType; +import com.intellij.ide.highlighter.ProjectFileType; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ExpandMacroToPathMap; import com.intellij.openapi.project.impl.convertors.Convertor34; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.refactoring.MultiFileTestCase; -import com.intellij.ide.highlighter.ProjectFileType; -import com.intellij.ide.highlighter.ModuleFileType; import org.jdom.Document; import org.jdom.Element; +import org.jdom.JDOMException; +import java.io.IOException; import java.util.List; /** * @author dsl */ public class Convertor34Test extends MultiFileTestCase { - public Convertor34Test() { + @Override + public void setUp() throws Exception { myDoCompare = false; + super.setUp(); } @Override @@ -44,17 +63,18 @@ public class Convertor34Test extends MultiFileTestCase { public void testScr25298() throws Exception { doTest(createPerformActionForLibraryTable());} - private PerformAction createPerformAction(final String projectName) { + private static PerformAction createPerformAction(final String projectName) { return new PerformAction() { @Override public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception { final VirtualFile projectFile = rootDir.findChild(projectName + ProjectFileType.DOT_DEFAULT_EXTENSION); + assertNotNull(rootDir.getPath(), projectFile); + final ExpandMacroToPathMap macros = new ExpandMacroToPathMap(); macros.addMacroExpand(PathMacrosImpl.PROJECT_DIR_MACRO_NAME, rootDir.getPath()); macros.addMacroExpand(PathMacrosImpl.MODULE_DIR_MACRO_NAME, rootDir.getPath()); - final Document projectDocument = JDOMUtil.loadDocument( - VfsUtil.loadText(projectFile)); + final Document projectDocument = JDOMUtil.loadDocument(VfsUtilCore.loadText(projectFile)); macros.substitute(projectDocument.getRootElement(), true); Convertor34.execute(projectDocument.getRootElement(), projectFile.getPath(), null); @@ -65,18 +85,11 @@ public class Convertor34Test extends MultiFileTestCase { LocalFileSystem.getInstance().refresh(false); } }); - final VirtualFile moduleFile = rootDir.findChild(projectName + ModuleFileType.DOT_DEFAULT_EXTENSION); - assertNotNull(moduleFile); - final Document moduleDocument = JDOMUtil.loadDocument( - VfsUtil.loadText(moduleFile)); + final Document moduleDocument = loadDocument(rootDir, projectName + ModuleFileType.DOT_DEFAULT_EXTENSION); macros.substitute(moduleDocument.getRootElement(), true); - final Document goldenProjectDocument = JDOMUtil.loadDocument( - VfsUtil.loadText(rootAfter.findChild(projectName + ProjectFileType.DOT_DEFAULT_EXTENSION)) - ); + final Document goldenProjectDocument = loadDocument(rootAfter, projectName + ProjectFileType.DOT_DEFAULT_EXTENSION); macros.substitute(goldenProjectDocument.getRootElement(), true); - final Document goldenModuleDocument = JDOMUtil.loadDocument( - VfsUtil.loadText(rootAfter.findChild(projectName + ModuleFileType.DOT_DEFAULT_EXTENSION)) - ); + final Document goldenModuleDocument = loadDocument(rootAfter, projectName + ModuleFileType.DOT_DEFAULT_EXTENSION); macros.substitute(goldenModuleDocument.getRootElement(), true); assertConfigsEqual("ProjectModuleManager", goldenProjectDocument, projectDocument); @@ -85,16 +98,17 @@ public class Convertor34Test extends MultiFileTestCase { }; } - private PerformAction createPerformActionForLibraryTable() { + private static PerformAction createPerformActionForLibraryTable() { return new PerformAction() { @Override public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception { final VirtualFile libFile = rootDir.findChild("library.table.xml"); + assertNotNull(rootDir.getPath(), libFile); + final ExpandMacroToPathMap macros = new ExpandMacroToPathMap(); macros.addMacroExpand("DIR", rootDir.getPath()); - final Document oldTable = JDOMUtil.loadDocument( - VfsUtil.loadText(libFile)); + final Document oldTable = JDOMUtil.loadDocument(VfsUtilCore.loadText(libFile)); macros.substitute(oldTable.getRootElement(), true); Convertor34.convertLibraryTable34(oldTable.getRootElement(), libFile.getPath()); ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -103,25 +117,27 @@ public class Convertor34Test extends MultiFileTestCase { LocalFileSystem.getInstance().refresh(false); } }); - final VirtualFile applicationLibraries = rootDir.findChild("applicationLibraries.xml"); - assertNotNull(applicationLibraries); - final Document newTable = JDOMUtil.loadDocument( - VfsUtil.loadText(applicationLibraries)); - final Document goldenNewTable = JDOMUtil.loadDocument( - VfsUtil.loadText(rootAfter.findChild("applicationLibraries.xml"))); + final Document newTable = loadDocument(rootDir, "applicationLibraries.xml"); + final Document goldenNewTable = loadDocument(rootAfter, "applicationLibraries.xml"); macros.substitute(goldenNewTable.getRootElement(), true); assertElementsEqual(goldenNewTable.getRootElement(), newTable.getRootElement()); } }; } - private void assertConfigsEqual(String componentName, Document goldenDocument, Document document) { + private static Document loadDocument(VirtualFile parent, String name) throws IOException, JDOMException { + final VirtualFile child = parent.findChild(name); + assertNotNull(parent + "/" + name, child); + return JDOMUtil.loadDocument(VfsUtilCore.loadText(child)); + } + + private static void assertConfigsEqual(String componentName, Document goldenDocument, Document document) { final Element goldenElement = getComponentElement(goldenDocument, componentName); final Element element = getComponentElement(document, componentName); assertElementsEqual(goldenElement, element); } - private void assertElementsEqual(final Element goldenElement, final Element element) { + private static void assertElementsEqual(final Element goldenElement, final Element element) { assertEquals(JDOMUtil.createOutputter("\n").outputString(goldenElement), JDOMUtil.createOutputter("\n").outputString(element)); } diff --git a/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java b/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java index 58528d12e401..9bd2f1abd2d4 100644 --- a/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,6 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.security.SecureRandom; - public class JavaStubBuilderTest extends LightIdeaTestCase { private static final StubBuilder NEW_BUILDER = new JavaLightStubBuilder(); @@ -40,7 +39,7 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { public void setUp() throws Exception { super.setUp(); doTest("@interface A { int i() default 42; }\n class C { void m(int p) throws E { } }", null); // warm up - LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7); + LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST); } public void testEmpty() { @@ -112,6 +111,10 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { " public C() throws Exception { }\n" + " public abstract void m(final int i, int[] a1, int a2[], int[] a3[]);\n" + " private static int v2a(int... v) [] { return v; }\n" + + "}\n" + + "interface I {\n" + + " void m1();\n" + + " void m2() default { }\n" + "}", "PsiJavaFileStub []\n" + @@ -160,6 +163,21 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { " PARAMETER_LIST:PsiParameterListStub\n" + " PARAMETER:PsiParameterStub[v:int...]\n" + " MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" + + " THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" + + " CLASS:PsiClassStub[interface name=I fqn=I]\n" + + " MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" + + " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + + " EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" + + " IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" + + " METHOD:PsiMethodStub[m1:void]\n" + + " MODIFIER_LIST:PsiModifierListStub[mask=1025]\n" + + " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + + " PARAMETER_LIST:PsiParameterListStub\n" + + " THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n" + + " METHOD:PsiMethodStub[m2:void default {}]\n" + + " MODIFIER_LIST:PsiModifierListStub[mask=1]\n" + + " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + + " PARAMETER_LIST:PsiParameterListStub\n" + " THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n"); } @@ -393,7 +411,7 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { final String lightStr2 = DebugUtil.stubTreeToString(lighterTree2); if (tree != null) { System.out.println("light=" + t1 + "mks, heavy=" + t2 + "mks"); - if (!"".equals(tree)) { + if (!tree.isEmpty()) { assertEquals("light tree differs", tree, lightStr); assertEquals("light tree (2nd) differs", tree, lightStr2); } diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java index 16fb8dd3c01c..63fcd6b60215 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.psi.formatter.java; import com.intellij.openapi.application.ApplicationManager; @@ -529,12 +544,12 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testJavaDocLinksWithParameterNames() throws Exception { // See IDEADEV-8332 doTextTest("/**\n" + - "* @return if ( x1 == x1 ) then retrun {@link #cmp(String y1,int y2)}\n" + + "* @return if ( x1 == x1 ) then return {@link #cmp(String y1,int y2)}\n" + "* otherwise return {@link #cmp(int x1,int x2)}\n" + "*/\n" + "class X {\n" + "}\n", "/**\n" + - " * @return if ( x1 == x1 ) then retrun {@link #cmp(String y1, int y2)}\n" + + " * @return if ( x1 == x1 ) then return {@link #cmp(String y1, int y2)}\n" + " * otherwise return {@link #cmp(int x1, int x2)}\n" + " */\n" + "class X {\n" + diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java index ae0e4715867e..e967250b7813 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableMultifileTest.java @@ -74,18 +74,13 @@ public class IntroduceVariableMultifileTest extends MultiFileTestCase { ); } - - public void testDummy() { - - } - PerformAction createAction(final String className, final IntroduceVariableBase testMe) { return new PerformAction() { @Override public void performAction(VirtualFile vroot, VirtualFile rootAfter) { final JavaPsiFacade psiManager = getJavaFacade(); final PsiClass aClass = psiManager.findClass(className, GlobalSearchScope.allScope(myProject)); - assertTrue(aClass != null); + assertTrue(className + " class not found", aClass != null); final PsiFile containingFile = aClass.getContainingFile(); final VirtualFile virtualFile = containingFile.getVirtualFile(); assertTrue(virtualFile != null); diff --git a/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java index 30d24589cd8d..cd3fed795f8a 100644 --- a/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java +++ b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java @@ -53,10 +53,7 @@ public class BaseGenerateAction extends CodeInsightAction { PsiDocumentManager.getInstance(project).commitAllDocuments(); PsiClass targetClass = getTargetClass(editor, file); - if (targetClass == null) return false; - if (!isValidForClass(targetClass)) return false; //? - - return true; + return targetClass != null && isValidForClass(targetClass); } protected boolean isValidForClass(final PsiClass targetClass) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/SequentialTaskExecutor.java b/jps/jps-builders/src/org/jetbrains/jps/api/SequentialTaskExecutor.java index 96c7da6d8fa3..8be4a25c76cf 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/SequentialTaskExecutor.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/SequentialTaskExecutor.java @@ -11,7 +11,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * @author Eugene Zhuravlev * Date: 9/24/11 */ -public class SequentialTaskExecutor { +public class SequentialTaskExecutor implements Executor { private final Executor myExecutor; private final Queue myTaskQueue = new LinkedBlockingQueue(); private final AtomicBoolean myInProgress = new AtomicBoolean(false); @@ -36,6 +36,11 @@ public class SequentialTaskExecutor { myExecutor = executor; } + @Override + public void execute(Runnable task) { + submit(task); + } + public RunnableFuture submit(Runnable task) { final FutureTask futureTask = new FutureTask(task, null); if (myTaskQueue.offer(futureTask)) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index 7838b9d84135..0f23ddf7c810 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -324,32 +324,25 @@ final class BuildSession implements Runnable, CanceledStatus { private static void saveFsState(File dataStorageRoot, BuildFSState state, long lastEventOrdinal) { final File file = new File(dataStorageRoot, FS_STATE_FILE); - - BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream(); try { + final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream(); final DataOutputStream out = new DataOutputStream(bytes); - out.writeLong(lastEventOrdinal); try { + out.writeLong(lastEventOrdinal); state.save(out); } finally { out.close(); } - } - catch (IOException e) { - LOG.error(e); - return; - } - FileOutputStream fos = null; - try { - fos = new FileOutputStream(file); - } - catch (FileNotFoundException e) { - FileUtil.createIfDoesntExist(file); - } + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + } + catch (FileNotFoundException e) { + FileUtil.createIfDoesntExist(file); + } - try { if (fos == null) { fos = new FileOutputStream(file); } @@ -359,8 +352,9 @@ final class BuildSession implements Runnable, CanceledStatus { finally { fos.close(); } + } - catch (IOException e) { + catch (Throwable e) { LOG.error(e); FileUtil.delete(file); } @@ -477,7 +471,7 @@ final class BuildSession implements Runnable, CanceledStatus { final String loadPath = isDirectoryBased(projectFile) ? new File(projectFile, IDEA_PROJECT_DIRNAME).getPath() : projectPath; IdeaProjectLoader.loadFromPath(project, loadPath, myPathVars, null, new SystemOutErrorReporter(false)); final String globalEncoding = myGlobalEncoding; - if (globalEncoding != null && project.getProjectCharset() == null) { + if (!StringUtil.isEmpty(globalEncoding) && project.getProjectCharset() == null) { project.setProjectCharset(globalEncoding); } project.getIgnoredFilePatterns().loadFromString(myIgnorePatterns); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/JavaBuilderService.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/JavaBuilderService.java index 5c47fb4cdfd6..541cd0ad756c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/JavaBuilderService.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/JavaBuilderService.java @@ -1,6 +1,7 @@ package org.jetbrains.jps.incremental; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.api.SequentialTaskExecutor; import org.jetbrains.jps.api.SharedThreadPool; import org.jetbrains.jps.incremental.java.JavaBuilder; import org.jetbrains.jps.incremental.resources.ResourcesBuilder; @@ -15,6 +16,6 @@ public class JavaBuilderService extends BuilderService { @NotNull @Override public List createModuleLevelBuilders() { - return Arrays.asList(new JavaBuilder(SharedThreadPool.INSTANCE), new ResourcesBuilder()); + return Arrays.asList(new JavaBuilder(new SequentialTaskExecutor(SharedThreadPool.INSTANCE)), new ResourcesBuilder()); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java index b3079ec10f65..4775d175a857 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java @@ -2,6 +2,8 @@ package org.jetbrains.jps.incremental.fs; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.io.IOUtil; +import gnu.trove.THashSet; +import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.Nullable; import java.io.DataInput; @@ -50,7 +52,7 @@ final class FilesDelta { final File root = new File(IOUtil.readString(in)); Set files = recompile.get(root); if (files == null) { - files = new HashSet(); + files = createSetOfFiles(); recompile.put(root, files); } int filesCount = in.readInt(); @@ -60,6 +62,21 @@ final class FilesDelta { } } + + private static Set createSetOfFiles() { + return new THashSet(new TObjectHashingStrategy() { + @Override + public int computeHashCode(File file) { + return FileUtil.fileHashCode(file); + } + + @Override + public boolean equals(File f1, File f2) { + return FileUtil.filesEqual(f1, f2); + } + }); + } + public void init(Collection deletedProduction, Collection deletedTests, Map> recompileProduction, Map> recompileTests) { myDeletedProduction.clear(); myDeletedProduction.addAll(deletedProduction); @@ -103,7 +120,7 @@ final class FilesDelta { synchronized (toRecompile) { files = toRecompile.get(root); if (files == null) { - files = new HashSet(); + files = createSetOfFiles(); toRecompile.put(root, files); } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index be62585412c8..f90f00941c1f 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -86,7 +86,7 @@ public class Mappings { myChangedFiles = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); myDeletedClasses = new HashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); myDeltaIsTransient = base.myDeltaIsTransient; - myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "delta"); + myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "myDelta"); myContext = base.myContext; myInitName = myContext.get(""); myEmptyName = myContext.get(""); @@ -232,7 +232,6 @@ public class Mappings { private final List myPostPasses; - private void addPostPass(final PostPass p) { myPostPasses.add(p); } @@ -672,7 +671,7 @@ public class Mappings { final File theFile = new File(myContext.getValue(depFile)); if (filter == null || filter.accept(theFile)) { - affectedFiles.add(theFile); + affectedFiles.add(theFile); } } return true; @@ -846,773 +845,270 @@ public class Mappings { boolean accept(File file); } - public boolean differentiate(final Mappings delta, - final Collection removed, - final Collection filesToCompile, - final Collection compiledFiles, - final Collection affectedFiles, - final DependentFilesFilter filter, - @Nullable final Callbacks.ConstantAffectionResolver constantSearch) { - synchronized (myLock) { + private class Differential { + final int DESPERATE_MASK = Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; - class DelayedWorks { - class Triple { - final int owner; - final FieldRepr field; - @Nullable - final Future affection; + final Mappings myDelta; + final Collection myRemoved; + final Collection myFilesToCompile; + final Collection myCompiledFiles; + final Collection myAffectedFiles; + final DependentFilesFilter myFilter; + @Nullable final Callbacks.ConstantAffectionResolver myConstantSearch; + final DelayedWorks myDelayedWorks; - private Triple(final int owner, final FieldRepr field, @Nullable final Future affection) { - this.owner = owner; - this.field = field; - this.affection = affection; - } + final Util myUpdated; + final Util mySelf; + final Util myOriginal; - Callbacks.ConstantAffection getAffection() { - try { - return affection != null ? affection.get() : Callbacks.ConstantAffection.EMPTY; - } - catch (Exception e) { - throw new RuntimeException(e); - } - } + private class DelayedWorks { + class Triple { + final int owner; + final FieldRepr field; + @Nullable + final Future affection; + + private Triple(final int owner, final FieldRepr field, @Nullable final Future affection) { + this.owner = owner; + this.field = field; + this.affection = affection; } - final Collection myQueue = new LinkedList(); - - void addConstantWork(final int ownerClass, final FieldRepr changedField, final boolean isRemoved, boolean accessChanged) { - final Future future; - if (constantSearch == null) { - future = null; + Callbacks.ConstantAffection getAffection() { + try { + return affection != null ? affection.get() : Callbacks.ConstantAffection.EMPTY; } - else { - final String className = myContext.getValue(ownerClass); - final String fieldName = myContext.getValue(changedField.name); - future = constantSearch.request(className.replace('/', '.'), fieldName, changedField.access, isRemoved, accessChanged); + catch (Exception e) { + throw new RuntimeException(e); } - myQueue.add(new Triple(ownerClass, changedField, future)); - } - - boolean doWork(final Collection affectedFiles) { - if (!myQueue.isEmpty()) { - debug("Starting delayed works."); - - for (final Triple t : myQueue) { - final Callbacks.ConstantAffection affection = t.getAffection(); - - debug("Class: ", t.owner); - debug("Field: ", t.field.name); - - if (!affection.isKnown()) { - debug("No external dependency information available."); - debug("Trying to soften non-incremental decision."); - if (!incrementalDecision(t.owner, t.field, affectedFiles, filter)) { - debug("No luck."); - debug("End of delayed work, returning false."); - return false; - } - } - else { - debug("External dependency information retrieved."); - affectedFiles.addAll(affection.getAffectedFiles()); - } - } - - debug("End of delayed work, returning true."); - } - return true; } } - final DelayedWorks works = new DelayedWorks(); + final Collection myQueue = new LinkedList(); - debug("Begin of Differentiate:"); + void addConstantWork(final int ownerClass, final FieldRepr changedField, final boolean isRemoved, boolean accessChanged) { + final Future future; + if (myConstantSearch == null) { + future = null; + } + else { + final String className = myContext.getValue(ownerClass); + final String fieldName = myContext.getValue(changedField.name); + future = myConstantSearch.request(className.replace('/', '.'), fieldName, changedField.access, isRemoved, accessChanged); + } + myQueue.add(new Triple(ownerClass, changedField, future)); + } - delta.runPostPasses(); - delta.compensateRemovedContent(filesToCompile); + boolean doWork(final Collection affectedFiles) { + if (!myQueue.isEmpty()) { + debug("Starting delayed works."); - final Util u = new Util(delta); - final Util self = new Util(this); - final Util o = new Util(); + for (final Triple t : myQueue) { + final Callbacks.ConstantAffection affection = t.getAffection(); - if (removed != null) { - for (String file : removed) { + debug("Class: ", t.owner); + debug("Field: ", t.field.name); + + if (!affection.isKnown()) { + debug("No external dependency information available."); + debug("Trying to soften non-incremental decision."); + if (!incrementalDecision(t.owner, t.field, affectedFiles, myFilter)) { + debug("No luck."); + debug("End of delayed work, returning false."); + return false; + } + } + else { + debug("External dependency information retrieved."); + affectedFiles.addAll(affection.getAffectedFiles()); + } + } + + debug("End of delayed work, returning true."); + } + return true; + } + } + + private class FileClasses { + final int fileName; + final Set fileClasses; + + FileClasses(int fileName, Collection fileClasses) { + this.fileName = fileName; + this.fileClasses = new HashSet(fileClasses); + } + } + + private class DiffState { + final public TIntHashSet dependants = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); + + final public Set affectedUsages = new HashSet(); + final public Set annotationQuery = new HashSet(); + final public Map usageConstraints = new HashMap(); + + final Difference.Specifier classDiff; + + private DiffState(Difference.Specifier classDiff) { + this.classDiff = classDiff; + } + } + + private Differential(final Mappings delta, + final Collection removed, + final Collection filesToCompile, + final Collection compiledFiles, + final Collection affectedFiles, + final DependentFilesFilter filter, + @Nullable final Callbacks.ConstantAffectionResolver constantSearch) { + this.myDelta = delta; + this.myRemoved = removed; + this.myFilesToCompile = filesToCompile; + this.myCompiledFiles = compiledFiles; + this.myAffectedFiles = affectedFiles; + this.myFilter = filter; + this.myConstantSearch = constantSearch; + + myDelayedWorks = new DelayedWorks(); + + myUpdated = new Util(myDelta); + mySelf = new Util(Mappings.this); + myOriginal = new Util(); + } + + private void processDisappearedClasses() { + myDelta.runPostPasses(); + myDelta.compensateRemovedContent(myFilesToCompile); + + if (myRemoved != null) { + for (String file : myRemoved) { final Collection classes = mySourceFileToClasses.get(myContext.get(file)); if (classes != null) { for (ClassRepr c : classes) { debug("Affecting usages of removed class ", c.name); - u.affectAll(c.name, affectedFiles, filter); + myUpdated.affectAll(c.name, myAffectedFiles, myFilter); } } } } + } - class FileClasses { - final int fileName; - final Set fileClasses; + private void processAddedMethods (final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) { + debug("Processing added methods: "); + for (final MethodRepr m : diff.methods().added()) { + debug("Method: ", m.name); - FileClasses(int fileName, Collection fileClasses) { - this.fileName = fileName; - this.fileClasses = new HashSet(fileClasses); + if (it.isAnnotation()) { + debug("Class is annotation, skipping method analysis"); + continue; } - } - final List newClasses = new ArrayList(); - delta.mySourceFileToClasses.forEachEntry(new TIntObjectProcedure>() { - @Override - public boolean execute(int fileName, Collection classes) { - newClasses.add(new FileClasses(fileName, classes)); - return true; + if ((it.access & Opcodes.ACC_INTERFACE) > 0 || + (it.access & Opcodes.ACC_ABSTRACT) > 0 || + (m.access & Opcodes.ACC_ABSTRACT) > 0) { + debug("Class is abstract, or is interface, or added method in abstract => affecting all subclasses"); + myUpdated.affectSubclasses(it.name, myAffectedFiles, state.affectedUsages, state.dependants, false); } - }); - for (final FileClasses compiledFile : newClasses) { - final int fileName = compiledFile.fileName; - final Set classes = compiledFile.fileClasses; - final Set pastClasses = (Set)mySourceFileToClasses.get(fileName); - final TIntHashSet dependants = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); + TIntHashSet propagated = null; - final Set affectedUsages = new HashSet(); - final Set annotationQuery = new HashSet(); - final Map usageConstraints = new HashMap(); + if ((m.access & Opcodes.ACC_PRIVATE) == 0 && m.name != myInitName) { + final ClassRepr oldIt = getReprByName(it.name); - final Difference.Specifier classDiff = Difference.make(pastClasses, classes); + if (oldIt != null && mySelf.findOverridenMethods(m, oldIt).size() > 0) { - debug("Processing changed classes:"); - for (final Pair changed : classDiff.changed()) { - final ClassRepr it = changed.first; - final ClassRepr.Diff diff = (ClassRepr.Diff)changed.second; + } + else { + if (m.argumentTypes.length > 0) { + propagated = myUpdated.propagateMethodAccess(m.name, it.name); + debug("Conservative case on overriding methods, affecting method usages"); + myUpdated.affectMethodUsages(m, propagated, m.createMetaUsage(myContext, it.name), state.affectedUsages, state.dependants); + } + } + } - self.appendDependents(it, dependants); + if ((m.access & Opcodes.ACC_PRIVATE) == 0) { + final Collection> affectedMethods = myUpdated.findAllMethodsBySpecificity(m, it); + final MethodRepr.Predicate overrides = MethodRepr.equalByJavaRules(m); - delta.addChangedClass(it.name); - - debug("Changed: ", it.name); - - final int addedModifiers = diff.addedModifiers(); - - final boolean superClassChanged = (diff.base() & Difference.SUPERCLASS) > 0; - final boolean interfacesChanged = !diff.interfaces().unchanged(); - final boolean signatureChanged = (diff.base() & Difference.SIGNATURE) > 0; - - if (superClassChanged || interfacesChanged || signatureChanged) { - debug("Superclass changed: ", superClassChanged); - debug("Interfaces changed: ", interfacesChanged); - debug("Signature changed ", signatureChanged); - - final boolean extendsChanged = superClassChanged && !diff.extendsAdded(); - final boolean interfacesRemoved = interfacesChanged && !diff.interfaces().removed().isEmpty(); - - debug("Extends changed: ", extendsChanged); - debug("Interfaces removed: ", interfacesRemoved); - - u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, extendsChanged || interfacesRemoved || signatureChanged); + if (propagated == null) { + propagated = myUpdated.propagateMethodAccess(m.name, it.name); } - if ((diff.addedModifiers() & Opcodes.ACC_INTERFACE) > 0 || (diff.removedModifiers() & Opcodes.ACC_INTERFACE) > 0) { - debug("Class-to-interface or interface-to-class conversion detected, added class usage to affected usages"); - affectedUsages.add(it.createUsage()); - } + final Collection lessSpecific = it.findMethods(myUpdated.lessSpecific(m)); - if (it.isAnnotation() && it.policy == RetentionPolicy.SOURCE) { - debug("Annotation, retention policy = SOURCE => a switch to non-incremental mode requested"); - if (!incrementalDecision(it.outerClassName, it, affectedFiles, filter)) { - debug("End of Differentiate, returning false"); - return false; + for (final MethodRepr mm : lessSpecific) { + if (!mm.equals(m)) { + debug("Found less specific method, affecting method usages"); + myUpdated.affectMethodUsages(mm, propagated, mm.createUsage(myContext, it.name), state.affectedUsages, state.dependants); } } - if ((addedModifiers & Opcodes.ACC_PROTECTED) > 0) { - debug("Introduction of 'protected' modifier detected, adding class usage + inheritance constraint to affected usages"); - final UsageRepr.Usage usage = it.createUsage(); + debug("Processing affected by specificity methods"); + for (final Pair p : affectedMethods) { + final MethodRepr mm = p.first; + final ClassRepr cc = p.second; - affectedUsages.add(usage); - usageConstraints.put(usage, u.new InheritanceConstraint(it.name)); - } + if (cc == myMockClass) { - if (diff.packageLocalOn()) { - debug("Introduction of 'package local' access detected, adding class usage + package constraint to affected usages"); - final UsageRepr.Usage usage = it.createUsage(); - - affectedUsages.add(usage); - usageConstraints.put(usage, u.new PackageConstraint(it.getPackageName())); - } - - if ((addedModifiers & Opcodes.ACC_FINAL) > 0 || (addedModifiers & Opcodes.ACC_PRIVATE) > 0) { - debug("Introduction of 'private' or 'final' modifier(s) detected, adding class usage to affected usages"); - affectedUsages.add(it.createUsage()); - } - - if ((addedModifiers & Opcodes.ACC_ABSTRACT) > 0 || (addedModifiers & Opcodes.ACC_STATIC) > 0) { - debug("Introduction of 'abstract' or 'static' modifier(s) detected, adding class new usage to affected usages"); - affectedUsages.add(UsageRepr.createClassNewUsage(myContext, it.name)); - } - - if (it.isAnnotation()) { - debug("Class is annotation, performing annotation-specific analysis"); - - if (diff.retentionChanged()) { - debug("Retention policy change detected, adding class usage to affected usages"); - affectedUsages.add(it.createUsage()); } else { - final Collection removedtargets = diff.targets().removed(); + final Option inheritorOf = mySelf.isInheritorOf(cc.name, it.name); - if (removedtargets.contains(ElemType.LOCAL_VARIABLE)) { - debug("Removed target contains LOCAL_VARIABLE => a switch to non-incremental mode requested"); - if (!incrementalDecision(it.outerClassName, it, affectedFiles, filter)) { - debug("End of Differentiate, returning false"); - return false; + debug("Method: ", mm.name); + debug("Class : ", cc.name); + + if (overrides.satisfy(mm) && inheritorOf.isValue() && inheritorOf.value()) { + debug("Current method overrides that found"); + + final int file = myClassToSourceFile.get(cc.name); + + if (file > 0) { + final String f = myContext.getValue(file); + debug("Affecting file ", f); + myAffectedFiles.add(new File(f)); } } - - if (!removedtargets.isEmpty()) { - debug("Removed some annotation targets, adding annotation query"); - annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr - .createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), null, EnumSet.copyOf(removedtargets))); - } - - for (final MethodRepr m : diff.methods().added()) { - if (!m.hasValue()) { - debug("Added method with no default value: ", m.name); - debug("Adding class usage to affected usages"); - affectedUsages.add(it.createUsage()); - } - } - } - - debug("End of annotation-specific analysis"); - } - - debug("Processing added methods: "); - for (final MethodRepr m : diff.methods().added()) { - debug("Method: ", m.name); - - if (it.isAnnotation()) { - debug("Class is annotation, skipping method analysis"); - continue; - } - - if ((it.access & Opcodes.ACC_INTERFACE) > 0 || - (it.access & Opcodes.ACC_ABSTRACT) > 0 || - (m.access & Opcodes.ACC_ABSTRACT) > 0) { - debug("Class is abstract, or is interface, or added method in abstract => affecting all subclasses"); - u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false); - } - - TIntHashSet propagated = null; - - if ((m.access & Opcodes.ACC_PRIVATE) == 0 && m.name != myInitName) { - final ClassRepr oldIt = getReprByName(it.name); - - if (oldIt != null && self.findOverridenMethods(m, oldIt).size() > 0) { - - } else { - if (m.argumentTypes.length > 0) { - propagated = u.propagateMethodAccess(m.name, it.name); - debug("Conservative case on overriding methods, affecting method usages"); - u.affectMethodUsages(m, propagated, m.createMetaUsage(myContext, it.name), affectedUsages, dependants); - } - } - } + debug("Current method does not override that found"); - if ((m.access & Opcodes.ACC_PRIVATE) == 0) { - final Collection> affectedMethods = u.findAllMethodsBySpecificity(m, it); - final MethodRepr.Predicate overrides = MethodRepr.equalByJavaRules(m); + final TIntHashSet yetPropagated = mySelf.propagateMethodAccess(mm.name, it.name); - if (propagated == null) { - propagated = u.propagateMethodAccess(m.name, it.name); - } - - final Collection lessSpecific = it.findMethods(u.lessSpecific(m)); - - for (final MethodRepr mm : lessSpecific) { - if (!mm.equals(m)) { - debug("Found less specific method, affecting method usages"); - u.affectMethodUsages(mm, propagated, mm.createUsage(myContext, it.name), affectedUsages, dependants); - } - } - - debug("Processing affected by specificity methods"); - for (final Pair p : affectedMethods) { - final MethodRepr mm = p.first; - final ClassRepr cc = p.second; - - if (cc == myMockClass) { - - } - else { - final Option inheritorOf = self.isInheritorOf(cc.name, it.name); - - debug("Method: ", mm.name); - debug("Class : ", cc.name); - - if (overrides.satisfy(mm) && inheritorOf.isValue() && inheritorOf.value()) { - debug("Current method overrides that found"); - - final int file = myClassToSourceFile.get(cc.name); - - if (file > 0) { - final String f = myContext.getValue(file); - debug("Affecting file ", f); - affectedFiles.add(new File(f)); - } - } - else { - debug("Current method does not override that found"); - - final TIntHashSet yetPropagated = self.propagateMethodAccess(mm.name, it.name); - - if (inheritorOf.isValue() && inheritorOf.value()) { - final TIntHashSet deps = myClassToClassDependency.get(cc.name); - - if (deps != null) { - addAll(dependants, deps); - } - - u.affectMethodUsages(mm, yetPropagated, mm.createUsage(myContext, cc.name), affectedUsages, dependants); - } - - debug("Affecting method usages for that found"); - u.affectMethodUsages(mm, yetPropagated, mm.createUsage(myContext, it.name), affectedUsages, dependants); - } - } - } - - final TIntHashSet subClasses = getAllSubclasses(it.name); - - if (subClasses != null) { - subClasses.forEach(new TIntProcedure() { - @Override - public boolean execute(int subClass) { - final ClassRepr r = u.reprByName(subClass); - final int sourceFileName = myClassToSourceFile.get(subClass); - - if (r != null && sourceFileName > 0) { - final int outerClass = r.outerClassName; - - if (u.methodVisible(outerClass, m)) { - final String f = myContext.getValue(sourceFileName); - debug("Affecting file due to local overriding: ", f); - affectedFiles.add(new File(f)); - } - } - return true; - } - }); - } - } - } - debug("End of added methods processing"); - - debug("Processing removed methods:"); - for (final MethodRepr m : diff.methods().removed()) { - debug("Method ", m.name); - - final Collection> overridenMethods = u.findOverridenMethods(m, it); - final TIntHashSet propagated = u.propagateMethodAccess(m.name, it.name); - - if (overridenMethods.size() == 0) { - debug("No overridden methods found, affecting method usages"); - u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), affectedUsages, dependants); - } - else { - boolean clear = true; - - loop: - for (final Pair overriden : overridenMethods) { - final MethodRepr mm = overriden.first; - - if (mm == myMockMethod || !mm.type.equals(m.type) || !empty(mm.signature) || !empty(m.signature)) { - clear = false; - break loop; - } - } - - if (!clear) { - debug("No clearly overridden methods found, affecting method usages"); - u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), affectedUsages, dependants); - } - } - - final Collection> overriding = u.findOverridingMethods(m, it, false); - - for (final Pair p : overriding) { - final int fName = myClassToSourceFile.get(p.second.name); - debug("Affecting file by overriding: ", fName); - affectedFiles.add(new File(myContext.getValue(fName))); - } - - if ((m.access & Opcodes.ACC_ABSTRACT) == 0) { - propagated.forEach(new TIntProcedure() { - @Override - public boolean execute(int p) { - if (p != it.name) { - final ClassRepr s = u.reprByName(p); - - if (s != null) { - final Collection> overridenInS = u.findOverridenMethods(m, s); - - overridenInS.addAll(overridenMethods); - - boolean allAbstract = true; - boolean visited = false; - - for (final Pair pp : overridenInS) { - final ClassRepr cc = pp.second; - - if (cc == myMockClass) { - visited = true; - continue; - } - - if (cc.name == it.name) { - continue; - } - - visited = true; - allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((cc.access & Opcodes.ACC_INTERFACE) > 0); - - if (!allAbstract) { - break; - } - } - - if (allAbstract && visited) { - final int source = myClassToSourceFile.get(p); - - if (source > 0) { - final String f = myContext.getValue(source); - debug( - "Removed method is not abstract & overrides some abstract method which is not then over-overriden in subclass ", - p); - debug("Affecting subclass source file ", f); - affectedFiles.add(new File(f)); - } - } - } - } - return true; - } - }); - } - } - debug("End of removed methods processing"); - - debug("Processing changed methods:"); - for (final Pair mr : diff.methods().changed()) { - final MethodRepr m = mr.first; - final MethodRepr.Diff d = (MethodRepr.Diff)mr.second; - final boolean throwsChanged = (d.exceptions().added().size() > 0) || (d.exceptions().changed().size() > 0); - - debug("Method: ", m.name); - - if (it.isAnnotation()) { - if (d.defaultRemoved()) { - debug("Class is annotation, default value is removed => adding annotation query"); - final TIntHashSet l = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); - l.add(m.name); - annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr - .createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), l, null)); - } - } - else if (d.base() != Difference.NONE || throwsChanged) { - final TIntHashSet propagated = u.propagateMethodAccess(m.name, it.name); - - boolean affected = false; - boolean constrained = false; - - final Set usages = new HashSet(); - - if (d.packageLocalOn()) { - debug("Method became package-local, affecting method usages outside the package"); - u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants); - - for (final UsageRepr.Usage usage : usages) { - usageConstraints.put(usage, u.new InheritanceConstraint(it.name)); - } - - affectedUsages.addAll(usages); - affected = true; - constrained = true; - } - - if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0 || throwsChanged) { - if (!affected) { - debug("Return type, throws list or signature changed --- affecting method usages"); - u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants); - affectedUsages.addAll(usages); - } - } - else if ((d.base() & Difference.ACCESS) > 0) { - if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0 || - (d.removedModifiers() & Opcodes.ACC_STATIC) > 0 || - (d.addedModifiers() & Opcodes.ACC_PRIVATE) > 0) { - if (!affected) { - debug("Added static or private specifier or removed static specifier --- affecting method usages"); - u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants); - affectedUsages.addAll(usages); - } - - if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0) { - debug("Added static specifier --- affecting subclasses"); - u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false); - } - } - else { - if ((d.addedModifiers() & Opcodes.ACC_FINAL) > 0 || - (d.addedModifiers() & Opcodes.ACC_PUBLIC) > 0 || - (d.addedModifiers() & Opcodes.ACC_ABSTRACT) > 0) { - debug("Added final, public or abstract specifier --- affecting subclasses"); - u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false); - } - - if ((d.addedModifiers() & Opcodes.ACC_PROTECTED) > 0 && !((d.removedModifiers() & Opcodes.ACC_PRIVATE) > 0)) { - if (!constrained) { - debug("Added public or package-local method became protected --- affect method usages with protected constraint"); - if (!affected) { - u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants); - affectedUsages.addAll(usages); - } - - for (final UsageRepr.Usage usage : usages) { - usageConstraints.put(usage, u.new InheritanceConstraint(it.name)); - } - } - } - } - } - } - } - debug("End of changed methods processing"); - - final int mask = Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; - - debug("Processing added fields"); - for (final FieldRepr f : diff.fields().added()) { - debug("Field: ", f.name); - - final boolean fPrivate = (f.access & Opcodes.ACC_PRIVATE) > 0; - final boolean fProtected = (f.access & Opcodes.ACC_PROTECTED) > 0; - final boolean fPublic = (f.access & Opcodes.ACC_PUBLIC) > 0; - final boolean fPLocal = !fPrivate && !fProtected && !fPublic; - - if (!fPrivate) { - final TIntHashSet subClasses = getAllSubclasses(it.name); - subClasses.forEach(new TIntProcedure() { - @Override - public boolean execute(int subClass) { - final ClassRepr r = u.reprByName(subClass); - final int sourceFileName = myClassToSourceFile.get(subClass); - - if (r != null && sourceFileName > 0) { - if (r.isLocal) { - debug( - "Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ", - sourceFileName); - affectedFiles.add(new File(myContext.getValue(sourceFileName))); - } - else { - final int outerClass = r.outerClassName; - - if (!empty(outerClass) && u.fieldVisible(outerClass, f)) { - debug("Affecting inner subclass (introduced field can potentially hide surrounding class fields): ", - sourceFileName); - affectedFiles.add(new File(myContext.getValue(sourceFileName))); - } - } - } - - debug("Affecting field usages referenced from subclass ", subClass); - final TIntHashSet propagated = u.propagateFieldAccess(f.name, subClass); - u.affectFieldUsages(f, propagated, f.createUsage(myContext, subClass), affectedUsages, dependants); - - final TIntHashSet deps = myClassToClassDependency.get(subClass); + if (inheritorOf.isValue() && inheritorOf.value()) { + final TIntHashSet deps = myClassToClassDependency.get(cc.name); if (deps != null) { - addAll(dependants, deps); - } - return true; - } - }); - } - - final Collection> overridden = u.findOverridenFields(f, it); - - for (final Pair p : overridden) { - final FieldRepr ff = p.first; - final ClassRepr cc = p.second; - - final boolean ffPrivate = (ff.access & Opcodes.ACC_PRIVATE) > 0; - final boolean ffProtected = (ff.access & Opcodes.ACC_PROTECTED) > 0; - final boolean ffPublic = (ff.access & Opcodes.ACC_PUBLIC) > 0; - final boolean ffPLocal = Difference.isPackageLocal(ff.access); - - if (!ffPrivate) { - final TIntHashSet propagated = o.propagateFieldAccess(ff.name, cc.name); - final Set localUsages = new HashSet(); - - debug("Affecting usages of overridden field in class ", cc.name); - u.affectFieldUsages(ff, propagated, ff.createUsage(myContext, cc.name), localUsages, dependants); - - if (fPrivate || (fPublic && (ffPublic || ffPLocal)) || (fProtected && ffProtected) || (fPLocal && ffPLocal)) { - - } - else { - Util.UsageConstraint constaint; - - if ((ffProtected && fPublic) || (fProtected && ffPublic) || (ffPLocal && fProtected)) { - constaint = u.new NegationConstraint(u.new InheritanceConstraint(cc.name)); - } - else if (ffPublic && ffPLocal) { - constaint = u.new NegationConstraint(u.new PackageConstraint(cc.getPackageName())); - } - else { - constaint = u.new IntersectionConstraint(u.new NegationConstraint(u.new InheritanceConstraint(cc.name)), - u.new NegationConstraint(u.new PackageConstraint(cc.getPackageName()))); + addAll(state.dependants, deps); } - for (final UsageRepr.Usage usage : localUsages) { - usageConstraints.put(usage, constaint); - } + myUpdated + .affectMethodUsages(mm, yetPropagated, mm.createUsage(myContext, cc.name), state.affectedUsages, state.dependants); } - affectedUsages.addAll(localUsages); + debug("Affecting method usages for that found"); + myUpdated + .affectMethodUsages(mm, yetPropagated, mm.createUsage(myContext, it.name), state.affectedUsages, state.dependants); } } } - debug("End of added fields processing"); - debug("Processing removed fields:"); - for (final FieldRepr f : diff.fields().removed()) { - debug("Field: ", f.name); + final TIntHashSet subClasses = getAllSubclasses(it.name); - if ((f.access & Opcodes.ACC_PRIVATE) == 0 && (f.access & mask) == mask && f.hasValue()) { - debug("Field had value and was (non-private) final static => a switch to non-incremental mode requested"); - if (constantSearch != null) { - works.addConstantWork(it.name, f, true, false); - } - else { - if (!incrementalDecision(it.name, f, affectedFiles, filter)) { - debug("End of Differentiate, returning false"); - return false; - } - } - } - - final TIntHashSet propagated = u.propagateFieldAccess(f.name, it.name); - u.affectFieldUsages(f, propagated, f.createUsage(myContext, it.name), affectedUsages, dependants); - } - debug("End of removed fields processing"); - - debug("Processing changed fields:"); - for (final Pair f : diff.fields().changed()) { - final Difference d = f.second; - final FieldRepr field = f.first; - - debug("Field: ", field.name); - - if ((field.access & Opcodes.ACC_PRIVATE) == 0 && (field.access & mask) == mask) { - final int changedModifiers = d.addedModifiers() | d.removedModifiers(); - final boolean harmful = (changedModifiers & (Opcodes.ACC_STATIC | Opcodes.ACC_FINAL)) > 0; - final boolean accessChanged = (changedModifiers & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) > 0; - final boolean valueChanged = (d.base() & Difference.VALUE) > 0 && d.hadValue(); - - if (harmful || valueChanged || (accessChanged && !d.weakedAccess())) { - debug("Inline field changed it's access or value => a switch to non-incremental mode requested"); - if (constantSearch != null) { - works.addConstantWork(it.name, field, false, accessChanged); - } - else { - if (!incrementalDecision(it.name, field, affectedFiles, filter)) { - debug("End of Differentiate, returning false"); - return false; - } - } - } - } - - if (d.base() != Difference.NONE) { - final TIntHashSet propagated = u.propagateFieldAccess(field.name, it.name); - - if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0) { - debug("Type or signature changed --- affecting field usages"); - u.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), affectedUsages, dependants); - } - else if ((d.base() & Difference.ACCESS) > 0) { - if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0 || - (d.removedModifiers() & Opcodes.ACC_STATIC) > 0 || - (d.addedModifiers() & Opcodes.ACC_PRIVATE) > 0 || - (d.addedModifiers() & Opcodes.ACC_VOLATILE) > 0) { - debug("Added/removed static modifier or added private/volatile modifier --- affecting field usages"); - u.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), affectedUsages, dependants); - } - else { - boolean affected = false; - final Set usages = new HashSet(); - - if ((d.addedModifiers() & Opcodes.ACC_FINAL) > 0) { - debug("Added final modifier --- affecting field assign usages"); - u.affectFieldUsages(field, propagated, field.createAssignUsage(myContext, it.name), usages, dependants); - affectedUsages.addAll(usages); - affected = true; - } - - if ((d.removedModifiers() & Opcodes.ACC_PUBLIC) > 0) { - debug("Removed public modifier, affecting field usages with appropriate constraint"); - if (!affected) { - u.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), usages, dependants); - affectedUsages.addAll(usages); - } - - for (final UsageRepr.Usage usage : usages) { - if ((d.addedModifiers() & Opcodes.ACC_PROTECTED) > 0) { - usageConstraints.put(usage, u.new InheritanceConstraint(it.name)); - } - else { - usageConstraints.put(usage, u.new PackageConstraint(it.getPackageName())); - } - } - } - } - } - } - } - debug("End of changed fields processing"); - } - debug("End of changed classes processing"); - - debug("Processing removed classes:"); - for (final ClassRepr c : classDiff.removed()) { - delta.addDeletedClass(c); - self.appendDependents(c, dependants); - debug("Adding usages of class ", c.name); - affectedUsages.add(c.createUsage()); - } - debug("End of removed classes processing."); - - debug("Processing added classes:"); - for (final ClassRepr c : classDiff.added()) { - debug("Class name: ", c.name); - delta.addChangedClass(c.name); - - final TIntHashSet depClasses = myClassToClassDependency.get(c.name); - - if (depClasses != null) { - depClasses.forEach(new TIntProcedure() { + if (subClasses != null) { + subClasses.forEach(new TIntProcedure() { @Override - public boolean execute(int depClass) { - final int fName = myClassToSourceFile.get(depClass); + public boolean execute(int subClass) { + final ClassRepr r = myUpdated.reprByName(subClass); + final int sourceFileName = myClassToSourceFile.get(subClass); - if (fName > 0) { - final String f = myContext.getValue(fName); - final File theFile = new File(f); + if (r != null && sourceFileName > 0) { + final int outerClass = r.outerClassName; - if (filter.accept(theFile)) { - debug("Adding dependent file ", f); - affectedFiles.add(theFile); + if (myUpdated.methodVisible(outerClass, m)) { + final String f = myContext.getValue(sourceFileName); + debug("Affecting file due to local overriding: ", f); + myAffectedFiles.add(new File(f)); } } return true; @@ -1620,92 +1116,704 @@ public class Mappings { }); } } - debug("End of added classes processing."); + } + debug("End of added methods processing"); + } - debug("Checking dependent files:"); - final TIntHashSet dependentFiles = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); + private void processRemovedMethods (final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) { + debug("Processing removed methods:"); + for (final MethodRepr m : diff.methods().removed()) { + debug("Method ", m.name); - dependants.forEach(new TIntProcedure() { - @Override - public boolean execute(int depClass) { - final int file = myClassToSourceFile.get(depClass); - if (file > 0) { - dependentFiles.add(file); + final Collection> overridenMethods = myUpdated.findOverridenMethods(m, it); + final TIntHashSet propagated = myUpdated.propagateMethodAccess(m.name, it.name); + + if (overridenMethods.size() == 0) { + debug("No overridden methods found, affecting method usages"); + myUpdated.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), state.affectedUsages, state.dependants); + } + else { + boolean clear = true; + + loop: + for (final Pair overriden : overridenMethods) { + final MethodRepr mm = overriden.first; + + if (mm == myMockMethod || !mm.type.equals(m.type) || !empty(mm.signature) || !empty(m.signature)) { + clear = false; + break loop; } - return true; - } - }); - - - filewise: - for (final int depFile : dependentFiles.toArray()) { // todo: avoid toArray()? - final File theFile = new File(myContext.getValue(depFile)); - - if (affectedFiles.contains(theFile) || compiledFiles.contains(theFile)) { - continue filewise; } - debug("Dependent file: ", depFile); - final Collection depClusters = mySourceFileToUsages.get(depFile); - if (depClusters != null) { - for (final UsageRepr.Cluster depCluster : depClusters) { - final Set depUsages = depCluster.getUsages(); - if (depUsages == null) { - continue; - } - final Set usages = new HashSet(depUsages); + if (!clear) { + debug("No clearly overridden methods found, affecting method usages"); + myUpdated.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), state.affectedUsages, state.dependants); + } + } - usages.retainAll(affectedUsages); + final Collection> overriding = myUpdated.findOverridingMethods(m, it, false); - if (!usages.isEmpty()) { - for (UsageRepr.Usage usage : usages) { - final Util.UsageConstraint constraint = usageConstraints.get(usage); + for (final Pair p : overriding) { + final int fName = myClassToSourceFile.get(p.second.name); + debug("Affecting file by overriding: ", fName); + myAffectedFiles.add(new File(myContext.getValue(fName))); + } - if (constraint == null) { - debug("Added file with no constraints"); - affectedFiles.add(theFile); - continue filewise; + if ((m.access & Opcodes.ACC_ABSTRACT) == 0) { + propagated.forEach(new TIntProcedure() { + @Override + public boolean execute(int p) { + if (p != it.name) { + final ClassRepr s = myUpdated.reprByName(p); + + if (s != null) { + final Collection> overridenInS = myUpdated.findOverridenMethods(m, s); + + overridenInS.addAll(overridenMethods); + + boolean allAbstract = true; + boolean visited = false; + + for (final Pair pp : overridenInS) { + final ClassRepr cc = pp.second; + + if (cc == myMockClass) { + visited = true; + continue; + } + + if (cc.name == it.name) { + continue; + } + + visited = true; + allAbstract = ((pp.first.access & Opcodes.ACC_ABSTRACT) > 0) || ((cc.access & Opcodes.ACC_INTERFACE) > 0); + + if (!allAbstract) { + break; + } } - else { - final TIntHashSet residenceClasses = depCluster.getResidence(usage); - for (final int residentName : residenceClasses.toArray()) { - if (constraint.checkResidence(residentName)) { - debug("Added file with satisfied constraint"); - affectedFiles.add(theFile); - continue filewise; - } + + if (allAbstract && visited) { + final int source = myClassToSourceFile.get(p); + + if (source > 0) { + final String f = myContext.getValue(source); + debug( + "Removed method is not abstract & overrides some abstract method which is not then over-overriden in subclass ", + p); + debug("Affecting subclass source file ", f); + myAffectedFiles.add(new File(f)); } } } } + return true; + } + }); + } + } + debug("End of removed methods processing"); + } - if (annotationQuery.size() > 0) { - final Collection annotationUsages = mySourceFileToAnnotationUsages.get(depFile); + private void processChangedMethods (final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) { + debug("Processing changed methods:"); + for (final Pair mr : diff.methods().changed()) { + final MethodRepr m = mr.first; + final MethodRepr.Diff d = (MethodRepr.Diff)mr.second; + final boolean throwsChanged = (d.exceptions().added().size() > 0) || (d.exceptions().changed().size() > 0); - for (final UsageRepr.Usage usage : annotationUsages) { - for (final UsageRepr.AnnotationUsage query : annotationQuery) { - if (query.satisfies(usage)) { - debug("Added file due to annotation query"); - affectedFiles.add(theFile); + debug("Method: ", m.name); + + if (it.isAnnotation()) { + if (d.defaultRemoved()) { + debug("Class is annotation, default value is removed => adding annotation query"); + final TIntHashSet l = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); + l.add(m.name); + state.annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr + .createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), l, null)); + } + } + else if (d.base() != Difference.NONE || throwsChanged) { + final TIntHashSet propagated = myUpdated.propagateMethodAccess(m.name, it.name); + + boolean affected = false; + boolean constrained = false; + + final Set usages = new HashSet(); + + if (d.packageLocalOn()) { + debug("Method became package-local, affecting method usages outside the package"); + myUpdated.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.dependants); + + for (final UsageRepr.Usage usage : usages) { + state.usageConstraints.put(usage, myUpdated.new InheritanceConstraint(it.name)); + } + + state.affectedUsages.addAll(usages); + affected = true; + constrained = true; + } + + if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0 || throwsChanged) { + if (!affected) { + debug("Return type, throws list or signature changed --- affecting method usages"); + myUpdated.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.dependants); + state.affectedUsages.addAll(usages); + } + } + else if ((d.base() & Difference.ACCESS) > 0) { + if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0 || + (d.removedModifiers() & Opcodes.ACC_STATIC) > 0 || + (d.addedModifiers() & Opcodes.ACC_PRIVATE) > 0) { + if (!affected) { + debug("Added static or private specifier or removed static specifier --- affecting method usages"); + myUpdated.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.dependants); + state.affectedUsages.addAll(usages); + } + + if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0) { + debug("Added static specifier --- affecting subclasses"); + myUpdated.affectSubclasses(it.name, myAffectedFiles, state.affectedUsages, state.dependants, false); + } + } + else { + if ((d.addedModifiers() & Opcodes.ACC_FINAL) > 0 || + (d.addedModifiers() & Opcodes.ACC_PUBLIC) > 0 || + (d.addedModifiers() & Opcodes.ACC_ABSTRACT) > 0) { + debug("Added final, public or abstract specifier --- affecting subclasses"); + myUpdated.affectSubclasses(it.name, myAffectedFiles, state.affectedUsages, state.dependants, false); + } + + if ((d.addedModifiers() & Opcodes.ACC_PROTECTED) > 0 && !((d.removedModifiers() & Opcodes.ACC_PRIVATE) > 0)) { + if (!constrained) { + debug("Added public or package-local method became protected --- affect method usages with protected constraint"); + if (!affected) { + myUpdated.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.dependants); + state.affectedUsages.addAll(usages); + } + + for (final UsageRepr.Usage usage : usages) { + state.usageConstraints.put(usage, myUpdated.new InheritanceConstraint(it.name)); + } + } + } + } + } + } + } + debug("End of changed methods processing"); + } + + private boolean processAddedFields (final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) { + debug("Processing added fields"); + + for (final FieldRepr f : diff.fields().added()) { + debug("Field: ", f.name); + + final boolean fPrivate = (f.access & Opcodes.ACC_PRIVATE) > 0; + final boolean fProtected = (f.access & Opcodes.ACC_PROTECTED) > 0; + final boolean fPublic = (f.access & Opcodes.ACC_PUBLIC) > 0; + final boolean fPLocal = !fPrivate && !fProtected && !fPublic; + + if (!fPrivate) { + final TIntHashSet subClasses = getAllSubclasses(it.name); + subClasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int subClass) { + final ClassRepr r = myUpdated.reprByName(subClass); + final int sourceFileName = myClassToSourceFile.get(subClass); + + if (r != null && sourceFileName > 0) { + if (r.isLocal) { + debug( + "Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ", + sourceFileName); + myAffectedFiles.add(new File(myContext.getValue(sourceFileName))); + } + else { + final int outerClass = r.outerClassName; + + if (!empty(outerClass) && myUpdated.fieldVisible(outerClass, f)) { + debug("Affecting inner subclass (introduced field can potentially hide surrounding class fields): ", + sourceFileName); + myAffectedFiles.add(new File(myContext.getValue(sourceFileName))); + } + } + } + + debug("Affecting field usages referenced from subclass ", subClass); + final TIntHashSet propagated = myUpdated.propagateFieldAccess(f.name, subClass); + myUpdated.affectFieldUsages(f, propagated, f.createUsage(myContext, subClass), state.affectedUsages, state.dependants); + + final TIntHashSet deps = myClassToClassDependency.get(subClass); + + if (deps != null) { + addAll(state.dependants, deps); + } + return true; + } + }); + } + + final Collection> overridden = myUpdated.findOverridenFields(f, it); + + for (final Pair p : overridden) { + final FieldRepr ff = p.first; + final ClassRepr cc = p.second; + + final boolean ffPrivate = (ff.access & Opcodes.ACC_PRIVATE) > 0; + final boolean ffProtected = (ff.access & Opcodes.ACC_PROTECTED) > 0; + final boolean ffPublic = (ff.access & Opcodes.ACC_PUBLIC) > 0; + final boolean ffPLocal = Difference.isPackageLocal(ff.access); + + if (!ffPrivate) { + final TIntHashSet propagated = myOriginal.propagateFieldAccess(ff.name, cc.name); + final Set localUsages = new HashSet(); + + debug("Affecting usages of overridden field in class ", cc.name); + myUpdated.affectFieldUsages(ff, propagated, ff.createUsage(myContext, cc.name), localUsages, state.dependants); + + if (fPrivate || (fPublic && (ffPublic || ffPLocal)) || (fProtected && ffProtected) || (fPLocal && ffPLocal)) { + + } + else { + Util.UsageConstraint constaint; + + if ((ffProtected && fPublic) || (fProtected && ffPublic) || (ffPLocal && fProtected)) { + constaint = myUpdated.new NegationConstraint(myUpdated.new InheritanceConstraint(cc.name)); + } + else if (ffPublic && ffPLocal) { + constaint = myUpdated.new NegationConstraint(myUpdated.new PackageConstraint(cc.getPackageName())); + } + else { + constaint = + myUpdated.new IntersectionConstraint(myUpdated.new NegationConstraint(myUpdated.new InheritanceConstraint(cc.name)), + myUpdated.new NegationConstraint( + myUpdated.new PackageConstraint(cc.getPackageName()))); + } + + for (final UsageRepr.Usage usage : localUsages) { + state.usageConstraints.put(usage, constaint); + } + } + + state.affectedUsages.addAll(localUsages); + } + } + } + debug("End of added fields processing"); + + return true; + } + + private boolean processRemovedFields (final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) { + debug("Processing removed fields:"); + + for (final FieldRepr f : diff.fields().removed()) { + debug("Field: ", f.name); + + if ((f.access & Opcodes.ACC_PRIVATE) == 0 && (f.access & DESPERATE_MASK) == DESPERATE_MASK && f.hasValue()) { + debug("Field had value and was (non-private) final static => a switch to non-incremental mode requested"); + if (myConstantSearch != null) { + myDelayedWorks.addConstantWork(it.name, f, true, false); + } + else { + if (!incrementalDecision(it.name, f, myAffectedFiles, myFilter)) { + debug("End of Differentiate, returning false"); + return false; + } + } + } + + final TIntHashSet propagated = myUpdated.propagateFieldAccess(f.name, it.name); + myUpdated.affectFieldUsages(f, propagated, f.createUsage(myContext, it.name), state.affectedUsages, state.dependants); + } + debug("End of removed fields processing"); + + return true; + } + + private boolean processChangedFields (final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) { + debug("Processing changed fields:"); + + for (final Pair f : diff.fields().changed()) { + final Difference d = f.second; + final FieldRepr field = f.first; + + debug("Field: ", field.name); + + if ((field.access & Opcodes.ACC_PRIVATE) == 0 && (field.access & DESPERATE_MASK) == DESPERATE_MASK) { + final int changedModifiers = d.addedModifiers() | d.removedModifiers(); + final boolean harmful = (changedModifiers & (Opcodes.ACC_STATIC | Opcodes.ACC_FINAL)) > 0; + final boolean accessChanged = (changedModifiers & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) > 0; + final boolean valueChanged = (d.base() & Difference.VALUE) > 0 && d.hadValue(); + + if (harmful || valueChanged || (accessChanged && !d.weakedAccess())) { + debug("Inline field changed it's access or value => a switch to non-incremental mode requested"); + if (myConstantSearch != null) { + myDelayedWorks.addConstantWork(it.name, field, false, accessChanged); + } + else { + if (!incrementalDecision(it.name, field, myAffectedFiles, myFilter)) { + debug("End of Differentiate, returning false"); + return false; + } + } + } + } + + if (d.base() != Difference.NONE) { + final TIntHashSet propagated = myUpdated.propagateFieldAccess(field.name, it.name); + + if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0) { + debug("Type or signature changed --- affecting field usages"); + myUpdated.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), state.affectedUsages, state.dependants); + } + else if ((d.base() & Difference.ACCESS) > 0) { + if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0 || + (d.removedModifiers() & Opcodes.ACC_STATIC) > 0 || + (d.addedModifiers() & Opcodes.ACC_PRIVATE) > 0 || + (d.addedModifiers() & Opcodes.ACC_VOLATILE) > 0) { + debug("Added/removed static modifier or added private/volatile modifier --- affecting field usages"); + myUpdated + .affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), state.affectedUsages, state.dependants); + } + else { + boolean affected = false; + final Set usages = new HashSet(); + + if ((d.addedModifiers() & Opcodes.ACC_FINAL) > 0) { + debug("Added final modifier --- affecting field assign usages"); + myUpdated.affectFieldUsages(field, propagated, field.createAssignUsage(myContext, it.name), usages, state.dependants); + state.affectedUsages.addAll(usages); + affected = true; + } + + if ((d.removedModifiers() & Opcodes.ACC_PUBLIC) > 0) { + debug("Removed public modifier, affecting field usages with appropriate constraint"); + if (!affected) { + myUpdated.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), usages, state.dependants); + state.affectedUsages.addAll(usages); + } + + for (final UsageRepr.Usage usage : usages) { + if ((d.addedModifiers() & Opcodes.ACC_PROTECTED) > 0) { + state.usageConstraints.put(usage, myUpdated.new InheritanceConstraint(it.name)); + } + else { + state.usageConstraints.put(usage, myUpdated.new PackageConstraint(it.getPackageName())); + } + } + } + } + } + } + } + debug("End of changed fields processing"); + + return true; + } + + private boolean processChangedClasses(final DiffState state) { + debug("Processing changed classes:"); + for (final Pair changed : state.classDiff.changed()) { + final ClassRepr it = changed.first; + final ClassRepr.Diff diff = (ClassRepr.Diff)changed.second; + + mySelf.appendDependents(it, state.dependants); + + myDelta.addChangedClass(it.name); + + debug("Changed: ", it.name); + + final int addedModifiers = diff.addedModifiers(); + + final boolean superClassChanged = (diff.base() & Difference.SUPERCLASS) > 0; + final boolean interfacesChanged = !diff.interfaces().unchanged(); + final boolean signatureChanged = (diff.base() & Difference.SIGNATURE) > 0; + + if (superClassChanged || interfacesChanged || signatureChanged) { + debug("Superclass changed: ", superClassChanged); + debug("Interfaces changed: ", interfacesChanged); + debug("Signature changed ", signatureChanged); + + final boolean extendsChanged = superClassChanged && !diff.extendsAdded(); + final boolean interfacesRemoved = interfacesChanged && !diff.interfaces().removed().isEmpty(); + + debug("Extends changed: ", extendsChanged); + debug("Interfaces removed: ", interfacesRemoved); + + myUpdated.affectSubclasses(it.name, myAffectedFiles, state.affectedUsages, state.dependants, + extendsChanged || interfacesRemoved || signatureChanged); + } + + if ((diff.addedModifiers() & Opcodes.ACC_INTERFACE) > 0 || (diff.removedModifiers() & Opcodes.ACC_INTERFACE) > 0) { + debug("Class-to-interface or interface-to-class conversion detected, added class usage to affected usages"); + state.affectedUsages.add(it.createUsage()); + } + + if (it.isAnnotation() && it.policy == RetentionPolicy.SOURCE) { + debug("Annotation, retention policy = SOURCE => a switch to non-incremental mode requested"); + if (!incrementalDecision(it.outerClassName, it, myAffectedFiles, myFilter)) { + debug("End of Differentiate, returning false"); + return false; + } + } + + if ((addedModifiers & Opcodes.ACC_PROTECTED) > 0) { + debug("Introduction of 'protected' modifier detected, adding class usage + inheritance constraint to affected usages"); + final UsageRepr.Usage usage = it.createUsage(); + + state.affectedUsages.add(usage); + state.usageConstraints.put(usage, myUpdated.new InheritanceConstraint(it.name)); + } + + if (diff.packageLocalOn()) { + debug("Introduction of 'package local' access detected, adding class usage + package constraint to affected usages"); + final UsageRepr.Usage usage = it.createUsage(); + + state.affectedUsages.add(usage); + state.usageConstraints.put(usage, myUpdated.new PackageConstraint(it.getPackageName())); + } + + if ((addedModifiers & Opcodes.ACC_FINAL) > 0 || (addedModifiers & Opcodes.ACC_PRIVATE) > 0) { + debug("Introduction of 'private' or 'final' modifier(s) detected, adding class usage to affected usages"); + state.affectedUsages.add(it.createUsage()); + } + + if ((addedModifiers & Opcodes.ACC_ABSTRACT) > 0 || (addedModifiers & Opcodes.ACC_STATIC) > 0) { + debug("Introduction of 'abstract' or 'static' modifier(s) detected, adding class new usage to affected usages"); + state.affectedUsages.add(UsageRepr.createClassNewUsage(myContext, it.name)); + } + + if (it.isAnnotation()) { + debug("Class is annotation, performing annotation-specific analysis"); + + if (diff.retentionChanged()) { + debug("Retention policy change detected, adding class usage to affected usages"); + state.affectedUsages.add(it.createUsage()); + } + else { + final Collection removedtargets = diff.targets().removed(); + + if (removedtargets.contains(ElemType.LOCAL_VARIABLE)) { + debug("Removed target contains LOCAL_VARIABLE => a switch to non-incremental mode requested"); + if (!incrementalDecision(it.outerClassName, it, myAffectedFiles, myFilter)) { + debug("End of Differentiate, returning false"); + return false; + } + } + + if (!removedtargets.isEmpty()) { + debug("Removed some annotation targets, adding annotation query"); + state.annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr + .createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), null, EnumSet.copyOf(removedtargets))); + } + + for (final MethodRepr m : diff.methods().added()) { + if (!m.hasValue()) { + debug("Added method with no default value: ", m.name); + debug("Adding class usage to affected usages"); + state.affectedUsages.add(it.createUsage()); + } + } + } + + debug("End of annotation-specific analysis"); + } + + processAddedMethods (state, diff, it); + processRemovedMethods (state, diff, it); + processChangedMethods (state, diff, it); + + if (!processAddedFields (state, diff, it)) { + return false; + } + + if (!processRemovedFields (state, diff, it)) { + return false; + } + + if (!processChangedFields (state, diff, it)) { + return false; + } + } + debug("End of changed classes processing"); + + return true; + } + + private void processRemovedClases(final DiffState state) { + debug("Processing removed classes:"); + for (final ClassRepr c : state.classDiff.removed()) { + myDelta.addDeletedClass(c); + mySelf.appendDependents(c, state.dependants); + debug("Adding usages of class ", c.name); + state.affectedUsages.add(c.createUsage()); + } + debug("End of removed classes processing."); + } + + private void processAddedClasses(final DiffState state) { + debug("Processing added classes:"); + for (final ClassRepr c : state.classDiff.added()) { + debug("Class name: ", c.name); + myDelta.addChangedClass(c.name); + + final TIntHashSet depClasses = myClassToClassDependency.get(c.name); + + if (depClasses != null) { + depClasses.forEach(new TIntProcedure() { + @Override + public boolean execute(int depClass) { + final int fName = myClassToSourceFile.get(depClass); + + if (fName > 0) { + final String f = myContext.getValue(fName); + final File theFile = new File(f); + + if (myFilter.accept(theFile)) { + debug("Adding dependent file ", f); + myAffectedFiles.add(theFile); + } + } + return true; + } + }); + } + } + debug("End of added classes processing."); + } + + private void calaulateAffectedFiles(final DiffState state) { + debug("Checking dependent files:"); + final TIntHashSet dependentFiles = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); + + state.dependants.forEach(new TIntProcedure() { + @Override + public boolean execute(int depClass) { + final int file = myClassToSourceFile.get(depClass); + if (file > 0) { + dependentFiles.add(file); + } + return true; + } + }); + + filewise: + for (final int depFile : dependentFiles.toArray()) { // todo: avoid toArray()? + final File theFile = new File(myContext.getValue(depFile)); + + if (myAffectedFiles.contains(theFile) || myCompiledFiles.contains(theFile)) { + continue filewise; + } + + debug("Dependent file: ", depFile); + final Collection depClusters = mySourceFileToUsages.get(depFile); + if (depClusters != null) { + for (final UsageRepr.Cluster depCluster : depClusters) { + final Set depUsages = depCluster.getUsages(); + if (depUsages == null) { + continue; + } + final Set usages = new HashSet(depUsages); + + usages.retainAll(state.affectedUsages); + + if (!usages.isEmpty()) { + for (UsageRepr.Usage usage : usages) { + final Util.UsageConstraint constraint = state.usageConstraints.get(usage); + + if (constraint == null) { + debug("Added file with no constraints"); + myAffectedFiles.add(theFile); + continue filewise; + } + else { + final TIntHashSet residenceClasses = depCluster.getResidence(usage); + for (final int residentName : residenceClasses.toArray()) { + if (constraint.checkResidence(residentName)) { + debug("Added file with satisfied constraint"); + myAffectedFiles.add(theFile); continue filewise; } } } } } + + if (state.annotationQuery.size() > 0) { + final Collection annotationUsages = mySourceFileToAnnotationUsages.get(depFile); + + for (final UsageRepr.Usage usage : annotationUsages) { + for (final UsageRepr.AnnotationUsage query : state.annotationQuery) { + if (query.satisfies(usage)) { + debug("Added file due to annotation query"); + myAffectedFiles.add(theFile); + continue filewise; + } + } + } + } } } } - - if (removed != null) { - for (final String r : removed) { - affectedFiles.remove(new File(r)); - } - } - - debug("End of Differentiate."); - return works.doWork(affectedFiles); } + + boolean differentiate() { + synchronized (myLock) { + + debug("Begin of Differentiate:"); + + processDisappearedClasses(); + + final List newClasses = new ArrayList(); + myDelta.mySourceFileToClasses.forEachEntry(new TIntObjectProcedure>() { + @Override + public boolean execute(int fileName, Collection classes) { + newClasses.add(new FileClasses(fileName, classes)); + return true; + } + }); + + for (final FileClasses compiledFile : newClasses) { + final int fileName = compiledFile.fileName; + final Set classes = compiledFile.fileClasses; + final Set pastClasses = (Set)mySourceFileToClasses.get(fileName); + final DiffState state = new DiffState(Difference.make(pastClasses, classes)); + + if (!processChangedClasses(state)) { + return false; + } + + processRemovedClases(state); + processAddedClasses(state); + + calaulateAffectedFiles(state); + } + + if (myRemoved != null) { + for (final String r : myRemoved) { + myAffectedFiles.remove(new File(r)); + } + } + + debug("End of Differentiate."); + return myDelayedWorks.doWork(myAffectedFiles); + } + } + } + + public boolean differentiate + (final Mappings delta, + final Collection removed, + final Collection filesToCompile, + final Collection compiledFiles, + final Collection affectedFiles, + final DependentFilesFilter filter, + @Nullable final Callbacks.ConstantAffectionResolver constantSearch) { + return new Differential(delta, removed, filesToCompile, compiledFiles, affectedFiles, filter, constantSearch).differentiate(); } private void cleanupBackDependency(final int className, @Nullable Collection clusters, IntIntMultiMaplet buffer) { diff --git a/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy b/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy index d40e9cc91e9b..92521fb12f09 100644 --- a/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy +++ b/jps/model/src/org/jetbrains/jps/idea/IdeaProjectLoader.groovy @@ -334,15 +334,17 @@ public class IdeaProjectLoader { def componentTag = getComponent(root, "Encoding"); if (componentTag == null) return; componentTag.file?.each {Node fileNode -> - def url = fileNode."@url"; - def charset = fileNode."@charset"; + String url = fileNode."@url"; + String charset = fileNode."@charset"; - if ("PROJECT".equals(url)) { - project.projectCharset = charset; - } - else { - def path = projectMacroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(url)); - project.filePathToCharset[path] = charset; + if (!StringUtil.isEmptyOrSpaces(charset)) { + if ("PROJECT".equals(url)) { + project.projectCharset = charset; + } + else { + def path = projectMacroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(url)); + project.filePathToCharset[FileUtil.toCanonicalPath(path)] = charset; + } } } } @@ -632,6 +634,12 @@ public class IdeaProjectLoader { case "JDK_1_5": return "1.5" case "JDK_1_6": return "1.6" case "JDK_1_7": return "1.7" + case "JDK_1_8": return "1.8" + } + + final String prefix = "JDK_"; + if (imlPropertyText != null && imlPropertyText.startsWith(prefix)) { + return imlPropertyText.substring(prefix.length()).replace('_', '.'); } return "1.6" diff --git a/platform/lang-api/src/com/intellij/execution/RunManager.java b/platform/lang-api/src/com/intellij/execution/RunManager.java index 4280e6b7c729..3f9522eb4c5f 100644 --- a/platform/lang-api/src/com/intellij/execution/RunManager.java +++ b/platform/lang-api/src/com/intellij/execution/RunManager.java @@ -18,6 +18,7 @@ package com.intellij.execution; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.ConfigurationType; import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RunProfile; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,7 +46,7 @@ public abstract class RunManager { public abstract boolean isTemporary(@NotNull RunConfiguration configuration); - public abstract void makeStable(@Nullable RunConfiguration configuration); + public abstract void makeStable(@NotNull RunConfiguration configuration); @Nullable public abstract RunnerAndConfigurationSettings getSelectedConfiguration(); @@ -58,4 +59,7 @@ public abstract class RunManager { @NotNull public abstract RunnerAndConfigurationSettings[] getConfigurationSettings(@NotNull ConfigurationType type); + + public abstract void refreshUsagesList(RunProfile profile); + } diff --git a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java index 8d8550e664cc..1605124ffcbf 100644 --- a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java +++ b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java @@ -75,6 +75,11 @@ public abstract class GenericProgramRunner return; } + RunnerSettings runnerSettings = env.getRunnerSettings(); + if (runnerSettings != null) { + RunManager.getInstance(project).refreshUsagesList(runnerSettings.getRunProfile()); + } + ExecutionManager.getInstance(project).startRunProfile(new RunProfileStarter() { @Override public RunContentDescriptor execute(@NotNull Project project, diff --git a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java index 331bcad134c2..a84bac7f454d 100644 --- a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java +++ b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java @@ -18,6 +18,7 @@ package com.intellij.ui.popup.util; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ColoredTreeCellRenderer; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -32,6 +33,8 @@ import javax.swing.*; public interface ItemWrapper { void setupRenderer(ColoredListCellRenderer renderer, Project project, boolean selected); + void setupRenderer(ColoredTreeCellRenderer renderer); + void updateAccessoryView(JComponent label); void execute(Project project, JBPopup popup); diff --git a/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java b/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java index 2f9e5f96c660..4c038b103861 100644 --- a/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java +++ b/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java @@ -18,6 +18,7 @@ package com.intellij.ui.popup.util; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ColoredTreeCellRenderer; import javax.swing.*; @@ -45,6 +46,11 @@ public class SplitterItem implements ItemWrapper { //To change body of implemented methods use File | Settings | File Templates. } + @Override + public void setupRenderer(ColoredTreeCellRenderer renderer) { + //To change body of implemented methods use File | Settings | File Templates. + } + @Override public void updateAccessoryView(JComponent label) { //To change body of implemented methods use File | Settings | File Templates. diff --git a/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form b/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form index 8d7004f7c8cf..e401e911e9a1 100644 --- a/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form +++ b/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form @@ -25,7 +25,7 @@ - + @@ -192,7 +192,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form index f97cce95948e..aab91296ed1b 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form @@ -30,7 +30,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -169,7 +169,7 @@ - + @@ -206,7 +206,7 @@ - + @@ -244,7 +244,7 @@ - + @@ -311,7 +311,7 @@ - + @@ -368,7 +368,7 @@ - + @@ -397,7 +397,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form index ee3f75552b04..4dc3d103cc51 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorSmartKeysConfigurable.form @@ -101,7 +101,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form index 37d06a9de2a2..4825e02f9db7 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form @@ -15,7 +15,7 @@ - + @@ -105,7 +105,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/ErrorHighlightingPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/ErrorHighlightingPanel.form index 945a063f7a3e..45db5b0cc407 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/ErrorHighlightingPanel.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/ErrorHighlightingPanel.form @@ -7,7 +7,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java index 5290bf1e5ee3..2df59cd5fa37 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import org.jetbrains.annotations.NotNull; @@ -38,7 +39,7 @@ public class PrefixMatchingWeigher extends CompletionWeigher { final NameUtil.MatchingCaseSensitivity sensitivity = setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE : setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL; - final NameUtil.MinusculeMatcher matcher = new NameUtil.MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity); + final MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity); int max = Integer.MIN_VALUE; for (String lookupString : item.getAllLookupStrings()) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/CodeCompletionGroup.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/CodeCompletionGroup.java index b4be2de99a73..15c2da2bbc25 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/CodeCompletionGroup.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/actions/CodeCompletionGroup.java @@ -47,4 +47,9 @@ public class CodeCompletionGroup extends DefaultActionGroup implements DumbAware presentation.setEnabled(true); } + + @Override + public boolean disableIfNoVisibleChildren() { + return false; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java index 32d11c7fa6ed..51cf80b83161 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingUpdate.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.CachedValueProvider; @@ -49,6 +50,7 @@ public class FoldingUpdate { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.FoldingUpdate"); private static final Key>> CODE_FOLDING_KEY = Key.create("code folding"); + private static final Key CODE_FOLDING_FILE_EXTENSION_KEY = Key.create("code folding file extension"); private static final Comparator COMPARE_BY_OFFSET = new Comparator() { public int compare(PsiElement element, PsiElement element1) { @@ -67,13 +69,30 @@ public class FoldingUpdate { final Project project = file.getProject(); final Document document = editor.getDocument(); LOG.assertTrue(!PsiDocumentManager.getInstance(project).isUncommited(document)); + + String currentFileExtension = null; + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null) { + currentFileExtension = virtualFile.getExtension(); + } ParameterizedCachedValue> value = editor.getUserData(CODE_FOLDING_KEY); + if (value != null) { + // There was a problem that old fold regions have been cached on file extension change (e.g. *.java -> *.groovy). + // We want to drop them in such circumstances. + final String oldExtension = editor.getUserData(CODE_FOLDING_FILE_EXTENSION_KEY); + if (oldExtension == null ? currentFileExtension != null : !oldExtension.equals(currentFileExtension)) { + value = null; + editor.putUserData(CODE_FOLDING_KEY, null); + } + } + editor.putUserData(CODE_FOLDING_FILE_EXTENSION_KEY, currentFileExtension); + if (value != null && value.hasUpToDateValue() && !applyDefaultState) return null; if (quick) return getUpdateResult(file, document, quick, project, editor, applyDefaultState).getValue(); - return CachedValuesManager.getManager(project).getParameterizedCachedValue(editor, CODE_FOLDING_KEY, - new ParameterizedCachedValueProvider>() { + return CachedValuesManager.getManager(project).getParameterizedCachedValue( + editor, CODE_FOLDING_KEY, new ParameterizedCachedValueProvider>() { public CachedValueProvider.Result compute(Pair param) { Document document = editor.getDocument(); PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java index 685db4510e68..37a1d3b89ef1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionActionWrapper.java @@ -32,6 +32,7 @@ public class IntentionActionWrapper implements IntentionAction { private IntentionAction myDelegate; private final String[] myCategories; private final IntentionActionBean myExtension; + private String myFullFamilyName; public IntentionActionWrapper(final IntentionActionBean extension, String[] categories) { myExtension = extension; @@ -60,13 +61,13 @@ public class IntentionActionWrapper implements IntentionAction { return getDelegate().startInWriteAction(); } + @NotNull public String getFullFamilyName(){ - if (myCategories != null) { - return StringUtil.join(myCategories, "/") + "/" + getFamilyName(); - } - else { - return getFamilyName(); + String result = myFullFamilyName; + if (result == null) { + myFullFamilyName = result = myCategories != null ? StringUtil.join(myCategories, "/") + "/" + getFamilyName() : getFamilyName(); } + return result; } public synchronized IntentionAction getDelegate() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java index 0a5e258a0c14..3e9b529ad131 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java @@ -24,6 +24,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.EditorFontType; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.ui.*; import com.intellij.ui.speedSearch.SpeedSearchUtil; @@ -255,7 +256,7 @@ public class LookupCellRenderer implements ListCellRenderer { final String prefix = myLookup.itemPattern(item); if (prefix.length() > 0) { - Iterable ranges = new NameUtil.MinusculeMatcher("*" + prefix, NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(name); + Iterable ranges = new MinusculeMatcher("*" + prefix, NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(name); if (ranges != null) { SimpleTextAttributes highlighted = new SimpleTextAttributes(style, selected ? SELECTED_PREFIX_FOREGROUND_COLOR : PREFIX_FOREGROUND_COLOR); diff --git a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java index 006f4060141b..68e4b437a954 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java @@ -186,9 +186,10 @@ public class RunConfigurationAction extends ComboBoxAction implements DumbAware public void actionPerformed(final AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - if (project != null) { + RunConfiguration configuration = chooseTempConfiguration(project); + if (project != null && configuration != null) { final RunManager runManager = RunManager.getInstance(project); - runManager.makeStable(chooseTempConfiguration(project)); + runManager.makeStable(configuration); } } diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java index 6a5d2cfd5c69..c0146befc912 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java +++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java @@ -23,8 +23,8 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.EmptyAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.command.undo.UndoConstants; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Document; @@ -225,16 +225,28 @@ public class ConsoleHistoryController { return myBrowseHistory; } - protected void setConsoleText(final String command, final boolean storeUserText, final boolean scrollToEnd) { + protected void setConsoleText(final String command, final boolean storeUserText, final boolean regularMode) { final Editor editor = myConsole.getCurrentEditor(); final Document document = editor.getDocument(); - new WriteCommandAction(myConsole.getProject(), myConsole.getFile()) { - protected void run(final Result result) throws Throwable { + new WriteCommandAction.Simple(myConsole.getProject()) { + @Override + public void run() { if (storeUserText) { myUserValue = document.getText(); } - document.setText(StringUtil.notNullize(command)); - editor.getCaretModel().moveToOffset(scrollToEnd? document.getTextLength() : 0); + if (regularMode) { + document.setText(StringUtil.notNullize(command)); + } + else { + try { + document.putUserData(UndoConstants.DONT_RECORD_UNDO, Boolean.TRUE); + document.setText(StringUtil.notNullize(command)); + } + finally { + document.putUserData(UndoConstants.DONT_RECORD_UNDO, null); + } + } + editor.getCaretModel().moveToOffset(regularMode? document.getTextLength() : 0); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } }.execute(); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java index 3ec35bfe5f28..ec3bcdb65793 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java @@ -112,7 +112,7 @@ public class ProjectRunConfigurationManager implements ProjectComponent, Persist } if (configuration != null) { - existing.add(RunManagerImpl.getUniqueName(configuration)); + existing.add(RunManagerImpl.getUniqueName(configuration.getConfiguration())); } } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java index 6f798533f6ff..1d20640a7930 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -54,10 +54,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.event.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; +import javax.swing.tree.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -518,7 +515,19 @@ class RunConfigurable extends BaseConfigurable { updateActiveConfigurationFromSelected(); final RunManagerImpl manager = getRunManager(); - final ConfigurationType[] configurationTypes = manager.getConfigurationFactories(); + final ConfigurationType[] types = manager.getConfigurationFactories(); + List configurationTypes = new ArrayList(); + for (int i = 0; i < myRoot.getChildCount(); i++) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)myRoot.getChildAt(i); + if (node.getUserObject() instanceof ConfigurationType) { + configurationTypes.add((ConfigurationType)node.getUserObject()); + } + } + for (ConfigurationType type : types) { + if (!configurationTypes.contains(type)) + configurationTypes.add(type); + } + for (ConfigurationType configurationType : configurationTypes) { applyByType(configurationType); } @@ -1092,6 +1101,23 @@ class RunConfigurable extends BaseConfigurable { final RunnerAndConfigurationSettings originalConfiguration = configurationConfigurable.getSettings(); if (getRunManager().isTemporary(originalConfiguration)) { getRunManager().makeStable(originalConfiguration.getConfiguration()); + final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)myTree.getSelectionPath().getLastPathComponent(); + MutableTreeNode parent = (MutableTreeNode)treeNode.getParent(); + int initialPosition = parent.getIndex(treeNode); + int position = parent.getIndex(treeNode); + DefaultMutableTreeNode node = treeNode.getPreviousSibling(); + while (node != null) { + RunnerAndConfigurationSettings settings = getSettings(node); + if (settings != null && settings.isTemporary()) { + position--; + } else { + break; + } + node = node.getPreviousSibling(); + } + for (int i = 0; i < initialPosition - position; i++) { + TreeUtil.moveSelectedRow(myTree, -1); + } } myTree.repaint(); } @@ -1139,20 +1165,20 @@ class RunConfigurable extends BaseConfigurable { } } } + } - @Nullable - private RunnerAndConfigurationSettings getSettings(DefaultMutableTreeNode treeNode) { - if (treeNode == null) - return null; - RunnerAndConfigurationSettings settings = null; - if (treeNode.getUserObject() instanceof SingleConfigurationConfigurable) { - settings = (RunnerAndConfigurationSettings)((SingleConfigurationConfigurable)treeNode.getUserObject()).getSettings(); - } - if (treeNode.getUserObject() instanceof RunnerAndConfigurationSettings) { - settings = (RunnerAndConfigurationSettings)treeNode.getUserObject(); - } - return settings; + @Nullable + private static RunnerAndConfigurationSettings getSettings(DefaultMutableTreeNode treeNode) { + if (treeNode == null) + return null; + RunnerAndConfigurationSettings settings = null; + if (treeNode.getUserObject() instanceof SingleConfigurationConfigurable) { + settings = (RunnerAndConfigurationSettings)((SingleConfigurationConfigurable)treeNode.getUserObject()).getSettings(); } + if (treeNode.getUserObject() instanceof RunnerAndConfigurationSettings) { + settings = (RunnerAndConfigurationSettings)treeNode.getUserObject(); + } + return settings; } private static class RunConfigurationBean { diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java index 6fbf4652024e..a476cef85d14 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java @@ -59,6 +59,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, @NonNls protected static final String CONFIGURATION = "configuration"; + protected static final String RECENT = "recent_temporary"; private ConfigurationType[] myTypes; private final RunManagerConfig myConfig; @NonNls @@ -70,6 +71,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, private List myUnknownElements = null; private JDOMExternalizableStringList myOrder = new JDOMExternalizableStringList(); + private final ArrayList myRecentlyUsedTemporaries = new ArrayList(); private boolean myOrdered = true; private final EventDispatcher myDispatcher = EventDispatcher.create(RunManagerListener.class); @@ -243,7 +245,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, List tasks, boolean addEnabledTemplateTasksIfAbsent) { final RunConfiguration configuration = settings.getConfiguration(); - Integer existingId = findConfigurationIdByUniqueName(getUniqueName(settings)); + Integer existingId = findConfigurationIdByUniqueName(getUniqueName(configuration)); Integer newId = configuration.getUniqueID(); RunnerAndConfigurationSettings existingSettings = null; @@ -252,14 +254,17 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, mySharedConfigurations.remove(existingId); } - if (mySelectedConfigurationId != null && mySelectedConfigurationId.equals(existingId)) setSelectedConfigurationId(newId); + if (mySelectedConfigurationId != null && mySelectedConfigurationId.equals(existingId)) { + setSelectedConfigurationId(newId); + } myConfigurations.put(newId, settings); + if (existingId == null) { + refreshUsagesList(configuration); + } checkRecentsLimit(); mySharedConfigurations.put(newId, shared); setBeforeRunTasks(configuration, tasks, addEnabledTemplateTasksIfAbsent); - saveOrder(); - myOrdered = false; if (existingSettings == settings) { myDispatcher.getMulticaster().runConfigurationChanged(settings); @@ -269,12 +274,23 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } } + @Override + public void refreshUsagesList(RunProfile profile) { + if (profile instanceof RunConfiguration && isTemporary((RunConfiguration)profile)) { + myRecentlyUsedTemporaries.remove((RunConfiguration)profile); + myRecentlyUsedTemporaries.add(0, (RunConfiguration)profile); + while(myRecentlyUsedTemporaries.size() > getConfig().getRecentsLimit()) { + myRecentlyUsedTemporaries.remove(myRecentlyUsedTemporaries.size() - 1); + } + } + } + void checkRecentsLimit() { List removed = new ArrayList(); while (getTempConfigurations().length > getConfig().getRecentsLimit()) { for (Iterator> it = myConfigurations.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = it.next(); - if (entry.getValue().isTemporary()) { + if (entry.getValue().isTemporary() && !myRecentlyUsedTemporaries.contains(entry.getValue().getConfiguration())) { removed.add(entry.getValue()); it.remove(); break; @@ -292,13 +308,12 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, myOrder.clear(); for (RunnerAndConfigurationSettings each : myConfigurations.values()) { if (each.getType() instanceof UnknownConfigurationType) continue; - myOrder.add(getUniqueName(each)); + myOrder.add(getUniqueName(each.getConfiguration())); } } - static String getUniqueName(@NotNull RunnerAndConfigurationSettings settings) { - RunConfiguration config = settings.getConfiguration(); - return config.getType().getDisplayName() + "." + settings.getName() + + static String getUniqueName(@NotNull RunConfiguration config) { + return config.getType().getDisplayName() + "." + config.getName() + (config instanceof UnknownRunConfiguration ? config.getUniqueID() : ""); } @@ -348,7 +363,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, List> order = new ArrayList>(myConfigurations.size()); for (RunnerAndConfigurationSettings each : myConfigurations.values()) { - order.add(Pair.create(getUniqueName(each), each)); + order.add(Pair.create(getUniqueName(each.getConfiguration()), each)); } myConfigurations.clear(); @@ -428,11 +443,20 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, //temp && stable configurations, !unknown for (RunnerAndConfigurationSettings each : myConfigurations.values()) { if (each.getType() instanceof UnknownConfigurationType) continue; - order.add(getUniqueName(each)); + order.add(getUniqueName(each.getConfiguration())); } order.writeExternal(parentNode); + final JDOMExternalizableStringList recentList = new JDOMExternalizableStringList(); + for (RunConfiguration each : myRecentlyUsedTemporaries) { + if (each.getType() instanceof UnknownConfigurationType) continue; + recentList.add(getUniqueName(each)); + } + final Element recent = new Element(RECENT); + parentNode.addContent(recent); + recentList.writeExternal(recent); + if (myUnknownElements != null) { for (Element unloadedElement : myUnknownElements) { parentNode.addContent((Element)unloadedElement.clone()); @@ -448,7 +472,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } RunnerAndConfigurationSettings selected = getSelectedConfiguration(); if (selected != null) { - parentNode.setAttribute(SELECTED_ATTR, getUniqueName(selected)); + parentNode.setAttribute(SELECTED_ATTR, getUniqueName(selected.getConfiguration())); } } @@ -533,6 +557,18 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } myOrder.readExternal(parentNode); + myRecentlyUsedTemporaries.clear(); + Element recentNode = parentNode.getChild(RECENT); + if (recentNode != null) { + JDOMExternalizableStringList list = new JDOMExternalizableStringList(); + list.readExternal(recentNode); + for (String name : list) { + Integer id = findConfigurationIdByUniqueName(name); + if (id != null) { + myRecentlyUsedTemporaries.add(myConfigurations.get(id).getConfiguration()); + } + } + } myOrdered = false; myLoadedSelectedConfigurationUniqueName = parentNode.getAttributeValue(SELECTED_ATTR); @@ -551,7 +587,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, if (myLoadedSelectedConfigurationUniqueName == null && config != null && Boolean.valueOf(element.getAttributeValue(SELECTED_ATTR)).booleanValue()) { - myLoadedSelectedConfigurationUniqueName = getUniqueName(config); + myLoadedSelectedConfigurationUniqueName = getUniqueName(config.getConfiguration()); } } @@ -564,7 +600,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, private Integer findConfigurationIdByUniqueName(@Nullable String selectedUniqueName) { if (selectedUniqueName != null) { for (RunnerAndConfigurationSettings each : myConfigurations.values()) { - if (selectedUniqueName.equals(getUniqueName(each))) { + if (selectedUniqueName.equals(getUniqueName(each.getConfiguration()))) { return each.getConfiguration().getUniqueID(); } } @@ -589,6 +625,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, mySelectedConfigurationId = null; myLoadedSelectedConfigurationUniqueName = null; myIdToIcon.clear(); + myRecentlyUsedTemporaries.clear(); fireRunConfigurationsRemoved(configurations); } @@ -728,11 +765,13 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return configurations.toArray(new RunConfiguration[configurations.size()]); } - public void makeStable(@Nullable RunConfiguration configuration) { + public void makeStable(@NotNull RunConfiguration configuration) { RunnerAndConfigurationSettings settings = getSettings(configuration); if (settings != null) { invalidateConfigurationIcon(settings); settings.setTemporary(false); + myRecentlyUsedTemporaries.remove(configuration); + setOrdered(false); fireRunConfigurationChanged(settings); } } @@ -926,11 +965,11 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, void removeNotExistingSharedConfigurations(final Set existing) { List removed = new ArrayList(); for (Iterator> it = myConfigurations.entrySet().iterator(); it.hasNext(); ) { - Map.Entry c = it.next(); - final RunnerAndConfigurationSettings o = c.getValue(); - if (!o.isTemplate() && isConfigurationShared(o) && !existing.contains(getUniqueName(o))) { - removed.add(o); - invalidateConfigurationIcon(o); + Map.Entry entry = it.next(); + final RunnerAndConfigurationSettings settings = entry.getValue(); + if (!settings.isTemplate() && isConfigurationShared(settings) && !existing.contains(getUniqueName(settings.getConfiguration()))) { + removed.add(settings); + invalidateConfigurationIcon(settings); it.remove(); } } @@ -938,13 +977,12 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } public void fireRunConfigurationChanged(@NotNull RunnerAndConfigurationSettings settings) { - myOrdered = false; invalidateConfigurationIcon(settings); myDispatcher.getMulticaster().runConfigurationChanged(settings); } private void fireRunConfigurationsRemoved(@NotNull List removed) { - myOrdered = false; + myRecentlyUsedTemporaries.removeAll(removed); for (RunnerAndConfigurationSettings settings : removed) { myDispatcher.getMulticaster().runConfigurationRemoved(settings); } diff --git a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java index 329cab1f1e7a..d166573bdb97 100644 --- a/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/AbstractBlockAlignmentProcessor.java @@ -15,7 +15,9 @@ */ package com.intellij.formatting; +import com.intellij.diagnostic.LogMessageEx; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.TextRange; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -85,12 +87,20 @@ public abstract class AbstractBlockAlignmentProcessor implements BlockAlignmentP // alignment of blocks located before them and post error every time we detect endless cycle. Set blocksCausedRealignment = context.backwardShiftedAlignedBlocks.get(offsetResponsibleBlock); if (blocksCausedRealignment != null && blocksCausedRealignment.contains(context.targetBlock)) { - LOG.error(String.format("Please create dedicated ticket at the tracker with the content of the current editor attached%n%n" - + "Formatting error - code block %s is set to be shifted right because of its alignment with " - + "block %s more than once. I.e. moving the former block because of alignment algorithm causes " - + "subsequent block to be shifted right as well - cyclic dependency.%nDebug info: %s", - offsetResponsibleBlock.getTextRange(), context.targetBlock.getTextRange(), context.targetBlock.getDebugInfo() - )); + StringBuilder messageBuilder = new StringBuilder(); + TextRange targetRange = context.targetBlock.getTextRange(); + messageBuilder.append( + String.format("Formatting error - code block %s is set to be shifted right because of its alignment with " + + "block %s more than once. I.e. moving the former block because of alignment algorithm causes " + + "subsequent block to be shifted right as well - cyclic dependency.", + offsetResponsibleBlock.getTextRange(), targetRange + )); + messageBuilder.append(context.targetBlock.getDebugInfo()); + messageBuilder.append("\nBlock content: '") + .append(context.document.getText().substring(targetRange.getStartOffset(), targetRange.getEndOffset())) + .append("'\n"); + messageBuilder.append("Note: document text is attached to this report."); + LogMessageEx.error(LOG, messageBuilder.toString(), context.document.getText()); blocksCausedRealignment.add(context.targetBlock); return Result.UNABLE_TO_ALIGN_BACKWARD_BLOCK; } diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java index 41c51522bf43..68151a1dfc01 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java @@ -28,6 +28,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.FileColorManager; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.popup.util.DetailView; @@ -89,6 +90,11 @@ public class BookmarkItem implements ItemWrapper { } } + @Override + public void setupRenderer(ColoredTreeCellRenderer renderer) { + //bookmarks tree view not supported + } + public void updateAccessoryView(JComponent component) { JLabel label = (JLabel)component; final char mnemonic = myBookmark.getMnemonic(); @@ -107,6 +113,7 @@ public class BookmarkItem implements ItemWrapper { public void execute(Project project, JBPopup popup) { popup.cancel(); myBookmark.navigate(); + popup.cancel(); } public String footerText() { diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java index 99d3c7be6b7e..3bdb5b8f8fe5 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java @@ -113,6 +113,11 @@ public class BookmarksAction extends AnAction implements DumbAware, MasterDetail return mnemonicLabel; } + @Override + public Object[] getSelectedItemsInTree() { + return new Object[0]; //To change body of implemented methods use File | Settings | File Templates. + } + private static DefaultListModel buildModel(Project project) { final DefaultListModel model = new DefaultListModel(); diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java index 4bf704ff34d6..886d5d758592 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java @@ -17,9 +17,9 @@ package com.intellij.ide.bookmarks.actions; import com.intellij.ide.bookmarks.Bookmark; import com.intellij.ide.bookmarks.BookmarkManager; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.ui.ListUtil; @@ -27,14 +27,7 @@ import com.intellij.ui.ListUtil; import javax.swing.*; import java.util.List; -/** -* Created with IntelliJ IDEA. -* User: zajac -* Date: 5/6/12 -* Time: 2:09 AM -* To change this template use File | Settings | File Templates. -*/ -class DeleteBookmarkAction extends AnAction { +class DeleteBookmarkAction extends DumbAwareAction { private final Project myProject; private final JList myList; diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java index 87203dd12c70..946f75ed666e 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java @@ -17,9 +17,9 @@ package com.intellij.ide.bookmarks.actions; import com.intellij.ide.bookmarks.Bookmark; import com.intellij.ide.bookmarks.BookmarkManager; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.InputValidator; import com.intellij.openapi.ui.Messages; @@ -29,14 +29,7 @@ import com.intellij.openapi.util.SystemInfo; import javax.swing.*; -/** -* Created with IntelliJ IDEA. -* User: zajac -* Date: 5/6/12 -* Time: 2:08 AM -* To change this template use File | Settings | File Templates. -*/ -class EditBookmarkDescriptionAction extends AnAction { +class EditBookmarkDescriptionAction extends DumbAwareAction { private final JList myList; private final Project myProject; private JBPopup myPopup; diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkDownAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkDownAction.java index fd43d4207c07..ea3c28cdac74 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkDownAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkDownAction.java @@ -17,9 +17,9 @@ package com.intellij.ide.bookmarks.actions; import com.intellij.ide.bookmarks.BookmarkItem; import com.intellij.ide.bookmarks.BookmarkManager; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.SystemInfo; @@ -27,14 +27,7 @@ import com.intellij.ui.ListUtil; import javax.swing.*; -/** -* Created with IntelliJ IDEA. -* User: zajac -* Date: 5/6/12 -* Time: 2:09 AM -* To change this template use File | Settings | File Templates. -*/ -class MoveBookmarkDownAction extends AnAction { +class MoveBookmarkDownAction extends DumbAwareAction { private final Project myProject; private final JList myList; diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkUpAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkUpAction.java index 16d86518bc11..72c09e7be5d3 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkUpAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MoveBookmarkUpAction.java @@ -16,9 +16,9 @@ package com.intellij.ide.bookmarks.actions; import com.intellij.ide.bookmarks.BookmarkManager; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.SystemInfo; @@ -26,14 +26,7 @@ import com.intellij.ui.ListUtil; import javax.swing.*; -/** -* Created with IntelliJ IDEA. -* User: zajac -* Date: 5/6/12 -* Time: 2:09 AM -* To change this template use File | Settings | File Templates. -*/ -class MoveBookmarkUpAction extends AnAction { +class MoveBookmarkUpAction extends DumbAwareAction { private final Project myProject; private final JList myList; diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 393fd5000bd5..c3839457750b 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -46,6 +46,7 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.psi.PsiElement; +import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.statistics.StatisticsInfo; import com.intellij.psi.statistics.StatisticsManager; @@ -1020,7 +1021,8 @@ public abstract class ChooseByNameBase { String text = EXTRA_ELEM.equals(modelElement) ? null : myModel.getFullName(modelElement); if (text != null) { String shortName = myModel.getElementName(modelElement); - int match = shortName != null && matcher instanceof NameUtil.MinusculeMatcher ? ((NameUtil.MinusculeMatcher)matcher).matchingDegree(shortName) : Integer.MIN_VALUE; + int match = shortName != null && matcher instanceof MinusculeMatcher + ? ((MinusculeMatcher)matcher).matchingDegree(shortName) : Integer.MIN_VALUE; int stats = StatisticsManager.getInstance().getUseCount(new StatisticsInfo(statContext, text)); if (stats > best || stats == best && match > bestMatch) { best = stats; diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java index 89bb47436d43..7fbc2a2fdbd4 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; +import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.util.proximity.PsiProximityComparator; import com.intellij.util.Function; @@ -147,10 +148,10 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider if (name == null) return false; final List suspects = split(name, base); - final List> patternsAndMatchers = - ContainerUtil.map2List(split(qualifierPattern, base), new Function>() { + final List> patternsAndMatchers = + ContainerUtil.map2List(split(qualifierPattern, base), new Function>() { @Override - public Pair fun(String s) { + public Pair fun(String s) { return Pair.create(getNamePattern(base, s), buildPatternMatcher(getNamePattern(base, s))); } }); @@ -159,9 +160,9 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider try { patterns: - for (Pair patternAndMatcher : patternsAndMatchers) { + for (Pair patternAndMatcher : patternsAndMatchers) { final String pattern = patternAndMatcher.first; - final NameUtil.MinusculeMatcher matcher = patternAndMatcher.second; + final MinusculeMatcher matcher = patternAndMatcher.second; if (!pattern.isEmpty()) { for (int j = matchPosition; j < suspects.size() - 1; j++) { String suspect = suspects.get(j); @@ -204,7 +205,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider pattern = pattern.substring(1); } - final NameUtil.MinusculeMatcher matcher = buildPatternMatcher(pattern); + final MinusculeMatcher matcher = buildPatternMatcher(pattern); try { for (String name : names) { @@ -221,7 +222,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider } } - private static boolean matches(ChooseByNameBase base, String pattern, NameUtil.MinusculeMatcher matcher, String name) { + private static boolean matches(ChooseByNameBase base, String pattern, MinusculeMatcher matcher, String name) { boolean matches = false; if (name != null) { if (base.getModel() instanceof CustomMatcherModel) { @@ -236,7 +237,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider return matches; } - private static NameUtil.MinusculeMatcher buildPatternMatcher(String pattern) { + private static MinusculeMatcher buildPatternMatcher(String pattern) { return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE); } diff --git a/platform/lang-impl/src/com/intellij/openapi/application/StructuralSearchPathMacroFilter.java b/platform/lang-impl/src/com/intellij/openapi/application/StructuralSearchPathMacroFilter.java new file mode 100644 index 000000000000..b42ba1701b31 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/application/StructuralSearchPathMacroFilter.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.application; + +import org.jdom.Attribute; + +/** + * Since SSR inspections can be stored in inspection profiles and loaded by users who don't have the SSR plugin installed, unfortunately + * this must be in the platform and not in the SSR plugin. + * + * @author yole + */ +public class StructuralSearchPathMacroFilter extends PathMacroFilter { + @Override + public boolean skipPathMacros(Attribute attribute) { + final String parentName = attribute.getParent().getName(); + if ("replaceConfiguration".equals(parentName) || "searchConfiguration".equals(parentName)) { + return true; + } + return false; + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java index 5f61f7424598..f0a0d05163b1 100644 --- a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java +++ b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java @@ -103,7 +103,7 @@ public class CodeAnalysisBeforeCheckinHandler extends CheckinHandler { commitButtonText = commitButtonText.substring(0, commitButtonText.length()-3); } - final int answer = Messages.showYesNoCancelDialog( + final int answer = Messages.showYesNoCancelDialog(myProject, VcsBundle.message("before.commit.files.contain.code.smells.edit.them.confirm.text", errorCount, warningCount), VcsBundle.message("code.smells.error.messages.tab.name"), VcsBundle.message("code.smells.review.button"), commitButtonText, CommonBundle.getCancelButtonText(), UIUtil.getWarningIcon()); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java index 0e8c66a904ea..c52befbdd650 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java @@ -378,7 +378,7 @@ public class FileReferenceSet { } @NotNull - private static Collection getAbsoluteTopLevelDirLocations(final @NotNull PsiFile file) { + public static Collection getAbsoluteTopLevelDirLocations(final @NotNull PsiFile file) { final VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/actions/RenameElementAction.java b/platform/lang-impl/src/com/intellij/refactoring/actions/RenameElementAction.java index 426aa4863f53..51046716b486 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/actions/RenameElementAction.java +++ b/platform/lang-impl/src/com/intellij/refactoring/actions/RenameElementAction.java @@ -18,7 +18,9 @@ package com.intellij.refactoring.actions; import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.SyntheticElement; import com.intellij.refactoring.RefactoringActionHandler; @@ -57,4 +59,9 @@ public class RenameElementAction extends BaseRefactoringAction { protected boolean isAvailableForLanguage(Language language) { return true; } + + @Override + protected boolean isAvailableOnElementInEditorAndFile(PsiElement element, Editor editor, PsiFile file, DataContext context) { + return getHandler(context) != null; + } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java index 7717f3513a0a..e9af5ca2164a 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/CallerChooserBase.java @@ -148,7 +148,7 @@ public abstract class CallerChooserBase extends DialogWrap }); final M caller = node.getMethod(); - final M callee = parentNode != null ? parentNode.getMethod() : null; + final PsiElement callee = parentNode != null ? parentNode.getElementToSearch() : null; if (caller != null && caller.isPhysical() && callee != null) { HighlightManager highlighter = HighlightManager.getInstance(myProject); EditorColorsManager colorManager = EditorColorsManager.getInstance(); @@ -161,7 +161,7 @@ public abstract class CallerChooserBase extends DialogWrap } } - protected Collection findElementsToHighlight(M caller, M callee) { + protected Collection findElementsToHighlight(M caller, PsiElement callee) { Query references = ReferencesSearch.search(callee, new LocalSearchScope(caller), false); return ContainerUtil.mapNotNull(references, new Function() { @Override diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodNodeBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodNodeBase.java index 6b51236c1ef1..f4a1faa80bb9 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodNodeBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/MethodNodeBase.java @@ -115,4 +115,9 @@ public abstract class MethodNodeBase extends CheckedTreeNo public M getMethod() { return myMethod; } + + public PsiElement getElementToSearch() { + return getMethod(); + } + } diff --git a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java index 7dc8e6b4238a..92ce9a481739 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/safeDelete/SafeDeleteHandler.java @@ -129,8 +129,10 @@ public class SafeDeleteHandler implements RefactoringActionHandler { }; - SafeDeleteDialog dialog = new SafeDeleteDialog(project, elementsToDelete, callback); - dialog.show(); + if (elementsToDelete.length > 0) { + SafeDeleteDialog dialog = new SafeDeleteDialog(project, elementsToDelete, callback); + dialog.show(); + } } } } diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java index 269c38ca500b..b230f482cad1 100644 --- a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java @@ -17,6 +17,7 @@ package com.intellij.ui.popup.util; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; @@ -51,6 +52,12 @@ public class DetailViewImpl extends JPanel implements DetailView { private JLabel myNothingToShowInEditor = new JLabel("Nothing to show"); private RangeHighlighter myHighlighter; + public void setScheme(EditorColorsScheme scheme) { + myScheme = scheme; + } + + private EditorColorsScheme myScheme = EditorColorsManager.getInstance().getGlobalScheme(); + public DetailViewImpl(Project project) { super(new BorderLayout()); myProject = project; @@ -112,10 +119,13 @@ public class DetailViewImpl extends JPanel implements DetailView { clearEditor(); remove(myNothingToShowInEditor); setEditor(EditorFactory.getInstance().createViewer(document, project)); - EditorHighlighter highlighter = EditorHighlighterFactory.getInstance() - .createEditorHighlighter(file, EditorColorsManager.getInstance().getGlobalScheme(), project); - ((EditorEx)getEditor()).setHighlighter(highlighter); + + final EditorColorsScheme scheme = getScheme(); + + EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(file, scheme, project); + ((EditorEx)getEditor()).setFile(file); + ((EditorEx)getEditor()).setHighlighter(highlighter); getEditor().getSettings().setAnimatedScrolling(false); getEditor().getSettings().setRefrainFromScrolling(false); @@ -145,6 +155,12 @@ public class DetailViewImpl extends JPanel implements DetailView { } } + public EditorColorsScheme getScheme() { + return myScheme; + } + + + private void clearHightlighting() { if (myHighlighter != null) { getEditor().getMarkupModel().removeHighlighter(myHighlighter); diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java index 4df48c798aa1..257197ead096 100644 --- a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java +++ b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java @@ -15,14 +15,12 @@ */ package com.intellij.ui.popup.util; -import com.intellij.ide.bookmarks.BookmarkItem; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.PopupChooserBuilder; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.Gray; @@ -37,6 +35,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -54,10 +54,21 @@ public class MasterDetailPopupBuilder { private static final Color BORDER_COLOR = Gray._135; private Project myProject; private ActionGroup myActions; - private JBList myList; private Delegate myDelegate; private boolean myCloseOnEnter; + public DetailViewImpl getDetailView() { + return myDetailView; + } + + private DetailViewImpl myDetailView; + private JLabel myPathLabel; + private JBPopup myPopup; + private Alarm myUpdateAlarm; + + + private JComponent myChooserComponent; + public ActionToolbar getActionToolbar() { return myActionToolbar; } @@ -69,114 +80,49 @@ public class MasterDetailPopupBuilder { myProject = project; } + private String getTitle2Text(String fullText) { + int labelWidth = myPathLabel.getWidth(); + if (fullText == null || fullText.length() == 0) return " "; + while (myPathLabel.getFontMetrics(myPathLabel.getFont()).stringWidth(fullText) > labelWidth) { + int sep = fullText.indexOf(File.separatorChar, 4); + if (sep < 0) return fullText; + fullText = "..." + fullText.substring(sep); + } + + return fullText; + } + + private void doUpdateDetailView() { + final Object[] values = getSelectedItems(); + ItemWrapper wrapper = null; + if (values != null && values.length == 1) { + wrapper = (ItemWrapper)values[0]; + myPathLabel.setText(getTitle2Text(wrapper.footerText())); + } + else { + myPathLabel.setText(" "); + } + final ItemWrapper wrapper1 = wrapper; + myUpdateAlarm.cancelAllRequests(); + myUpdateAlarm.addRequest(new Runnable() { + public void run() { + myDetailView.updateWithItem(wrapper1); + } + }, 100); + } public JBPopup createMasterDetailPopup() { - final JLabel pathLabel = new JLabel(" "); - pathLabel.setHorizontalAlignment(SwingConstants.RIGHT); - final Font font = pathLabel.getFont(); - pathLabel.setFont(font.deriveFont((float)10)); + setupRenderer(); - final Alarm updateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); - final DetailViewImpl detailView = new DetailViewImpl(myProject); + myPathLabel = new JLabel(" "); + myPathLabel.setHorizontalAlignment(SwingConstants.RIGHT); - myList.setCellRenderer(new ItemRenderer(myDelegate, myProject)); + final Font font = myPathLabel.getFont(); + myPathLabel.setFont(font.deriveFont((float)10)); - final ListSelectionModel selectionModel = myList.getSelectionModel(); - selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - final boolean directionUp[] = new boolean[1]; - - selectionModel.addListSelectionListener(new ListSelectionListener() { - private String getTitle2Text(String fullText) { - int labelWidth = pathLabel.getWidth(); - if (fullText == null || fullText.length() == 0) return " "; - while (pathLabel.getFontMetrics(pathLabel.getFont()).stringWidth(fullText) > labelWidth) { - int sep = fullText.indexOf(File.separatorChar, 4); - if (sep < 0) return fullText; - fullText = "..." + fullText.substring(sep); - } - - return fullText; - } - - public void valueChanged(final ListSelectionEvent e) { - //noinspection SSBasedInspection - SwingUtilities.invokeLater(new Runnable() { - public void run() { - updatePathLabel(); - } - }); - } - - private void updatePreviewPanel(final ItemWrapper wrapper) { - updateAlarm.cancelAllRequests(); - updateAlarm.addRequest(new Runnable() { - public void run() { - detailView.updateWithItem(wrapper); - } - }, 100); - } - - private void updatePathLabel() { - final Object[] values = myList.getSelectedValues(); - ItemWrapper wrapper = null; - if (values != null && values.length == 1) { - wrapper = (ItemWrapper)values[0]; - if (wrapper instanceof SplitterItem) { - if (!directionUp[0]) { - final int index = myList.getSelectedIndex(); - if (myList.getItemsCount() >= index + 1) { - myList.setSelectedIndex(index + 1); - } - else { - myList.setSelectedIndex(0); - } - } - else { - final int index = myList.getSelectedIndex(); - if (index - 1 > 0) { - myList.setSelectedIndex(index - 1); - } - else { - myList.setSelectedIndex(myList.getItemsCount() - 1); - } - } - } - pathLabel.setText(getTitle2Text(wrapper.footerText())); - } - else { - pathLabel.setText(" "); - } - updatePreviewPanel(wrapper); - } - }); - final Ref popupRef = Ref.create(null); - - Runnable runnable = new Runnable() { - public void run() { - IdeFocusManager.getInstance(myProject).doWhenFocusSettlesDown(new Runnable() { - public void run() { - Object[] values = myList.getSelectedValues(); - - if (values.length == 1) { - ((ItemWrapper)values[0]).execute(myProject, popupRef.get()); - } - else { - for (Object value : values) { - if (value instanceof BookmarkItem) { - ((ItemWrapper)value).execute(myProject, popupRef.get()); - } - } - } - } - }); - } - }; - - if (myList.getModel().getSize() == 0) { - myList.clearSelection(); - } + myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + myDetailView = new DetailViewImpl(myProject); JPanel footerPanel = new JPanel(new BorderLayout()) { @Override @@ -187,8 +133,30 @@ public class MasterDetailPopupBuilder { } }; + + Runnable runnable = new Runnable() { + public void run() { + IdeFocusManager.getInstance(myProject).doWhenFocusSettlesDown(new Runnable() { + public void run() { + Object[] values = getSelectedItems(); + + if (values.length == 1) { + ((ItemWrapper)values[0]).execute(myProject, myPopup); + } + else { + for (Object value : values) { + if (value instanceof ItemWrapper) { + ((ItemWrapper)value).execute(myProject, myPopup); + } + } + } + } + }); + } + }; + footerPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); - footerPanel.add(pathLabel); + footerPanel.add(myPathLabel); myActionToolbar = ActionManager.getInstance().createActionToolbar("", myActions, true); myActionToolbar.setReservePlaceAutoPopupIcon(false); @@ -196,14 +164,15 @@ public class MasterDetailPopupBuilder { final JComponent toolBar = myActionToolbar.getComponent(); toolBar.setOpaque(false); - final JBPopup popup = new PopupChooserBuilder(myList). + final PopupChooserBuilder builder = createInnerBuilder(); + myPopup = builder. setTitle(myDelegate.getTitle()). setMovable(true). setResizable(true). setAutoselectOnMouseMove(false). setSettingButton(toolBar). setSouthComponent(footerPanel). - setEastComponent(detailView). + setEastComponent(myDetailView). setItemChoosenCallback(runnable). setCloseOnEnter(myCloseOnEnter). setMayBeParent(true). @@ -213,29 +182,46 @@ public class MasterDetailPopupBuilder { return ((ItemWrapper)o).speedSearchText(); } }).createPopup(); - - popupRef.set(popup); - - myList.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_DELETE) { - removeSelectedItems(MasterDetailPopupBuilder.this.myList, MasterDetailPopupBuilder.this.myProject); - } - else if (e.getKeyCode() == KeyEvent.VK_UP) { - directionUp[0] = true; - } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { - directionUp[0] = false; - } - else if (e.getModifiersEx() == 0) { - myDelegate.handleMnemonic(e, myProject, popup); - } - } - }); - return popup; + return myPopup; } - public static boolean allowedToRemoveSelectedItem(JBList list, Project project) { - Object[] values = list.getSelectedValues(); + private void setupRenderer() { + if (myChooserComponent instanceof JList) { + final JList list = (JList)myChooserComponent; + list.setCellRenderer(new ListItemRenderer(myDelegate, myProject)); + } + } + + private PopupChooserBuilder createInnerBuilder() { + if (myChooserComponent instanceof JList) { + return new PopupChooserBuilder((JList)myChooserComponent); + } + else if (myChooserComponent instanceof JTree) { + return new PopupChooserBuilder((JTree)myChooserComponent); + } + return null; + } + + public Object[] getSelectedItems() { + if (myChooserComponent instanceof JList) { + return ((JList)myChooserComponent).getSelectedValues(); + } + else if (myChooserComponent instanceof JTree) { + return myDelegate.getSelectedItemsInTree(); + } + return new Object[0]; + } + + private void updateDetailViewLater() { + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + public void run() { + doUpdateDetailView(); + } + }); + } + + public static boolean allowedToRemoveItems(Object[] values) { for (Object value : values) { ItemWrapper item = (ItemWrapper)value; if (!item.allowedToRemove()) { @@ -245,33 +231,42 @@ public class MasterDetailPopupBuilder { return values.length > 0; } - public static void removeSelectedItems(JBList list, Project project) { - int index = list.getSelectedIndex(); - if (index == -1 || index >= list.getModel().getSize()) { - return; + public void removeSelectedItems(Project project) { + if (myChooserComponent instanceof JList) { + final JList list = (JList)myChooserComponent; + int index = list.getSelectedIndex(); + if (index == -1 || index >= list.getModel().getSize()) { + return; + } + Object[] values = list.getSelectedValues(); + for (Object value : values) { + ItemWrapper item = (ItemWrapper)value; + + DefaultListModel model = list.getModel() instanceof DefaultListModel + ? (DefaultListModel)list.getModel() + : (DefaultListModel)((FilteringListModel)list.getModel()).getOriginalModel(); + if (item.allowedToRemove()) { + model.removeElement(item); + + if (model.getSize() > 0) { + if (model.getSize() == index) { + list.setSelectedIndex(model.getSize() - 1); + } + else if (model.getSize() > index) { + list.setSelectedIndex(index); + } + } + else { + list.clearSelection(); + } + item.removed(project); + } + } } - Object[] values = list.getSelectedValues(); - for (Object value : values) { - ItemWrapper item = (ItemWrapper)value; - - DefaultListModel model = list.getModel() instanceof DefaultListModel - ? (DefaultListModel)list.getModel() - : (DefaultListModel)((FilteringListModel)list.getModel()).getOriginalModel(); - if (item.allowedToRemove()) { - model.removeElement(item); - - if (model.getSize() > 0) { - if (model.getSize() == index) { - list.setSelectedIndex(model.getSize() - 1); - } - else if (model.getSize() > index) { - list.setSelectedIndex(index); - } - } - else { - list.clearSelection(); - } - item.removed(project); + else { + final Object[] items = getSelectedItems(); + for (Object item : items) { + ((ItemWrapper)item).removed(project); } } } @@ -281,11 +276,51 @@ public class MasterDetailPopupBuilder { return this; } - public MasterDetailPopupBuilder setList(JBList list) { - myList = list; + public MasterDetailPopupBuilder setTree(final JTree tree) { + setChooser(tree); + + tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + @Override + public void valueChanged(TreeSelectionEvent event) { + updateDetailViewLater(); + } + }); + return this; } + public MasterDetailPopupBuilder setList(final JBList list) { + setChooser(list); + final ListSelectionModel listSelectionModel = list.getSelectionModel(); + listSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + listSelectionModel.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(final ListSelectionEvent e) { + updateDetailViewLater(); + } + }); + + + if (list.getModel().getSize() == 0) { + list.clearSelection(); + } + return this; + } + + private void setChooser(JComponent list) { + myChooserComponent = list; + list.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_DELETE) { + removeSelectedItems(myProject); + } + else if (e.getModifiersEx() == 0) { + myDelegate.handleMnemonic(e, myProject, myPopup); + } + } + }); + } + public MasterDetailPopupBuilder setDelegate(Delegate delegate) { myDelegate = delegate; return this; @@ -303,14 +338,16 @@ public class MasterDetailPopupBuilder { @Nullable JComponent createAccessoryView(Project project); + + Object[] getSelectedItemsInTree(); } - public static class ItemRenderer extends JPanel implements ListCellRenderer { + public static class ListItemRenderer extends JPanel implements ListCellRenderer { private final Project myProject; private final ColoredListCellRenderer myRenderer; private Delegate myDelegate; - private ItemRenderer(Delegate delegate, Project project) { + private ListItemRenderer(Delegate delegate, Project project) { super(new BorderLayout()); myProject = project; setBackground(UIUtil.getListBackground()); diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionGroup.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionGroup.java index bfc4375287c2..df23e12b780f 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionGroup.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionGroup.java @@ -188,4 +188,8 @@ public abstract class ActionGroup extends AnAction { public boolean hideIfNoVisibleChildren() { return false; } + + public boolean disableIfNoVisibleChildren() { + return true; + } } diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java index 96fe2949971e..e80150193419 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,9 +44,12 @@ public class EditorModificationUtil { int selectionStart = selectionModel.getSelectionStart(); int selectionEnd = selectionModel.getSelectionEnd(); - editor.getCaretModel().moveToOffset(selectionStart); + final CaretModel caretModel = editor.getCaretModel(); + final VisualPosition position = caretModel.getVisualPosition(); + caretModel.moveToOffset(selectionStart); selectionModel.removeSelection(); editor.getDocument().deleteString(selectionStart, selectionEnd); + caretModel.moveToVisualPosition(position); // Try to preserve visual caret position editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } diff --git a/platform/platform-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java b/platform/platform-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java index b6ea12c0257f..05fa2cd09b82 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/markup/AttributesFlyweight.java @@ -29,7 +29,55 @@ import java.awt.*; public class AttributesFlyweight { private final int myHashCode; - private static final StripedLockConcurrentHashMap entries = new StripedLockConcurrentHashMap(); + private static final StripedLockConcurrentHashMap entries = new StripedLockConcurrentHashMap(); + private static final ThreadLocal ourKey = new ThreadLocal(); + + private static class FlyweightKey implements Cloneable { + Color foreground; + Color background; + @JdkConstants.FontStyle int fontType; + Color effectColor; + EffectType effectType; + Color errorStripeColor; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof FlyweightKey)) return false; + + FlyweightKey key = (FlyweightKey)o; + + if (fontType != key.fontType) return false; + if (background != null ? !background.equals(key.background) : key.background != null) return false; + if (effectColor != null ? !effectColor.equals(key.effectColor) : key.effectColor != null) return false; + if (effectType != key.effectType) return false; + if (errorStripeColor != null ? !errorStripeColor.equals(key.errorStripeColor) : key.errorStripeColor != null) return false; + if (foreground != null ? !foreground.equals(key.foreground) : key.foreground != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = foreground != null ? foreground.hashCode() : 0; + result = 31 * result + (background != null ? background.hashCode() : 0); + result = 31 * result + fontType; + result = 31 * result + (effectColor != null ? effectColor.hashCode() : 0); + result = 31 * result + (effectType != null ? effectType.hashCode() : 0); + result = 31 * result + (errorStripeColor != null ? errorStripeColor.hashCode() : 0); + return result; + } + + @Override + protected FlyweightKey clone() { + try { + return (FlyweightKey)super.clone(); + } + catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + } @NotNull public static AttributesFlyweight create(Color foreground, @@ -38,8 +86,23 @@ public class AttributesFlyweight { Color effectColor, EffectType effectType, Color errorStripeColor) { - AttributesFlyweight key = new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor); - return ConcurrencyUtil.cacheOrGet(entries, key, key); + FlyweightKey key = ourKey.get(); + if (key == null) { + ourKey.set(key = new FlyweightKey()); + } + key.foreground = foreground; + key.background = background; + key.fontType = fontType; + key.effectColor = effectColor; + key.effectType = effectType; + key.errorStripeColor = errorStripeColor; + + AttributesFlyweight flyweight = entries.get(key); + if (flyweight != null) { + return flyweight; + } + + return ConcurrencyUtil.cacheOrGet(entries, key.clone(), new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor)); } private final Color myForeground; diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java index 367957385950..839eea53bd76 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java @@ -716,7 +716,7 @@ public class Messages { } /** - * Shows dialog with given message and title, infomation icon {@link #getInformationIcon()} and OK button + * Shows dialog with given message and title, information icon {@link #getInformationIcon()} and OK button */ public static void showInfoMessage(Component component, String message, String title) { if (canShowMacSheetPanel()) { @@ -728,7 +728,7 @@ public class Messages { } /** - * Shows dialog with given message and title, infomation icon {@link #getInformationIcon()} and OK button + * Shows dialog with given message and title, information icon {@link #getInformationIcon()} and OK button */ public static void showInfoMessage(Project project, @Nls String message, @Nls String title) { if (canShowMacSheetPanel()) { @@ -740,7 +740,7 @@ public class Messages { } /** - * Shows dialog with given message and title, infomation icon {@link #getInformationIcon()} and OK button + * Shows dialog with given message and title, information icon {@link #getInformationIcon()} and OK button */ public static void showInfoMessage(String message, String title) { if (canShowMacSheetPanel()) { diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java index 3345439bed79..1d7ddf517976 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java @@ -202,16 +202,9 @@ public class PopupChooserBuilder { } - final JList finalList = list; (list != null ? list : myChooserComponent).addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { - - final Point onScreen = e.getLocationOnScreen(); - SwingUtilities.convertPointFromScreen(onScreen, finalList); - - final int index = finalList.locationToIndex(onScreen); - if (finalList.getSelectedIndex() != index) return; if (UIUtil.isActionClick(e, MouseEvent.MOUSE_RELEASED) && !UIUtil.isSelectionButtonDown(e) && !e.isConsumed()) { if (myCloseOnEnter) { closePopup(true, e, true); diff --git a/platform/platform-api/src/com/intellij/ui/IdeBorderFactory.java b/platform/platform-api/src/com/intellij/ui/IdeBorderFactory.java index 0cd38d327e79..e3a7c78f7ead 100644 --- a/platform/platform-api/src/com/intellij/ui/IdeBorderFactory.java +++ b/platform/platform-api/src/com/intellij/ui/IdeBorderFactory.java @@ -122,96 +122,6 @@ public class IdeBorderFactory { } } - @Deprecated - public static class BoldSmallWithIndent { - private BoldSmallWithIndent() { - } - - public static TitledBorder createTitledBorder(Border border, - String title, - int titleJustification, - int titlePosition, - Font titleFont, - Color titleColor) { - return IdeBorderFactory.createTitledBorder(title, true); - } - } - - @Deprecated - public static class BoldSmallWithoutIndent { - private BoldSmallWithoutIndent() { - } - - public static TitledBorder createTitledBorder(Border border, - String title, - int titleJustification, - int titlePosition, - Font titleFont, - Color titleColor) { - return IdeBorderFactory.createTitledBorder(title, false); - } - } - - @Deprecated - public static class PlainLargeWithIndent { - private PlainLargeWithIndent() { - } - - public static TitledBorder createTitledBorder(Border border, - String title, - int titleJustification, - int titlePosition, - Font titleFont, - Color titleColor) { - return IdeBorderFactory.createTitledBorder(title, true); - } - } - - @Deprecated - public static class PlainLargeWithoutIndent { - private PlainLargeWithoutIndent() { - } - - public static TitledBorder createTitledBorder(Border border, - String title, - int titleJustification, - int titlePosition, - Font titleFont, - Color titleColor) { - return IdeBorderFactory.createTitledBorder(title, false); - } - } - - @Deprecated - public static class BoldLargeWithIndent { - private BoldLargeWithIndent() { - } - - public static TitledBorder createTitledBorder(Border border, - String title, - int titleJustification, - int titlePosition, - Font titleFont, - Color titleColor) { - return IdeBorderFactory.createTitledBorder(title, true); - } - } - - @Deprecated - public static class BoldLargeWithoutIndent { - private BoldLargeWithoutIndent() { - } - - public static TitledBorder createTitledBorder(Border border, - String title, - int titleJustification, - int titlePosition, - Font titleFont, - Color titleColor) { - return IdeBorderFactory.createTitledBorder(title, false); - } - } - public static class PlainSmallWithoutIndentWithoutInsets { private PlainSmallWithoutIndentWithoutInsets() { } diff --git a/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java index 8a8a53528fa3..87fbe17a5258 100644 --- a/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java +++ b/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java @@ -105,7 +105,11 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan } public static ToolbarDecorator createDecorator(@NotNull JTree tree) { - return new TreeToolbarDecorator(tree).initPosition(); + return createDecorator(tree, null); + } + + private static ToolbarDecorator createDecorator(@Nullable JTree tree, @Nullable ElementProducer producer) { + return new TreeToolbarDecorator(tree, producer).initPosition(); } public static ToolbarDecorator createDecorator(@NotNull JList list) { diff --git a/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java index 79d1a3af4621..4b10c2e0d0e8 100644 --- a/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java +++ b/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,90 @@ package com.intellij.ui; import com.intellij.openapi.actionSystem.ActionToolbarPosition; import com.intellij.openapi.util.SystemInfo; +import com.intellij.ui.treeStructure.SimpleNode; +import com.intellij.util.ui.EditableTreeModel; +import com.intellij.util.ui.ElementProducer; +import com.intellij.util.ui.tree.TreeUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; /** * @author Konstantin Bulenkov */ class TreeToolbarDecorator extends ToolbarDecorator { private final JTree myTree; + @Nullable private final ElementProducer myProducer; - TreeToolbarDecorator(JTree tree) { + TreeToolbarDecorator(JTree tree, @Nullable final ElementProducer producer) { myTree = tree; + myProducer = producer; + myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = myTree.getModel() instanceof EditableTreeModel; + if (myTree.getModel() instanceof EditableTreeModel) { + createDefaultTreeActions(); + } + myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + @Override + public void valueChanged(TreeSelectionEvent e) { + updateButtons(); + } + }); + myTree.addPropertyChangeListener("enabled", new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateButtons(); + } + }); + } + + private void createDefaultTreeActions() { + final EditableTreeModel model = (EditableTreeModel)myTree.getModel(); + myAddAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + final TreePath path = myTree.getSelectionPath(); + final DefaultMutableTreeNode selected = + path == null ? (DefaultMutableTreeNode)myTree.getModel().getRoot() : (DefaultMutableTreeNode)path.getLastPathComponent(); + final Object selectedNode = selected.getUserObject(); + + myTree.stopEditing(); + Object element; + if (model instanceof DefaultTreeModel && myProducer != null) { + element = myProducer.createElement(); + if (element == null) return; + } else { + element = null; + } + DefaultMutableTreeNode parent = selected; + if ((selectedNode instanceof SimpleNode && ((SimpleNode)selectedNode).isAlwaysLeaf()) || !selected.getAllowsChildren()) { + parent = (DefaultMutableTreeNode)selected.getParent(); + } + if (parent != null) { + parent.insert(new DefaultMutableTreeNode(element), parent.getChildCount()); + } + final TreePath createdPath = model.addNode(new TreePath(parent.getPath())); + if (path != null) { + TreeUtil.selectPath(myTree, createdPath); + myTree.requestFocus(); + } + } + }; + + myRemoveAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + myTree.stopEditing(); + final TreePath path = myTree.getSelectionPath(); + model.removeNode(path); + } + }; } @Override @@ -42,6 +115,7 @@ class TreeToolbarDecorator extends ToolbarDecorator { @Override protected void updateButtons() { + getPanel().setEnabled(CommonActionsPanel.Buttons.REMOVE, myTree.getSelectionPath() != null); } @Override diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchUtil.java b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchUtil.java index b75cd5db6fa3..8e3f0f5ba13e 100644 --- a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchUtil.java +++ b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearchUtil.java @@ -18,7 +18,7 @@ package com.intellij.ui.speedSearch; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.registry.Registry; -import com.intellij.psi.codeStyle.NameUtil; +import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.Processor; @@ -65,12 +65,12 @@ public final class SpeedSearchUtil { final Matcher matcher, final Color selectedBg, final boolean selected) { - if (!(matcher instanceof NameUtil.MinusculeMatcher) || (Registry.is("ide.highlight.match.in.selected.only") && !selected)) { + if (!(matcher instanceof MinusculeMatcher) || (Registry.is("ide.highlight.match.in.selected.only") && !selected)) { component.append(text, attributes); return; } - final Iterable iterable = ((NameUtil.MinusculeMatcher)matcher).matchingFragments(text); + final Iterable iterable = ((MinusculeMatcher)matcher).matchingFragments(text); if (iterable != null) { final Color fg = attributes.getFgColor(); final int style = attributes.getStyle(); diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index 2f67b1bfefe8..342f8578e0e1 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -320,6 +320,17 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } } + @Override + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + if (orientation == SwingConstants.VERTICAL) { + return super.getScrollableUnitIncrement(visibleRect, orientation, direction); + } + else { // if orientation == SwingConstants.HORIZONTAL + // use smooth editor-like scrolling + return SwingUtilities.computeStringWidth(getFontMetrics(getFont()), " "); + } + } + @Override public void doLayout() { super.doLayout(); diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java index 06e05fc8e15d..5333bfb89c50 100644 --- a/platform/platform-api/src/com/intellij/ui/table/TableView.java +++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java @@ -93,8 +93,7 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel int[] sizeMode = new int[columns.length]; int[] headers = new int[columns.length]; int[] widths = new int[columns.length]; - int fixedWidth = 0; - int varWidth = 0; + int allColumnWidth = 0; int varCount = 0; // calculate @@ -132,18 +131,18 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel widths[i] = getFontMetrics(getFont()).stringWidth(preferredValue) + columnInfo.getAdditionalWidth(); varCount ++; } - if (sizeMode[i] == 0) { - fixedWidth += widths[i]; - } - else { - varWidth += widths[i]; - } + allColumnWidth += widths[i]; } - // apply: distribute available space between resizable columns but no more than *4 times. + // apply: distribute available space between resizable columns // and make sure that header will fit as well int viewWidth = getParent() != null? getParent().getWidth() : getWidth(); - int addendum = varCount > 0 && viewWidth > fixedWidth + varWidth? (viewWidth - fixedWidth - varWidth) / varCount : 0; + double gold = 0.5 * (3 - Math.sqrt(5)); + int addendum = varCount == 0 || viewWidth < allColumnWidth ? + 0 : (int)((allColumnWidth < gold * viewWidth ? gold * viewWidth : + allColumnWidth < (1 - gold) * viewWidth ? (1 - gold) * viewWidth : + viewWidth) - allColumnWidth) / varCount; + for (int i=0 ; i extends BaseTableView implements ItemsProvider, Sel column.setMinWidth(width); } else if (sizeMode[i] == 2) { - width = Math.max(width + Math.min(addendum, 4 * width), headers[i]); + width = Math.max(width + addendum, headers[i]); column.setPreferredWidth(width); column.setMaxWidth(width); } else if (sizeMode[i] == 3) { - width = Math.max(width + Math.min(addendum, 4 * width), headers[i]); + width = Math.max(width + addendum, headers[i]); column.setPreferredWidth(width); } } diff --git a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java index 2dbed1f359d8..a6cde49c8888 100644 --- a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java +++ b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java @@ -20,9 +20,7 @@ import com.intellij.ui.GuiUtils; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; +import java.awt.event.*; import java.lang.reflect.InvocationTargetException; /** @@ -93,6 +91,14 @@ public class IOExceptionDialog extends JDialog { setLocation((parentSize.width - ownSize.width) / 2, (parentSize.height - ownSize.height) / 2); pack(); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + cancelPressed = true; + dispose(); + } + }); } /** diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form index 6b0859da2c19..c5f3697acb11 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form +++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form @@ -15,7 +15,7 @@ - + diff --git a/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java b/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java index 02c97564511f..10ddca58f138 100644 --- a/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java +++ b/platform/platform-impl/src/com/intellij/execution/impl/EditorHyperlinkSupport.java @@ -338,7 +338,7 @@ public class EditorHyperlinkSupport { action.consume(next); linkFollowed(editor, ranges, next); } - }, i, ranges.size()); + }, newIndex == -1 ? -1 : newIndex + 1, ranges.size()); } // todo fix link followed here! diff --git a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form index 3bef6a650100..cc46649dc81a 100644 --- a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form +++ b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsPanel.form @@ -20,7 +20,7 @@ - + @@ -66,7 +66,7 @@ - + diff --git a/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java b/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java index 6104f9e28042..c72131529adf 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java @@ -25,7 +25,6 @@ import com.intellij.openapi.components.StorageScheme; import com.intellij.openapi.components.impl.stores.IProjectStore; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectCoreUtil; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.project.ex.ProjectManagerEx; diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeOptionsPanel.form b/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeOptionsPanel.form index ebdab1d41adf..070432d8084e 100644 --- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeOptionsPanel.form +++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/config/PasswordSafeOptionsPanel.form @@ -53,7 +53,7 @@ - + diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java index fa4d1ff12f99..f25fb7c91d2b 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java @@ -30,7 +30,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Dictionary; @@ -318,7 +317,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab private JLabel myFontNameLabel; private JPanel myTransparencyPanel; private JCheckBox myOverrideLAFFonts; - private JLabel myIDEALafFont; private JCheckBox myHideIconsInQuickNavigation; private JCheckBox myCbDisplayIconsInMenu; @@ -328,24 +326,15 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab private JCheckBox myAllowMergeButtons; public MyComponent() { - ActionListener updater = new ActionListener() { + myOverrideLAFFonts.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { updateCombo(); } - }; - myLafComboBox.addActionListener(updater); - myOverrideLAFFonts.addActionListener(updater); - myIDEALafFont.setPreferredSize(new Dimension(myIDEALafFont.getPreferredSize().width, myOverrideLAFFonts.getPreferredSize().height)); + }); } public void updateCombo() { - UIManager.LookAndFeelInfo selectedLAF = (UIManager.LookAndFeelInfo)myLafComboBox.getSelectedItem(); - //noinspection HardCodedStringLiteral - boolean isIdeaLAFSelected = selectedLAF != null && selectedLAF.getName().startsWith("IDEA"); - - myIDEALafFont.setVisible(isIdeaLAFSelected); - myOverrideLAFFonts.setVisible(!isIdeaLAFSelected); - boolean enableChooser = isIdeaLAFSelected || myOverrideLAFFonts.isSelected(); + boolean enableChooser = myOverrideLAFFonts.isSelected(); myFontCombo.setEnabled(enableChooser); myFontSizeCombo.setEnabled(enableChooser); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form index 062d2941c78e..dd3335cf37dc 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form @@ -23,7 +23,7 @@ - + @@ -134,7 +134,7 @@ - + @@ -142,17 +142,9 @@ - - - - - - - - - + @@ -186,7 +178,7 @@ - + @@ -242,7 +234,7 @@ - + diff --git a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java index c9cbf027ea33..626d4f9a66ea 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/LafManagerImpl.java @@ -433,7 +433,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo patchFileChooserStrings(uiDefaults); if (shouldPatchLAFFonts()) { storeOriginalFontDefaults(uiDefaults); - initFontDefaults(uiDefaults); + initFontDefaults(uiDefaults, myUiSettings.FONT_FACE, myUiSettings.FONT_SIZE); } else { restoreOriginalFontDefaults(uiDefaults); @@ -576,9 +576,8 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo } } - private boolean shouldPatchLAFFonts() { - //noinspection HardCodedStringLiteral - return getCurrentLookAndFeel().getName().startsWith("IDEA") || UISettings.getInstance().OVERRIDE_NONIDEA_LAF_FONTS; + private static boolean shouldPatchLAFFonts() { + return UISettings.getInstance().OVERRIDE_NONIDEA_LAF_FONTS; } private static void updateUI(Window window){ @@ -657,13 +656,11 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo } @SuppressWarnings({"HardCodedStringLiteral"}) - private void initFontDefaults(UIDefaults defaults) { + private static void initFontDefaults(UIDefaults defaults, String fontFace, int fontSize) { defaults.put("Tree.ancestorInputMap", null); - int uiFontSize = myUiSettings.FONT_SIZE; - String uiFontFace = myUiSettings.FONT_FACE; - FontUIResource uiFont = new FontUIResource(uiFontFace, Font.PLAIN, uiFontSize); - FontUIResource textFont = new FontUIResource("Serif", Font.PLAIN, uiFontSize); - FontUIResource monoFont = new FontUIResource("Monospaced", Font.PLAIN, uiFontSize); + FontUIResource uiFont = new FontUIResource(fontFace, Font.PLAIN, fontSize); + FontUIResource textFont = new FontUIResource("Serif", Font.PLAIN, fontSize); + FontUIResource monoFont = new FontUIResource("Monospaced", Font.PLAIN, fontSize); for (String fontResource : ourPatchableFontResources) { defaults.put(fontResource, uiFont); @@ -673,7 +670,6 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo defaults.put("TextArea.font", monoFont); defaults.put("TextPane.font", textFont); defaults.put("EditorPane.font", textFont); - defaults.put("TitledBorder.font", uiFont); } @@ -692,10 +688,11 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo } private static final class IdeaLaf extends MetalLookAndFeel{ - protected void initComponentDefaults(UIDefaults table) { - super.initComponentDefaults(table); - initInputMapDefaults(table); - initIdeaDefaults(table); + protected void initComponentDefaults(UIDefaults defaults) { + super.initComponentDefaults(defaults); + initInputMapDefaults(defaults); + initIdeaDefaults(defaults); + initFontDefaults(defaults, "Tahoma", 11); } @SuppressWarnings({"HardCodedStringLiteral"}) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java index 9d6da6f8d442..00ef9f89ad09 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -93,6 +93,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { private final DefaultActionGroup mySecondaryActions = new DefaultActionGroup(); private boolean myMinimalMode; + private boolean myForceUseMacEnhancements; public ActionButton getSecondaryActionsButton() { return mySecondaryActionsButton; @@ -164,7 +165,11 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { } private boolean doMacEnhancementsForMainToolbar() { - return (UIUtil.isUnderAquaLookAndFeel() && ActionPlaces.MAIN_TOOLBAR.equals(myPlace)); + return (UIUtil.isUnderAquaLookAndFeel() && (ActionPlaces.MAIN_TOOLBAR.equals(myPlace) || myForceUseMacEnhancements)); + } + + public void setForceUseMacEnhancements(boolean useMacEnhancements) { + myForceUseMacEnhancements = useMacEnhancements; } private boolean isInsideNavBar() { diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java index 056870f32628..0927854b75dd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java @@ -130,14 +130,14 @@ public class Utils{ if (child instanceof ActionGroup) { ActionGroup actionGroup = (ActionGroup)child; if (actionGroup.isPopup()) { // popup menu has its own presentation - // disable group if it contains no visible actions - final boolean visibleChildren = hasVisibleChildren(actionGroup, presentationFactory, context, place); - if (actionGroup.hideIfNoVisibleChildren() && !visibleChildren) { - continue; - } - if (!actionGroup.canBePerformed(context) && !visibleChildren) { - presentation.setEnabled(false); + if (actionGroup.disableIfNoVisibleChildren()) { + final boolean visibleChildren = hasVisibleChildren(actionGroup, presentationFactory, context, place); + if (actionGroup.hideIfNoVisibleChildren() && !visibleChildren) { + continue; + } + presentation.setEnabled(actionGroup.canBePerformed(context) || visibleChildren); } + list.add(child); } else { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index 3fdad4b2474e..a1a767ba6567 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -75,15 +75,21 @@ public class EditorActionUtil { * Tries to change given editor's viewport position in vertical dimension by the given number of visual lines. * * @param editor target editor which viewport position should be changed - * @param lineShift defines viewport position's change length + * @param lineShift defines viewport position's vertical change length + * @param columnShift defines viewport position's horizontal change length * @param moveCaret flag that identifies whether caret should be moved if its current position becomes off-screen */ - public static void scrollRelatively(Editor editor, int lineShift, boolean moveCaret) { + public static void scrollRelatively(Editor editor, int lineShift, int columnShift, boolean moveCaret) { if (lineShift != 0) { editor.getScrollingModel().scrollVertically( editor.getScrollingModel().getVerticalScrollOffset() + lineShift * editor.getLineHeight() ); } + if (columnShift != 0) { + editor.getScrollingModel().scrollHorizontally( + editor.getScrollingModel().getHorizontalScrollOffset() + columnShift * EditorUtil.getSpaceWidth(Font.PLAIN, editor) + ); + } if (!moveCaret) { return; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java index 80990c251578..45062c0ae04c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAction.java @@ -36,7 +36,7 @@ public class ScrollDownAction extends InactiveEditorAction { private static class Handler extends EditorActionHandler { @Override public void execute(Editor editor, DataContext dataContext) { - EditorActionUtil.scrollRelatively(editor, 1, false); + EditorActionUtil.scrollRelatively(editor, 1, 0, false); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java index 29bbedfba770..2d88af5a525c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollDownAndMoveAction.java @@ -34,7 +34,7 @@ public class ScrollDownAndMoveAction extends InactiveEditorAction { private static class Handler extends EditorActionHandler { @Override public void execute(Editor editor, DataContext dataContext) { - EditorActionUtil.scrollRelatively(editor, 1, true); + EditorActionUtil.scrollRelatively(editor, 1, 0, true); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollLeftAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollLeftAction.java new file mode 100644 index 000000000000..26aaf3129a5e --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollLeftAction.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +/** + * @author Denis Zhdanov + * @since 5/25/12 9:26 AM + */ +public class ScrollLeftAction extends InactiveEditorAction { + public ScrollLeftAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + @Override + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.scrollRelatively(editor, 0, -1, false); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollRightAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollRightAction.java new file mode 100644 index 000000000000..d417688026c3 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollRightAction.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor.actions; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; + +/** + * @author Denis Zhdanov + * @since 5/25/12 9:25 AM + */ +public class ScrollRightAction extends InactiveEditorAction { + + public ScrollRightAction() { + super(new Handler()); + } + + private static class Handler extends EditorActionHandler { + @Override + public void execute(Editor editor, DataContext dataContext) { + EditorActionUtil.scrollRelatively(editor, 0, 1, false); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java index f2214cdfaf1f..96e6c2faed8d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAction.java @@ -36,7 +36,7 @@ public class ScrollUpAction extends InactiveEditorAction { private static class Handler extends EditorActionHandler { @Override public void execute(Editor editor, DataContext dataContext) { - EditorActionUtil.scrollRelatively(editor, -1, false); + EditorActionUtil.scrollRelatively(editor, -1, 0, false); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java index 919e121323dd..a6ed71a61bb8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ScrollUpAndMoveAction.java @@ -34,7 +34,7 @@ public class ScrollUpAndMoveAction extends InactiveEditorAction { private static class Handler extends EditorActionHandler { @Override public void execute(Editor editor, DataContext dataContext) { - EditorActionUtil.scrollRelatively(editor, -1, true); + EditorActionUtil.scrollRelatively(editor, -1, 0, true); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java index 1adb4f46851e..7a772e7aed34 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.impl.FloatingDecorator; import com.intellij.openapi.wm.impl.IdeFrameImpl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -86,7 +87,8 @@ public final class RequestFocusInEditorComponentCmd extends FinalizableCommand{ return; } - if (owner instanceof IdeFrameImpl && IdeFrameImpl.getActiveFrame() != owner) { + final Window activeFrame = IdeFrameImpl.getActiveFrame(); + if (activeFrame != null && owner instanceof IdeFrameImpl && activeFrame != owner) { myDoneCallback.setRejected(); return; } @@ -97,7 +99,7 @@ public final class RequestFocusInEditorComponentCmd extends FinalizableCommand{ // if owner is active window or it has active child window which isn't floating decorator then // don't bring owner window to font. If we will make toFront every time then it's possible // the following situation: - // 1. user prform refactoring + // 1. user perform refactoring // 2. "Do not show preview" dialog is popping up. // 3. At that time "preview" tool window is being activated and modal "don't show..." dialog // isn't active. @@ -124,14 +126,15 @@ public final class RequestFocusInEditorComponentCmd extends FinalizableCommand{ * @return first active window from hierarchy with specified roots. Returns null * if there is no active window in the hierarchy. */ - private Window getActiveWindow(final Window[] windows){ - for(int i=0;i + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index ae9e603f5e7c..37d3ab3a7f40 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -61,6 +61,8 @@ + + diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/FileListeningTest.java b/platform/platform-tests/testSrc/com/intellij/history/integration/FileListeningTest.java index f5cbf86aac8a..2d65ec17ac8f 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/FileListeningTest.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/FileListeningTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ public class FileListeningTest extends IntegrationTestCase { LocalFileSystem.getInstance().refresh(false); List changes = getVcs().getChangeListInTests().getChangesInTests().get(0).getChanges(); - assertEquals(4, changes.size()); + assertEquals(changes.toString(), 4, changes.size()); List actual = new SmartList(); for (Change each : changes) { actual.add(((StructuralChange)each).getPath()); @@ -100,7 +100,7 @@ public class FileListeningTest extends IntegrationTestCase { VirtualFile f = createFile("file.txt"); assertEquals(2, getRevisionsFor(f).size()); - f.rename(null, "file2.txt"); + f.rename(this, "file2.txt"); assertEquals(3, getRevisionsFor(f).size()); } @@ -125,7 +125,7 @@ public class FileListeningTest extends IntegrationTestCase { addFileListenerDuring(l, new RunnableAdapter() { @Override public void doRun() throws IOException { - f.rename(null, "new.txt"); + f.rename(this, "new.txt"); } }); @@ -139,7 +139,7 @@ public class FileListeningTest extends IntegrationTestCase { VirtualFile f = createFile("file.hprof"); assertEquals(before, getRevisionsFor(myRoot).size()); - f.rename(null, "file.txt"); + f.rename(this, "file.txt"); assertEquals(before + 1, getRevisionsFor(myRoot).size()); assertEquals(2, getRevisionsFor(f).size()); @@ -151,7 +151,7 @@ public class FileListeningTest extends IntegrationTestCase { VirtualFile f = createFile("file.txt"); assertEquals(before + 1, getRevisionsFor(myRoot).size()); - f.rename(null, "file.hprof"); + f.rename(this, "file.hprof"); assertEquals(before + 2, getRevisionsFor(myRoot).size()); } @@ -161,7 +161,7 @@ public class FileListeningTest extends IntegrationTestCase { VirtualFile f = createFile(FILTERED_DIR_NAME); assertEquals(before, getRevisionsFor(myRoot).size()); - f.rename(null, "not_filtered"); + f.rename(this, "not_filtered"); assertEquals(before + 1, getRevisionsFor(myRoot).size()); assertEquals(2, getRevisionsFor(f).size()); @@ -173,7 +173,7 @@ public class FileListeningTest extends IntegrationTestCase { VirtualFile f = createDirectory("not_filtered"); assertEquals(before + 1, getRevisionsFor(myRoot).size()); - f.rename(null, FILTERED_DIR_NAME); + f.rename(this, FILTERED_DIR_NAME); assertEquals(before + 2, getRevisionsFor(myRoot).size()); } @@ -188,7 +188,7 @@ public class FileListeningTest extends IntegrationTestCase { assertEquals(4, getRevisionsFor(f).size()); } - public void testIgnoringROStstusChangeForUnversionedFiles() throws Exception { + public void testIgnoringROStatusChangeForUnversionedFiles() throws Exception { int before = getRevisionsFor(myRoot).size(); VirtualFile f = createFile("f.hprof"); @@ -202,7 +202,7 @@ public class FileListeningTest extends IntegrationTestCase { int before = getRevisionsFor(myRoot).size(); - f.delete(null); + f.delete(this); assertEquals(before + 1, getRevisionsFor(myRoot).size()); } @@ -210,24 +210,26 @@ public class FileListeningTest extends IntegrationTestCase { int before = getRevisionsFor(myRoot).size(); VirtualFile f = createDirectory(FILTERED_DIR_NAME); - f.delete(null); + f.delete(this); assertEquals(before, getRevisionsFor(myRoot).size()); } public void testDeletionDoesNotVersionIgnoredFilesRecursively() throws Exception { String dir1 = createDirectoryExternally("dir"); - String f1 = createFileExternally("dir/f.txt"); + createFileExternally("dir/f.txt"); createFileExternally("dir/f.class"); createFileExternally("dir/subdir/f.txt"); - String dir2 = createDirectoryExternally("dir/subdir/subdir2"); - String f2 = createFileExternally("dir/subdir/subdir2/f.txt"); + createDirectoryExternally("dir/subdir/subdir2"); + createFileExternally("dir/subdir/subdir2/f.txt"); LocalFileSystem.getInstance().refresh(false); addExcludedDir(myRoot.getPath() + "/dir/subdir"); addContentRoot(myRoot.getPath() + "/dir/subdir/subdir2"); - LocalFileSystem.getInstance().findFileByPath(dir1).delete(this); + final VirtualFile vDir1 = LocalFileSystem.getInstance().findFileByPath(dir1); + assertNotNull(dir1, vDir1); + vDir1.delete(this); List changes = getVcs().getChangeListInTests().getChangesInTests().get(0).getChanges(); assertEquals(1, changes.size()); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java index 6b4342aeadb0..bf71ec861559 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceOnDocumentModificationTest.java @@ -980,6 +980,21 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorP assertEquals(text, myEditor.getSelectionModel().getSelectedText()); } + public void testCaretPositionAfterLineRemoval() throws IOException { + final String text = + "123456\n" + + "123456\n" + + "line towrapbecauseitislong\n" + + "923456"; + init(8, text); + final CaretModel caretModel = myEditor.getCaretModel(); + caretModel.moveToOffset(text.indexOf("e")); + final VisualPosition position = caretModel.getVisualPosition(); + deleteLine(); + assertEquals(text.substring(0, text.indexOf("line")) + text.substring(text.indexOf('9')), myEditor.getDocument().getText()); + assertEquals(position, caretModel.getVisualPosition()); + } + private void init(final int visibleWidthInColumns, @NotNull String fileText) throws IOException { int symbolWidthInPixels = 7; init(visibleWidthInColumns * symbolWidthInPixels, fileText, symbolWidthInPixels); diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java index 72ac2b2fccac..c2a329e9dcae 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java @@ -20,6 +20,7 @@ package com.intellij.psi.util; import com.intellij.openapi.util.TextRange; +import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.UsefulTestCase; @@ -312,57 +313,57 @@ public class NameUtilTest extends UsefulTestCase { } public void testMinusculeFirstLetter() { - assertTrue(new NameUtil.MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic")); - assertFalse(new NameUtil.MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic")); - assertTrue(new NameUtil.MinusculeMatcher("cL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("class")); - assertTrue(new NameUtil.MinusculeMatcher("CL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("Class")); - assertFalse(new NameUtil.MinusculeMatcher("abc", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("_abc")); + assertTrue(new MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic")); + assertFalse(new MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic")); + assertTrue(new MinusculeMatcher("cL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("class")); + assertTrue(new MinusculeMatcher("CL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("Class")); + assertFalse(new MinusculeMatcher("abc", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("_abc")); } public void testMinusculeAllImportant() { - assertTrue(new NameUtil.MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); - assertFalse(new NameUtil.MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")); - assertFalse(new NameUtil.MinusculeMatcher("FOO", NameUtil.MatchingCaseSensitivity.ALL).matches("foo")); - assertFalse(new NameUtil.MinusculeMatcher("foo", NameUtil.MatchingCaseSensitivity.ALL).matches("fOO")); - assertFalse(new NameUtil.MinusculeMatcher("Wl", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); - assertTrue(new NameUtil.MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); - assertFalse(new NameUtil.MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("Weblogic")); - assertFalse(new NameUtil.MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")); - assertFalse(new NameUtil.MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); - assertFalse(new NameUtil.MinusculeMatcher("Str", NameUtil.MatchingCaseSensitivity.ALL).matches("SomeThingRidiculous")); + assertTrue(new MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); + assertFalse(new MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")); + assertFalse(new MinusculeMatcher("FOO", NameUtil.MatchingCaseSensitivity.ALL).matches("foo")); + assertFalse(new MinusculeMatcher("foo", NameUtil.MatchingCaseSensitivity.ALL).matches("fOO")); + assertFalse(new MinusculeMatcher("Wl", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); + assertTrue(new MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); + assertFalse(new MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("Weblogic")); + assertFalse(new MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic")); + assertFalse(new MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic")); + assertFalse(new MinusculeMatcher("Str", NameUtil.MatchingCaseSensitivity.ALL).matches("SomeThingRidiculous")); } public void testMatchingFragments() { @NonNls String sample = "NoClassDefFoundException"; // 0 2 7 10 15 21 - assertOrderedEquals(new NameUtil.MinusculeMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + assertOrderedEquals(new MinusculeMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 1), TextRange.from(2, 2), TextRange.from(7, 1), TextRange.from(10, 3), TextRange.from(21, 3)); sample = "doGet(HttpServletRequest, HttpServletResponse):void"; // 0 22 - assertOrderedEquals(new NameUtil.MinusculeMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + assertOrderedEquals(new MinusculeMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 1), TextRange.from(22, 2)); - assertOrderedEquals(new NameUtil.MinusculeMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + assertOrderedEquals(new MinusculeMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 4), TextRange.from(22, 2)); sample = "_test"; - assertOrderedEquals(new NameUtil.MinusculeMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + assertOrderedEquals(new MinusculeMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 1)); - assertOrderedEquals(new NameUtil.MinusculeMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + assertOrderedEquals(new MinusculeMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 2)); } public void testMatchingFragmentsSorted() { @NonNls String sample = "SWUPGRADEHDLRFSPR7TEST"; // 0 9 12 - assertOrderedEquals(new NameUtil.MinusculeMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + assertOrderedEquals(new MinusculeMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 3), TextRange.from(9, 1), TextRange.from(12, 1)); } public void testPreferCapsMatching() { String sample = "getCurrentUser"; // 0 4 10 - assertOrderedEquals(new NameUtil.MinusculeMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + assertOrderedEquals(new MinusculeMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 4), TextRange.from(10, 1)); } @@ -390,7 +391,7 @@ public class NameUtilTest extends UsefulTestCase { } public void testMeaningfulMatchingDegree() { - assertTrue(new NameUtil.MinusculeMatcher(" EUC-", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matchingDegree("x-EUC-TW") > Integer.MIN_VALUE); + assertTrue(new MinusculeMatcher(" EUC-", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matchingDegree("x-EUC-TW") > Integer.MIN_VALUE); } private static void assertPreference(@NonNls String pattern, @@ -403,7 +404,7 @@ public class NameUtilTest extends UsefulTestCase { @NonNls String less, @NonNls String more, NameUtil.MatchingCaseSensitivity sensitivity) { - NameUtil.MinusculeMatcher matcher = new NameUtil.MinusculeMatcher(pattern, sensitivity); + MinusculeMatcher matcher = new MinusculeMatcher(pattern, sensitivity); int iLess = matcher.matchingDegree(less); int iMore = matcher.matchingDegree(more); assertTrue(iLess + ">=" + iMore + "; " + less + ">=" + more, iLess < iMore); @@ -411,24 +412,24 @@ public class NameUtilTest extends UsefulTestCase { public void testPerformance() { @NonNls final String longName = "ThisIsAQuiteLongNameWithParentheses().Dots.-Minuses-_UNDERSCORES_digits239:colons:/slashes\\AndOfCourseManyLetters"; - final List matching = new ArrayList(); - final List nonMatching = new ArrayList(); + final List matching = new ArrayList(); + final List nonMatching = new ArrayList(); for (String s : CollectionFactory.ar("*", "*i", "*a", "*u", "T", "ti", longName, longName.substring(0, 20))) { - matching.add(new NameUtil.MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE)); + matching.add(new MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE)); } for (String s : CollectionFactory.ar("A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "ta")) { - nonMatching.add(new NameUtil.MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE)); + nonMatching.add(new MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE)); } - PlatformTestUtil.startPerformanceTest("Matcher is slow", 1200, new ThrowableRunnable() { + PlatformTestUtil.startPerformanceTest("Matcher is slow", 1700, new ThrowableRunnable() { @Override public void run() { for (int i = 0; i < 100000; i++) { - for (NameUtil.MinusculeMatcher matcher : matching) { + for (MinusculeMatcher matcher : matching) { assertTrue(matcher.matches(longName)); } - for (NameUtil.MinusculeMatcher matcher : nonMatching) { + for (MinusculeMatcher matcher : nonMatching) { assertFalse(matcher.matches(longName)); } } diff --git a/platform/platform-api/src/com/intellij/ide/highlighter/ModuleFileType.java b/platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java similarity index 100% rename from platform/platform-api/src/com/intellij/ide/highlighter/ModuleFileType.java rename to platform/projectModel-api/src/com/intellij/ide/highlighter/ModuleFileType.java diff --git a/platform/platform-api/src/com/intellij/ide/highlighter/ProjectFileType.java b/platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java similarity index 100% rename from platform/platform-api/src/com/intellij/ide/highlighter/ProjectFileType.java rename to platform/projectModel-api/src/com/intellij/ide/highlighter/ProjectFileType.java diff --git a/platform/projectModel-impl/projectModel-impl.iml b/platform/projectModel-impl/projectModel-impl.iml index a90adbfb0c15..78efe1a27d4f 100644 --- a/platform/projectModel-impl/projectModel-impl.iml +++ b/platform/projectModel-impl/projectModel-impl.iml @@ -10,7 +10,6 @@ - diff --git a/platform/testFramework/src/com/intellij/mock/MockRunManager.java b/platform/testFramework/src/com/intellij/mock/MockRunManager.java index 450d8b68ba4f..ff465a3d13cb 100644 --- a/platform/testFramework/src/com/intellij/mock/MockRunManager.java +++ b/platform/testFramework/src/com/intellij/mock/MockRunManager.java @@ -4,6 +4,7 @@ import com.intellij.execution.*; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.ConfigurationType; import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RunProfile; import com.intellij.openapi.util.Key; import org.jetbrains.annotations.NotNull; @@ -46,7 +47,7 @@ public class MockRunManager extends RunManagerEx { } @Override - public void makeStable(RunConfiguration configuration) { + public void makeStable(@NotNull RunConfiguration configuration) { } @Override @@ -164,4 +165,8 @@ public class MockRunManager extends RunManagerEx { @Override public void removeRunManagerListener(RunManagerListener listener) { } + + @Override + public void refreshUsagesList(RunProfile profile) { + } } diff --git a/platform/testFramework/src/com/intellij/testFramework/HighlightTestInfo.java b/platform/testFramework/src/com/intellij/testFramework/HighlightTestInfo.java index 9d12ebc4f484..407ae199627e 100644 --- a/platform/testFramework/src/com/intellij/testFramework/HighlightTestInfo.java +++ b/platform/testFramework/src/com/intellij/testFramework/HighlightTestInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ public abstract class HighlightTestInfo implements Disposable { Disposer.register(parentDisposable, this); myPlace = parentDisposable.toString(); } + public HighlightTestInfo checkWarnings() { checkWarnings = true; return this; } public HighlightTestInfo checkWeakWarnings() { checkWeakWarnings = true; return this; } public HighlightTestInfo checkInfos() { checkInfos = true; return this; } @@ -43,10 +44,14 @@ public abstract class HighlightTestInfo implements Disposable { public HighlightTestInfo projectRoot(@NonNls @NotNull String root) { projectRoot = root; return this; } public HighlightTestInfo test() throws Exception { - doTest(); - tested = true; - Disposer.dispose(this); - return this; + try { + doTest(); + return this; + } + finally { + tested = true; + Disposer.dispose(this); + } } @Override diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java new file mode 100644 index 000000000000..32074ac649f6 --- /dev/null +++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java @@ -0,0 +1,296 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.codeStyle; + +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.FList; +import com.intellij.util.text.CharArrayCharSequence; +import com.intellij.util.text.Matcher; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; + +/** +* @author peter +*/ +public class MinusculeMatcher implements Matcher { + private final char[] myPattern; + private final NameUtil.MatchingCaseSensitivity myOptions; + + public MinusculeMatcher(String pattern, NameUtil.MatchingCaseSensitivity options) { + myOptions = options; + myPattern = StringUtil.trimEnd(pattern, "* ").replaceAll(":", "\\*:").toCharArray(); + } + + @Nullable + private FList matchName(String name, int patternIndex, int nameIndex) { + if (patternIndex == myPattern.length) { + return FList.emptyList(); + } + if ('*' == myPattern[patternIndex]) { + return skipChars(name, patternIndex, nameIndex, true); + } + if (nameIndex == name.length()) { + return null; + } + + if ('.' == myPattern[patternIndex] && name.charAt(nameIndex) != '.') { + return skipChars(name, patternIndex, nameIndex, false); + } + + if (' ' == myPattern[patternIndex] && patternIndex != myPattern.length - 1) { + return skipWords(name, patternIndex, nameIndex); + } + + if ((patternIndex == 0 || patternIndex == 1 && myPattern[0] == ' ' && nameIndex == 0) && + myOptions != NameUtil.MatchingCaseSensitivity.NONE && name.charAt(nameIndex) != myPattern[patternIndex]) { + return null; + } + + if (NameUtil.isWordSeparator(name.charAt(nameIndex))) { + return skipSeparators(name, patternIndex, nameIndex); + } + + if (StringUtil.toLowerCase(name.charAt(nameIndex)) != StringUtil.toLowerCase(myPattern[patternIndex])) { + if (Character.isDigit(name.charAt(nameIndex)) && nameIndex > 0 || (name.charAt(nameIndex) == '.' && name.indexOf('.', nameIndex + 1) > 0)) { + return matchName(name, patternIndex, nameIndex + 1); + } + return null; + } + + if (myOptions == NameUtil.MatchingCaseSensitivity.ALL && name.charAt(nameIndex) != myPattern[patternIndex]) { + return null; + } + + int nextStart = NameUtil.nextWord(name, nameIndex); + + int lastUpper = NameUtil.isWordStart(myPattern[patternIndex]) ? 0 : -1; + + int i = 1; + while (true) { + if (patternIndex + i == myPattern.length || i + nameIndex == nextStart) { + break; + } + char p = myPattern[patternIndex + i]; + char w = name.charAt(i + nameIndex); + if (lastUpper == i - 1 && NameUtil.isWordStart(p) && myOptions != NameUtil.MatchingCaseSensitivity.ALL) { + if (p == w) { + lastUpper = i; + } + p = StringUtil.toLowerCase(p); + } + + if (myOptions != NameUtil.MatchingCaseSensitivity.ALL) { + w = StringUtil.toLowerCase(w); + } + if (w != p) { + break; + } + i++; + } + + if (isFinalSpaceMatch(name, patternIndex, nameIndex, nextStart, i)) { + return FList.emptyList().prepend(TextRange.from(nameIndex, i)); + } + + return matchAfterFragment(name, patternIndex, nameIndex, nextStart, lastUpper, i); + } + + private boolean isFinalSpaceMatch(String name, int patternIndex, int nameIndex, int nextStart, int i) { + return nextStart == name.length() && + patternIndex + i == myPattern.length - 1 && + ' ' == myPattern[patternIndex + i] && + (i == 1 && NameUtil.isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length()); + } + + @Nullable + private FList matchAfterFragment(String name, int patternIndex, int nameIndex, int nextStart, int lastUpper, int matchLen) { + boolean star = patternIndex + matchLen < myPattern.length && myPattern[patternIndex + matchLen] == '*'; + if (lastUpper >= 0) { + FList ranges = matchName(name, patternIndex + lastUpper + 1, star && matchLen == lastUpper ? nameIndex + lastUpper : nextStart); + if (ranges != null) { + return prependRange(ranges, nameIndex, lastUpper + 1); + } + } + + int trial = matchLen; + while (trial > 0) { + FList ranges = matchName(name, patternIndex + trial, nextStart); + if (ranges != null) { + return prependRange(ranges, nameIndex, trial); + } + trial--; + } + + FList ranges = matchName(name, patternIndex + matchLen, nameIndex + matchLen); + if (ranges != null) { + return prependRange(ranges, nameIndex, matchLen); + } + return null; + } + + private static FList prependRange(FList ranges, int from, int length) { + TextRange head = ranges.getHead(); + if (head != null && head.getStartOffset() == from + length) { + return ranges.getTail().prepend(new TextRange(from, head.getEndOffset())); + } + return ranges.prepend(TextRange.from(from, length)); + } + + @Nullable + private FList skipSeparators(String name, int patternIndex, int nameIndex) { + int nextStart = NameUtil.nextWord(name, nameIndex); + assert nextStart - nameIndex == 1 : "'" + name + "'" + nameIndex + " " + nextStart; + char p = myPattern[patternIndex]; + if (NameUtil.isWordSeparator(p)) { + if (myOptions != NameUtil.MatchingCaseSensitivity.NONE && + nameIndex == 0 && name.length() > 1 && patternIndex + 1 < myPattern.length && + NameUtil.isWordSeparator(name.charAt(1)) && !NameUtil.isWordSeparator(myPattern[patternIndex + 1])) { + return null; + } + + final FList ranges = matchName(name, patternIndex + 1, nextStart); + if (ranges != null) { + return prependRange(ranges, nameIndex, 1); + } + + return null; + } + + return matchName(name, patternIndex, nextStart); + } + + @Nullable + private FList skipChars(String name, int patternIndex, int nameIndex, boolean maySkipNextChar) { + while ('*' == myPattern[patternIndex]) { + patternIndex++; + if (patternIndex == myPattern.length) { + return FList.emptyList(); + } + } + + String nextChar = String.valueOf(myPattern[patternIndex]); + boolean upper = Character.isUpperCase(myPattern[patternIndex]); + + int fromIndex = nameIndex; + while (true) { + int next = StringUtil.indexOfIgnoreCase(name, nextChar, fromIndex); + if (next < 0) { + break; + } + if (upper && next > 0 && !Character.isUpperCase(name.charAt(next))) { + fromIndex = next + 1; + continue; + } + + FList ranges = matchName(name, patternIndex, next); + if (ranges != null) { + return ranges; + } + if (!maySkipNextChar) { + return null; + } + fromIndex = next + 1; + } + return null; + } + + @Nullable + private FList skipWords(String name, int patternIndex, int nameIndex) { + while (' ' == myPattern[patternIndex]) { + patternIndex++; + if (patternIndex == myPattern.length) { + return null; + } + } + + if (nameIndex == 0 || NameUtil.isWordStart(name, nameIndex)) { + FList ranges = matchName(name, patternIndex, nameIndex); + if (ranges != null) { + return ranges; + } + } + + boolean separatorInPattern = NameUtil.isWordSeparator(myPattern[patternIndex]); + int fromIndex = nameIndex; + while (fromIndex < name.length()) { + int next = separatorInPattern ? name.indexOf(myPattern[patternIndex], fromIndex) : NameUtil.nextWord(name, fromIndex); + if (next < 0) { + break; + } + + FList ranges = matchName(name, patternIndex, next); + if (ranges != null) { + return ranges; + } + fromIndex = next; + if (separatorInPattern) { + fromIndex++; + } + } + return null; + } + + public int matchingDegree(String name) { + Iterable iterable = matchingFragments(name); + if (iterable == null) return Integer.MIN_VALUE; + + int fragmentCount = 0; + int matchingCase = 0; + CharArrayCharSequence seq = new CharArrayCharSequence(myPattern); + int p = -1; + TextRange first = null; + for (TextRange range : iterable) { + if (first == null) { + first = range; + } + for (int i = range.getStartOffset(); i < range.getEndOffset(); i++) { + char c = name.charAt(i); + p = StringUtil.indexOf(seq, c, p + 1, myPattern.length, false); + if (p < 0) { + break; + } + matchingCase += c == myPattern[p] ? 1 : 0; + } + fragmentCount++; + } + + int commonStart = 0; + while (commonStart < name.length() && commonStart < myPattern.length && name.charAt(commonStart) == myPattern[commonStart]) { + commonStart++; + } + + boolean prefixMatching = first != null && first.getStartOffset() == 0; + boolean middleWordStart = first != null && first.getStartOffset() > 0 && NameUtil.isWordStart(name, first.getStartOffset()); + + return -fragmentCount + matchingCase * 10 + commonStart + (prefixMatching ? 2 : middleWordStart ? 1 : 0) * 100; + } + + @Override + public boolean matches(String name) { + return matchingFragments(name) != null; + } + + @Nullable + public Iterable matchingFragments(String name) { + if (name.isEmpty()) { + return myPattern.length == 0 ? Collections.emptyList() : null; + } + + return matchName(name, 0, 0); + } +} diff --git a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java index 1fd815e56922..5725e6460a48 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java +++ b/platform/util/src/com/intellij/psi/codeStyle/NameUtil.java @@ -15,20 +15,15 @@ */ package com.intellij.psi.codeStyle; -import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.FList; -import com.intellij.util.text.CharArrayCharSequence; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class NameUtil { @@ -331,24 +326,24 @@ public class NameUtil { return suggestion; } - private static boolean isWordStart(String text, int i) { + static boolean isWordStart(String text, int i) { if (isWordStart(text.charAt(i))) { return true; } if (!Character.isLetterOrDigit(text.charAt(i))) { return false; } - if (i > 0 && (MinusculeMatcher.isWordSeparator(text.charAt(i - 1)) || text.charAt(i - 1) == '.')) { + if (i > 0 && (isWordSeparator(text.charAt(i - 1)) || text.charAt(i - 1) == '.')) { return true; } return false; } - private static boolean isWordStart(char p) { + static boolean isWordStart(char p) { return Character.isUpperCase(p) || Character.isDigit(p); } - private static int nextWord(String text, int start) { + static int nextWord(String text, int start) { if (!Character.isLetterOrDigit(text.charAt(start))) { return start + 1; } @@ -378,6 +373,10 @@ public class NameUtil { } } + static boolean isWordSeparator(char c) { + return Character.isWhitespace(c) || c == '_' || c == '-' || c == ':'; + } + /** * @deprecated use com.intellij.util.text.Matcher */ @@ -409,276 +408,4 @@ public class NameUtil { public enum MatchingCaseSensitivity { NONE, FIRST_LETTER, ALL } - - public static class MinusculeMatcher implements com.intellij.util.text.Matcher { - private final char[] myPattern; - private final MatchingCaseSensitivity myOptions; - - public MinusculeMatcher(String pattern, MatchingCaseSensitivity options) { - myOptions = options; - myPattern = StringUtil.trimEnd(pattern, "* ").replaceAll(":", "\\*:").toCharArray(); - } - - @Nullable - private FList matchName(String name, int patternIndex, int nameIndex) { - if (patternIndex == myPattern.length) { - return FList.emptyList(); - } - if ('*' == myPattern[patternIndex]) { - return skipChars(name, patternIndex, nameIndex, true); - } - if (nameIndex == name.length()) { - return null; - } - - if ('.' == myPattern[patternIndex] && name.charAt(nameIndex) != '.') { - return skipChars(name, patternIndex, nameIndex, false); - } - - if (' ' == myPattern[patternIndex] && patternIndex != myPattern.length - 1) { - return skipWords(name, patternIndex, nameIndex); - } - - if ((patternIndex == 0 || patternIndex == 1 && myPattern[0] == ' ' && nameIndex == 0) && - myOptions != MatchingCaseSensitivity.NONE && name.charAt(nameIndex) != myPattern[patternIndex]) { - return null; - } - - if (isWordSeparator(name.charAt(nameIndex))) { - return skipSeparators(name, patternIndex, nameIndex); - } - - if (StringUtil.toLowerCase(name.charAt(nameIndex)) != StringUtil.toLowerCase(myPattern[patternIndex])) { - if (Character.isDigit(name.charAt(nameIndex)) && nameIndex > 0 || (name.charAt(nameIndex) == '.' && name.indexOf('.', nameIndex + 1) > 0)) { - return matchName(name, patternIndex, nameIndex + 1); - } - return null; - } - - if (myOptions == MatchingCaseSensitivity.ALL && name.charAt(nameIndex) != myPattern[patternIndex]) { - return null; - } - - int nextStart = NameUtil.nextWord(name, nameIndex); - - int lastUpper = isWordStart(myPattern[patternIndex]) ? 0 : -1; - - int i = 1; - while (true) { - if (patternIndex + i == myPattern.length || i + nameIndex == nextStart) { - break; - } - char p = myPattern[patternIndex + i]; - char w = name.charAt(i + nameIndex); - if (lastUpper == i - 1 && isWordStart(p) && myOptions != MatchingCaseSensitivity.ALL) { - if (p == w) { - lastUpper = i; - } - p = StringUtil.toLowerCase(p); - } - - if (myOptions != MatchingCaseSensitivity.ALL) { - w = StringUtil.toLowerCase(w); - } - if (w != p) { - break; - } - i++; - } - - if (isFinalSpaceMatch(name, patternIndex, nameIndex, nextStart, i)) { - return FList.emptyList().prepend(TextRange.from(nameIndex, i)); - } - - return matchAfterFragment(name, patternIndex, nameIndex, nextStart, lastUpper, i); - } - - private boolean isFinalSpaceMatch(String name, int patternIndex, int nameIndex, int nextStart, int i) { - return nextStart == name.length() && - patternIndex + i == myPattern.length - 1 && - ' ' == myPattern[patternIndex + i] && - (i == 1 && isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length()); - } - - @Nullable - private FList matchAfterFragment(String name, int patternIndex, int nameIndex, int nextStart, int lastUpper, int matchLen) { - boolean star = patternIndex + matchLen < myPattern.length && myPattern[patternIndex + matchLen] == '*'; - if (lastUpper >= 0) { - FList ranges = matchName(name, patternIndex + lastUpper + 1, star && matchLen == lastUpper ? nameIndex + lastUpper : nextStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, lastUpper + 1); - } - } - - int trial = matchLen; - while (trial > 0) { - FList ranges = matchName(name, patternIndex + trial, nextStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, trial); - } - trial--; - } - - FList ranges = matchName(name, patternIndex + matchLen, nameIndex + matchLen); - if (ranges != null) { - return prependRange(ranges, nameIndex, matchLen); - } - return null; - } - - private static FList prependRange(FList ranges, int from, int length) { - TextRange head = ranges.getHead(); - if (head != null && head.getStartOffset() == from + length) { - return ranges.getTail().prepend(new TextRange(from, head.getEndOffset())); - } - return ranges.prepend(TextRange.from(from, length)); - } - - private static boolean isWordSeparator(char c) { - return Character.isWhitespace(c) || c == '_' || c == '-' || c == ':'; - } - - @Nullable - private FList skipSeparators(String name, int patternIndex, int nameIndex) { - int nextStart = NameUtil.nextWord(name, nameIndex); - assert nextStart - nameIndex == 1 : "'" + name + "'" + nameIndex + " " + nextStart; - char p = myPattern[patternIndex]; - if (isWordSeparator(p)) { - if (myOptions != MatchingCaseSensitivity.NONE && - nameIndex == 0 && name.length() > 1 && patternIndex + 1 < myPattern.length && - isWordSeparator(name.charAt(1)) && !isWordSeparator(myPattern[patternIndex + 1])) { - return null; - } - - final FList ranges = matchName(name, patternIndex + 1, nextStart); - if (ranges != null) { - return prependRange(ranges, nameIndex, 1); - } - - return null; - } - - return matchName(name, patternIndex, nextStart); - } - - @Nullable - private FList skipChars(String name, int patternIndex, int nameIndex, boolean maySkipNextChar) { - while ('*' == myPattern[patternIndex]) { - patternIndex++; - if (patternIndex == myPattern.length) { - return FList.emptyList(); - } - } - - String nextChar = String.valueOf(myPattern[patternIndex]); - boolean upper = Character.isUpperCase(myPattern[patternIndex]); - - int fromIndex = nameIndex; - while (true) { - int next = StringUtil.indexOfIgnoreCase(name, nextChar, fromIndex); - if (next < 0) { - break; - } - if (upper && next > 0 && !Character.isUpperCase(name.charAt(next))) { - fromIndex = next + 1; - continue; - } - - FList ranges = matchName(name, patternIndex, next); - if (ranges != null) { - return ranges; - } - if (!maySkipNextChar) { - return null; - } - fromIndex = next + 1; - } - return null; - } - - @Nullable - private FList skipWords(String name, int patternIndex, int nameIndex) { - while (' ' == myPattern[patternIndex]) { - patternIndex++; - if (patternIndex == myPattern.length) { - return null; - } - } - - if (nameIndex == 0 || isWordStart(name, nameIndex)) { - FList ranges = matchName(name, patternIndex, nameIndex); - if (ranges != null) { - return ranges; - } - } - - boolean separatorInPattern = isWordSeparator(myPattern[patternIndex]); - int fromIndex = nameIndex; - while (fromIndex < name.length()) { - int next = separatorInPattern ? name.indexOf(myPattern[patternIndex], fromIndex) : nextWord(name, fromIndex); - if (next < 0) { - break; - } - - FList ranges = matchName(name, patternIndex, next); - if (ranges != null) { - return ranges; - } - fromIndex = next; - if (separatorInPattern) { - fromIndex++; - } - } - return null; - } - - public int matchingDegree(String name) { - Iterable iterable = matchingFragments(name); - if (iterable == null) return Integer.MIN_VALUE; - - int fragmentCount = 0; - int matchingCase = 0; - CharArrayCharSequence seq = new CharArrayCharSequence(myPattern); - int p = -1; - TextRange first = null; - for (TextRange range : iterable) { - if (first == null) { - first = range; - } - for (int i = range.getStartOffset(); i < range.getEndOffset(); i++) { - char c = name.charAt(i); - p = StringUtil.indexOf(seq, c, p + 1, myPattern.length, false); - if (p < 0) { - break; - } - matchingCase += c == myPattern[p] ? 1 : 0; - } - fragmentCount++; - } - - int commonStart = 0; - while (commonStart < name.length() && commonStart < myPattern.length && name.charAt(commonStart) == myPattern[commonStart]) { - commonStart++; - } - - boolean prefixMatching = first != null && first.getStartOffset() == 0; - boolean middleWordStart = first != null && first.getStartOffset() > 0 && isWordStart(name, first.getStartOffset()); - - return -fragmentCount + matchingCase * 10 + commonStart + (prefixMatching ? 2 : middleWordStart ? 1 : 0) * 100; - } - - @Override - public boolean matches(String name) { - return matchingFragments(name) != null; - } - - @Nullable - public Iterable matchingFragments(String name) { - if (name.isEmpty()) { - return myPattern.length == 0 ? Collections.emptyList() : null; - } - - return matchName(name, 0, 0); - } - } } diff --git a/platform/util/src/com/intellij/util/ui/EditableTreeModel.java b/platform/util/src/com/intellij/util/ui/EditableTreeModel.java new file mode 100644 index 000000000000..c254c4631e38 --- /dev/null +++ b/platform/util/src/com/intellij/util/ui/EditableTreeModel.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.ui; + +import javax.swing.tree.TreePath; + +/** + * @author Konstantin Bulenkov + * @since 12.0 + */ +public interface EditableTreeModel { + /** + * Adds a new node into a + * @param parent selected node, maybe used as parent or as a neighbour + * @return path to newly created element + */ + TreePath addNode(TreePath parentOrNeighbour); + + void removeNode(TreePath parent); + + void moveNodeTo(TreePath parentOrNeighbour); +} diff --git a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/IdeaTextPatchBuilder.java b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/IdeaTextPatchBuilder.java index 839e94ba8049..3b6b9a034cb0 100644 --- a/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/IdeaTextPatchBuilder.java +++ b/platform/vcs-api/src/com/intellij/openapi/diff/impl/patch/IdeaTextPatchBuilder.java @@ -52,12 +52,12 @@ public class IdeaTextPatchBuilder { for (VcsRoot root : byRoots.keySet()) { final Collection rootChanges = byRoots.get(root); - if (root.vcs == null || root.vcs.getOutgoingChangesProvider() == null) { + if (root.getVcs() == null || root.getVcs().getOutgoingChangesProvider() == null) { addConvertChanges(rootChanges, result); continue; } - final VcsOutgoingChangesProvider provider = root.vcs.getOutgoingChangesProvider(); - final Collection basedOnLocal = provider.filterLocalChangesBasedOnLocalCommits(rootChanges, root.path); + final VcsOutgoingChangesProvider provider = root.getVcs().getOutgoingChangesProvider(); + final Collection basedOnLocal = provider.filterLocalChangesBasedOnLocalCommits(rootChanges, root.getPath()); rootChanges.removeAll(basedOnLocal); addConvertChanges(rootChanges, result); diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRoot.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRoot.java index c05995636b45..771a7e29885a 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRoot.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsRoot.java @@ -17,18 +17,31 @@ package com.intellij.openapi.vcs; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.Nullable; /** * @author yole */ public class VcsRoot { - public final AbstractVcs vcs; - public final VirtualFile path; + + @Nullable private final AbstractVcs myVcs; + @Nullable private final VirtualFile myPath; + private int hashcode; - public VcsRoot(final AbstractVcs vcs, final VirtualFile path) { - this.vcs = vcs; - this.path = path; + public VcsRoot(@Nullable AbstractVcs vcs, @Nullable VirtualFile path) { + myVcs = vcs; + myPath = path; + } + + @Nullable + public AbstractVcs getVcs() { + return myVcs; + } + + @Nullable + public VirtualFile getPath() { + return myPath; } @Override @@ -38,26 +51,22 @@ public class VcsRoot { VcsRoot root = (VcsRoot)o; - if (path != null ? !path.equals(root.path) : root.path != null) return false; - if (vcs != null ? !vcs.getName().equals(root.vcs.getName()) : root.vcs != null) return false; + if (myPath != null ? !myPath.equals(root.myPath) : root.myPath != null) return false; + if (myVcs != null ? !myVcs.equals(root.myVcs) : root.myVcs != null) return false; return true; } - @Override public int hashCode() { if (hashcode == 0) { - hashcode = vcs != null ? vcs.getName().hashCode() : 0; - hashcode = 31 * hashcode + (path != null ? path.hashCode() : 0); + hashcode = myVcs != null ? myVcs.hashCode() : 0; + hashcode = 31 * hashcode + (myPath != null ? myPath.hashCode() : 0); } return hashcode; } @Override public String toString() { - return "VcsRoot{" + - "vcs=" + vcs + - ", path=" + path + - '}'; + return String.format("VcsRoot{vcs=%s, path=%s}", myVcs, myPath); } } \ No newline at end of file diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/TriggerAdditionOrDeletion.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/TriggerAdditionOrDeletion.java index e9a3eec147cd..b74937583127 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/TriggerAdditionOrDeletion.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/TriggerAdditionOrDeletion.java @@ -91,14 +91,14 @@ public class TriggerAdditionOrDeletion { if (myPreparedDeletion != null) { for (Map.Entry> entry : myPreparedDeletion.entrySet()) { final VcsRoot vcsRoot = entry.getKey(); - final CheckinEnvironment localChangesProvider = vcsRoot.vcs.getCheckinEnvironment(); + final CheckinEnvironment localChangesProvider = vcsRoot.getVcs().getCheckinEnvironment(); if (localChangesProvider == null) continue; final Collection filePaths = entry.getValue(); - if (vcsRoot.vcs.fileListenerIsSynchronous()) { + if (vcsRoot.getVcs().fileListenerIsSynchronous()) { myAffected.addAll(filePaths); continue; } - askUserIfNeededDeletion(vcsRoot.vcs, (List)filePaths); + askUserIfNeededDeletion(vcsRoot.getVcs(), (List)filePaths); myAffected.addAll(filePaths); localChangesProvider.scheduleMissingFileForDeletion((List)filePaths); } @@ -106,14 +106,14 @@ public class TriggerAdditionOrDeletion { if (myPreparedAddition != null) { for (Map.Entry> entry : myPreparedAddition.entrySet()) { final VcsRoot vcsRoot = entry.getKey(); - final CheckinEnvironment localChangesProvider = vcsRoot.vcs.getCheckinEnvironment(); + final CheckinEnvironment localChangesProvider = vcsRoot.getVcs().getCheckinEnvironment(); if (localChangesProvider == null) continue; final Collection filePaths = entry.getValue(); - if (vcsRoot.vcs.fileListenerIsSynchronous()) { + if (vcsRoot.getVcs().fileListenerIsSynchronous()) { myAffected.addAll(filePaths); continue; } - askUserIfNeededAddition(vcsRoot.vcs, (List)filePaths); + askUserIfNeededAddition(vcsRoot.getVcs(), (List)filePaths); myAffected.addAll(filePaths); localChangesProvider.scheduleUnversionedFilesForAddition(ObjectsConvertor.fp2vf(filePaths)); } @@ -128,10 +128,10 @@ public class TriggerAdditionOrDeletion { final MultiMap map = sortByVcsRoots.sort(myDeleted); myPreparedDeletion = new MultiMap(); for (VcsRoot vcsRoot : map.keySet()) { - if (vcsRoot != null && vcsRoot.vcs != null) { - final CheckinEnvironment localChangesProvider = vcsRoot.vcs.getCheckinEnvironment(); + if (vcsRoot != null && vcsRoot.getVcs() != null) { + final CheckinEnvironment localChangesProvider = vcsRoot.getVcs().getCheckinEnvironment(); if (localChangesProvider == null) continue; - final boolean takeDirs = vcsRoot.vcs.areDirectoriesVersionedItems(); + final boolean takeDirs = vcsRoot.getVcs().areDirectoriesVersionedItems(); final Collection files = map.get(vcsRoot); final List toBeDeleted = new LinkedList(); @@ -142,7 +142,7 @@ public class TriggerAdditionOrDeletion { } } if (toBeDeleted.isEmpty()) return; - if (! vcsRoot.vcs.fileListenerIsSynchronous()) { + if (! vcsRoot.getVcs().fileListenerIsSynchronous()) { for (FilePath filePath : toBeDeleted) { myVcsFileListenerContextHelper.ignoreDeleted(filePath); } @@ -159,15 +159,15 @@ public class TriggerAdditionOrDeletion { final MultiMap map = sortByVcsRoots.sort(myExisting); myPreparedAddition = new MultiMap(); for (VcsRoot vcsRoot : map.keySet()) { - if (vcsRoot != null && vcsRoot.vcs != null) { - final CheckinEnvironment localChangesProvider = vcsRoot.vcs.getCheckinEnvironment(); + if (vcsRoot != null && vcsRoot.getVcs() != null) { + final CheckinEnvironment localChangesProvider = vcsRoot.getVcs().getCheckinEnvironment(); if (localChangesProvider == null) continue; - final boolean takeDirs = vcsRoot.vcs.areDirectoriesVersionedItems(); + final boolean takeDirs = vcsRoot.getVcs().areDirectoriesVersionedItems(); final Collection files = map.get(vcsRoot); final List toBeAdded; if (takeDirs) { - final RecursiveCheckAdder adder = new RecursiveCheckAdder(vcsRoot.path); + final RecursiveCheckAdder adder = new RecursiveCheckAdder(vcsRoot.getPath()); for (FilePath file : files) { adder.process(file); } @@ -184,7 +184,7 @@ public class TriggerAdditionOrDeletion { return; } Collections.sort(toBeAdded, FilePathByPathComparator.getInstance()); - if (! vcsRoot.vcs.fileListenerIsSynchronous()) { + if (! vcsRoot.getVcs().fileListenerIsSynchronous()) { for (FilePath filePath : toBeAdded) { myVcsFileListenerContextHelper.ignoreAdded(filePath.getVirtualFile()); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java index d6bdb2c34109..e79c4c098261 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java @@ -17,6 +17,8 @@ package com.intellij.openapi.vcs.changes; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diff.DiffPanel; import com.intellij.openapi.diff.ShiftedSimpleContent; import com.intellij.openapi.diff.SimpleContent; @@ -45,7 +47,10 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.DialogWrapperDialog; import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.ui.impl.DialogWrapperPeerImpl; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; @@ -150,8 +155,6 @@ public class ChangesFragmentedDiffPanel implements Disposable { myCurrentHorizontal = myConfiguration.SHORT_DIFF_HORISONTALLY; myHorizontal = createPanel(true); myVertical = createPanel(false); - myNavigateAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), myHorizontal.getComponent()); - myNavigateAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), myVertical.getComponent()); myPanel.add(myTopPanel, BorderLayout.NORTH); myPanel.add(getCurrentPanel().getComponent(), BorderLayout.CENTER); @@ -222,7 +225,26 @@ public class ChangesFragmentedDiffPanel implements Disposable { } } if (descriptor == null) return; - FileEditorManager.getInstance(myProject).openTextEditor(descriptor, true); + final OpenFileDescriptor finalDescriptor = descriptor; + final Runnable runnable = new Runnable() { + @Override + public void run() { + FileEditorManager.getInstance(myProject).openTextEditor(finalDescriptor, true); + } + }; + if (! ModalityState.NON_MODAL.equals(ModalityState.current())) { + final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + if (window instanceof DialogWrapperDialog) { + final DialogWrapper wrapper = ((DialogWrapperDialog)window).getDialogWrapper(); + if (wrapper != null) { + Disposer.dispose(wrapper.getDisposable()); + wrapper.close(0); + ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed()); + return; + } + } + } + runnable.run(); } } @@ -260,6 +282,14 @@ public class ChangesFragmentedDiffPanel implements Disposable { adjustPanelData((DiffPanelImpl)myHorizontal); adjustPanelData((DiffPanelImpl)myVertical); + if (((DiffPanelImpl) myHorizontal).getEditor1() != null) { + myNavigateAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), ((DiffPanelImpl) myHorizontal).getEditor1().getComponent()); + myNavigateAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), ((DiffPanelImpl) myVertical).getEditor1().getComponent()); + } + if (((DiffPanelImpl) myHorizontal).getEditor2() != null) { + myNavigateAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), ((DiffPanelImpl) myHorizontal).getEditor2().getComponent()); + myNavigateAction.registerCustomShortcutSet(CommonShortcuts.getEditSource(), ((DiffPanelImpl) myVertical).getEditor2().getComponent()); + } DiffPanel currentPanel = getCurrentPanel(); FragmentedDiffPanelState state = (FragmentedDiffPanelState)((DiffPanelImpl)currentPanel).getDiffPanelState(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DirtBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DirtBuilder.java index e67be9520256..aae32d66f9f2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DirtBuilder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/DirtBuilder.java @@ -58,13 +58,13 @@ public class DirtBuilder implements DirtBuilderReader { } public void addDirtyFile(final VcsRoot root) { - if (myFileTypeManager.isFileIgnored(root.path.getName())) return; - myFiles.add(new FilePathUnderVcs(new FilePathImpl(root.path), root.vcs)); + if (myFileTypeManager.isFileIgnored(root.getPath().getName())) return; + myFiles.add(new FilePathUnderVcs(new FilePathImpl(root.getPath()), root.getVcs())); } public void addDirtyDirRecursively(final VcsRoot root) { - if (myFileTypeManager.isFileIgnored(root.path.getName())) return; - myDirs.add(new FilePathUnderVcs(new FilePathImpl(root.path), root.vcs)); + if (myFileTypeManager.isFileIgnored(root.getPath().getName())) return; + myDirs.add(new FilePathUnderVcs(new FilePathImpl(root.getPath()), root.getVcs())); } public void addDirtyFile(final FilePathUnderVcs root) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FilePathUnderVcs.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FilePathUnderVcs.java index f3bed0b0a416..c2138f6d25cb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FilePathUnderVcs.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FilePathUnderVcs.java @@ -33,8 +33,8 @@ public class FilePathUnderVcs { } FilePathUnderVcs(final VcsRoot root) { - myPath = new FilePathImpl(root.path); - myVcs = root.vcs; + myPath = new FilePathImpl(root.getPath()); + myVcs = root.getVcs(); } public FilePath getPath() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java index ae5412bdfd9c..b172810d17da 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsCache.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.vcs.changes; -import com.intellij.lifecycle.AtomicSectionsAware; import com.intellij.lifecycle.PeriodicalTasksCloser; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; @@ -128,7 +127,7 @@ public class RemoteRevisionsCache implements PlusMinus final VcsRoot[] roots = myVcsManager.getAllVcsRoots(); synchronized (myLock) { for (VcsRoot root : roots) { - final AbstractVcs vcs = root.vcs; + final AbstractVcs vcs = root.getVcs(); if (! myKinds.containsKey(vcs.getName())) { myKinds.put(vcs.getName(), vcs.getRemoteDifferenceStrategy()); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java index 193d994f90e3..386c5751eb42 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsNumbersCache.java @@ -96,8 +96,8 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker { for (Iterator> iterator = copyMap.entrySet().iterator(); iterator.hasNext();) { final Map.Entry entry = iterator.next(); final VcsRoot key = entry.getKey(); - final boolean backgroundOperationsAllowed = key.vcs.isVcsBackgroundOperationsAllowed(key.path); - LOG.debug("backgroundOperationsAllowed: " + backgroundOperationsAllowed + " for " + key.vcs.getName() + ", " + key.path.getPath()); + final boolean backgroundOperationsAllowed = key.getVcs().isVcsBackgroundOperationsAllowed(key.getPath()); + LOG.debug("backgroundOperationsAllowed: " + backgroundOperationsAllowed + " for " + key.getVcs().getName() + ", " + key.getPath().getPath()); if (! backgroundOperationsAllowed) { iterator.remove(); } @@ -232,7 +232,7 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker { //todo check canceled - check VCS's ready for asynchronous queries final VirtualFile vf = myLfs.refreshAndFindFileByIoFile(new File(s)); final ItemLatestState state; - final DiffProvider diffProvider = myVcsRoot.vcs.getDiffProvider(); + final DiffProvider diffProvider = myVcsRoot.getVcs().getDiffProvider(); if (vf == null) { // doesnt matter if directory or not state = diffProvider.getLastRevision(FilePathImpl.createForDeletedFile(new File(s), false)); @@ -262,11 +262,11 @@ public class RemoteRevisionsNumbersCache implements ChangesOnServerTracker { } public Boolean compute() { - final AbstractVcs vcs = myVcsRoot.vcs; + final AbstractVcs vcs = myVcsRoot.getVcs(); // won't be called in parallel for same vcs -> just synchronized map is ok final String vcsName = vcs.getName(); - LOG.debug("should update for: " + vcsName + " root: " + myVcsRoot.path.getPath()); - final VcsRevisionNumber latestNew = vcs.getDiffProvider().getLatestCommittedRevision(myVcsRoot.path); + LOG.debug("should update for: " + vcsName + " root: " + myVcsRoot.getPath().getPath()); + final VcsRevisionNumber latestNew = vcs.getDiffProvider().getLatestCommittedRevision(myVcsRoot.getPath()); final VcsRevisionNumber latestKnown = myLatestRevisionsMap.get(vcsName); // not known diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsStateCache.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsStateCache.java index da6934f82e05..fd8a5372242a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsStateCache.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RemoteRevisionsStateCache.java @@ -135,12 +135,12 @@ public class RemoteRevisionsStateCache implements ChangesOnServerTracker { for (VcsRoot vcsRoot : dirty.keySet()) { // todo - actually it means nothing since the only known VCS to use this scheme is Git and now it always allow // todo - background operations. when it changes, develop more flexible behavior here - if (! vcsRoot.vcs.isVcsBackgroundOperationsAllowed(vcsRoot.path)) continue; - final TreeDiffProvider provider = vcsRoot.vcs.getTreeDiffProvider(); + if (! vcsRoot.getVcs().isVcsBackgroundOperationsAllowed(vcsRoot.getPath())) continue; + final TreeDiffProvider provider = vcsRoot.getVcs().getTreeDiffProvider(); if (provider == null) continue; final Collection paths = dirty.get(vcsRoot); - final Collection remotelyChanged = provider.getRemotelyChanged(vcsRoot.path, paths); + final Collection remotelyChanged = provider.getRemotelyChanged(vcsRoot.getPath(), paths); for (String path : paths) { results.put(path, new Pair(remotelyChanged.contains(path), vcsRoot)); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java index 149c6c9cb089..202e15ad9d72 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java @@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.changes; import com.intellij.CommonBundle; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vcs.VcsShowConfirmationOption; import com.intellij.util.ui.OptionsDialog; @@ -73,18 +74,20 @@ public class VcsConfirmationDialog extends OptionsDialog { @Override protected Action[] createActions() { - return new Action[] { - new AbstractAction(CommonBundle.getYesButtonText()) { - { - putValue(DEFAULT_ACTION, Boolean.TRUE); - } - public void actionPerformed(ActionEvent e) { - doOKAction(); - } - }, new AbstractAction(CommonBundle.getNoButtonText()) { - public void actionPerformed(ActionEvent e) { - doCancelAction(); - } - }}; + final AbstractAction okAction = new AbstractAction(CommonBundle.getYesButtonText()) { + { + putValue(DEFAULT_ACTION, Boolean.TRUE); + } + + public void actionPerformed(ActionEvent e) { + doOKAction(); + } + }; + final AbstractAction cancelAction = new AbstractAction(CommonBundle.getNoButtonText()) { + public void actionPerformed(ActionEvent e) { + doCancelAction(); + } + }; + return SystemInfo.isMac ? new Action[] {cancelAction, okAction} : new Action[] {okAction, cancelAction}; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java index 97f9e623dbcc..fcdd21c64d16 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.Processor; @@ -307,16 +308,16 @@ public class VcsDirtyScopeImpl extends VcsModifiableDirtyScope { if (myProject.isDisposed()) return Boolean.FALSE; final VcsRoot rootObject = myVcsManager.getVcsRootObjectFor(path); if (vcsConsumer != null && rootObject != null) { - vcsConsumer.consume(rootObject.vcs); + vcsConsumer.consume(rootObject.getVcs()); } - if (rootObject == null || rootObject.vcs != myVcs) { + if (rootObject == null || rootObject.getVcs() != myVcs) { return Boolean.FALSE; } - final VirtualFile vcsRoot = rootObject.path; + final VirtualFile vcsRoot = rootObject.getPath(); if (vcsRoot != null) { for (VirtualFile contentRoot : myAffectedContentRoots) { - if (VfsUtil.isAncestor(contentRoot, vcsRoot, false)) { + if (VfsUtilCore.isAncestor(contentRoot, vcsRoot, false)) { THashSet dirsByRoot = myDirtyDirectoriesRecursively.get(contentRoot); if (dirsByRoot != null) { for (FilePath filePath : dirsByRoot) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitLegendPanel.form b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitLegendPanel.form index e94a1015b243..d3128787f259 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitLegendPanel.form +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitLegendPanel.form @@ -15,7 +15,7 @@ - + diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsBackgroundOperationsConfigurationPanel.form b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsBackgroundOperationsConfigurationPanel.form index b26f54b2e269..7d0b32243890 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsBackgroundOperationsConfigurationPanel.form +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsBackgroundOperationsConfigurationPanel.form @@ -23,7 +23,7 @@ - + @@ -86,7 +86,7 @@ - + diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.form b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.form index ac45cac42c5b..e349a10da9b8 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.form +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.form @@ -20,7 +20,7 @@ - + @@ -60,7 +60,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -142,7 +142,7 @@ - + diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java index 3bbaed4fbef4..af08b7c08ae5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/FileHistoryPanelImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.OpenFileDescriptor; @@ -1023,7 +1024,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { new Task.Backgroundable(project, VcsBundle.message("show.diff.progress.title")) { @Override public void run(@NotNull ProgressIndicator indicator) { - LocalHistoryAction action = file != null ? startLocalHistoryAction(revision) : LocalHistoryAction.NULL; + final LocalHistoryAction action = file != null ? startLocalHistoryAction(revision) : LocalHistoryAction.NULL; final byte[] revisionContent; try { revisionContent = VcsHistoryUtil.loadRevisionContent(revision); @@ -1049,39 +1050,37 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton { return; } - try { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - CommandProcessor.getInstance().executeCommand(project, new Runnable() { - public void run() { - if (file != null && !file.isWritable()) { - if (ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(file).hasReadonlyFiles()) { - return; - } - } + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + try { + new WriteCommandAction.Simple(project) { + @Override + protected void run() throws Throwable { + if (file != null && + !file.isWritable() && + ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(file).hasReadonlyFiles()) { + return; + } - try { - write(revisionContent); - } catch (IOException e) { - Messages.showMessageDialog(VcsBundle.message("message.text.cannot.save.content", e.getLocalizedMessage()), - VcsBundle.message( "message.title.get.revision.content"), Messages.getErrorIcon()); - } - } - }, createGetActionTitle(revision), null); + try { + write(revisionContent); + } + catch (IOException e) { + Messages.showMessageDialog(VcsBundle.message("message.text.cannot.save.content", e.getLocalizedMessage()), + VcsBundle.message("message.title.get.revision.content"), Messages.getErrorIcon()); + } } - }); + }.execute(); + if (file != null) { + VcsDirtyScopeManager.getInstance(project).fileDirty(file); + } + } + finally { + action.finish(); } - }); - - if (file != null) { - VcsDirtyScopeManager.getInstance(project).fileDirty(file); } - } - finally { - action.finish(); - } + }); } }.queue(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LocalChangesUnderRoots.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LocalChangesUnderRoots.java index eeba391dd2e8..3412cdb4f57c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LocalChangesUnderRoots.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/LocalChangesUnderRoots.java @@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ChangesUtil; import com.intellij.openapi.vcs.changes.ContentRevision; import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -87,9 +88,9 @@ public class LocalChangesUnderRoots { } VirtualFile rootCandidate = null; for (VcsRoot root : myRoots) { - if (VfsUtil.isAncestor(root.path, vf, false)) { - if (rootCandidate == null || VfsUtil.isAncestor(rootCandidate, root.path, true)) { // in the case of nested roots choose the closest root - rootCandidate = root.path; + if (VfsUtilCore.isAncestor(root.getPath(), vf, false)) { + if (rootCandidate == null || VfsUtil.isAncestor(rootCandidate, root.getPath(), true)) { // in the case of nested roots choose the closest root + rootCandidate = root.getPath(); } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java index c272b36ad3a3..d580acbb176b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java @@ -92,8 +92,8 @@ public class VcsRootIterator { final String ourPath = myRoot.getUrl(); for (VcsRoot root : allRoots) { - if (Comparing.equal(root.vcs.getName(), myVcsName)) continue; - final String url = root.path.getUrl(); + if (Comparing.equal(root.getVcs().getName(), myVcsName)) continue; + final String url = root.getPath().getUrl(); if (url.startsWith(ourPath)) { myExcludedByOtherVcss.add(url); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java index 2e8d8380f5e7..d0a300d97200 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/update/AbstractCommonUpdateAction.java @@ -49,7 +49,6 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.util.WaitForProgressToShow; -import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.OptionsDialog; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NonNls; @@ -581,19 +580,14 @@ public abstract class AbstractCommonUpdateAction extends AbstractVcsAction { updateInfoTree.setBefore(myBefore); updateInfoTree.setAfter(myAfter); - // todo make temporal listener of changes reload - if (updateInfoTree != null) { - updateInfoTree.setCanGroupByChangeList(canGroupByChangelist(myVcsToVirtualFiles.keySet())); - final MessageBusConnection messageBusConnection = myProject.getMessageBus().connect(); - messageBusConnection.subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesAdapter() { - public void incomingChangesUpdated(final List receivedChanges) { - if (receivedChanges != null) { - updateInfoTree.setChangeLists(receivedChanges); - messageBusConnection.disconnect(); - } + updateInfoTree.setCanGroupByChangeList(canGroupByChangelist(myVcsToVirtualFiles.keySet())); + myProject.getMessageBus().connect(updateInfoTree).subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesAdapter() { + public void incomingChangesUpdated(final List receivedChanges) { + if (receivedChanges != null) { + updateInfoTree.setChangeLists(receivedChanges); } - }); - } + } + }); } public void onCancel() { diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java index 769366f94787..3dbc5b0541a4 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java @@ -21,12 +21,15 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.ColorUtil; +import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.popup.util.DetailView; import com.intellij.ui.popup.util.ItemWrapper; import com.intellij.xdebugger.ui.DebuggerColors; import javax.swing.*; -import java.awt.*; /** * Created with IntelliJ IDEA. @@ -43,16 +46,11 @@ public abstract class BreakpointItem implements ItemWrapper { public abstract void setEnabled(boolean state); protected void showInEditor(DetailView panel, VirtualFile virtualFile, int line) { - final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes( - DebuggerColors.BREAKPOINT_ATTRIBUTES).clone(); - final Color color = attributes.getBackgroundColor(); - attributes.setBackgroundColor(new Color(color.getRed(), color.getGreen()-100, color.getBlue()-100)); - panel.navigateInPreviewEditor(virtualFile, new LogicalPosition(line, 0), attributes); + panel.navigateInPreviewEditor(virtualFile, new LogicalPosition(line, 0), null); } @Override public void execute(Project project, JBPopup popup) { - setEnabled(!isEnabled()); } @Override @@ -60,4 +58,17 @@ public abstract class BreakpointItem implements ItemWrapper { final JCheckBox checkBox = (JCheckBox)component; checkBox.setSelected(isEnabled()); } + + @Override + public void setupRenderer(ColoredListCellRenderer renderer, Project project, boolean selected) { + setupGenericRenderer(renderer); + } + + @Override + public void setupRenderer(ColoredTreeCellRenderer renderer) { + setupGenericRenderer(renderer); + } + + protected abstract void setupGenericRenderer(SimpleColoredComponent renderer); + } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java new file mode 100644 index 000000000000..ec64306ea25a --- /dev/null +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.breakpoints.ui; + +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * Created with IntelliJ IDEA. + * User: zajac + * Date: 23.05.12 + * Time: 15:57 + * To change this template use File | Settings | File Templates. + */ +public class XBreakpointGroupingByTypeRule extends XBreakpointGroupingRule { + + public XBreakpointGroupingByTypeRule() { + super("XBreakpointGroupingByTypeRule", "Type"); + } + + @Override + public XBreakpointTypeGroup getGroup(@NotNull B b, @NotNull Collection groups) { + if (b instanceof XBreakpoint) { + final XBreakpoint breakpoint = (XBreakpoint)b; + for (XBreakpointTypeGroup group : groups) { + if (group.getBreakpointType() == breakpoint.getType()) { + return group; + } + } + return new XBreakpointTypeGroup(breakpoint.getType()); + } + return null; + } +} diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java index 9732460e44ab..b152b869d3e7 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java @@ -15,7 +15,6 @@ */ package com.intellij.xdebugger.breakpoints.ui; -import com.intellij.xdebugger.breakpoints.XBreakpoint; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -26,7 +25,7 @@ import java.util.Collection; /** * @author nik */ -public abstract class XBreakpointGroupingRule, G extends XBreakpointGroup> { +public abstract class XBreakpointGroupingRule { private final String myId; private final String myPresentableName; diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java new file mode 100644 index 000000000000..aa4879ef1781 --- /dev/null +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.breakpoints.ui; + +import com.intellij.xdebugger.breakpoints.XBreakpointType; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * Created with IntelliJ IDEA. + * User: zajac + * Date: 23.05.12 + * Time: 15:55 + * To change this template use File | Settings | File Templates. + */ +public class XBreakpointTypeGroup extends XBreakpointGroup { + + private XBreakpointType myBreakpointType; + + public XBreakpointTypeGroup(XBreakpointType type) { + myBreakpointType = type; + } + + @NotNull + @Override + public String getName() { + return myBreakpointType.getTitle(); + } + + public XBreakpointType getBreakpointType() { + return myBreakpointType; + } + + @Override + public Icon getIcon(boolean isOpen) { + return myBreakpointType.getEnabledIcon(); + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java index 96891234d401..3df95722ff41 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java @@ -18,8 +18,10 @@ package com.intellij.xdebugger.impl.breakpoints; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.ui.ColoredListCellRenderer; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.popup.util.DetailView; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.breakpoints.XBreakpoint; @@ -44,15 +46,25 @@ class XBreakpointItem extends BreakpointItem { @Override public void setupRenderer(ColoredListCellRenderer renderer, Project project, boolean selected) { - renderer.setIcon(getIcon()); - renderer.append(XBreakpointUtil.getShortText(myBreakpoint)); + setupGenericRenderer(renderer); + } + + @Override + public void setupRenderer(ColoredTreeCellRenderer renderer) { + setupGenericRenderer(renderer); + } + + protected void setupGenericRenderer(SimpleColoredComponent renderer) { + //renderer.setIcon(getIcon()); + final SimpleTextAttributes attributes = + myBreakpoint.isEnabled() ? SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES : SimpleTextAttributes.GRAYED_ATTRIBUTES; + renderer.append(XBreakpointUtil.getShortText(myBreakpoint), attributes); } private Icon getIcon() { return ((XBreakpointBase)myBreakpoint).getIcon(); } - @Override public String speedSearchText() { return ((XBreakpointBase)myBreakpoint).getType().getDisplayText(myBreakpoint); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java index eaabb8bc8e7d..5529ba0af3d4 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java @@ -17,26 +17,28 @@ package com.intellij.xdebugger.impl.breakpoints; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.popup.util.ItemWrapper; -import com.intellij.ui.popup.util.SplitterItem; -import com.intellij.xdebugger.breakpoints.*; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.breakpoints.*; +import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingByTypeRule; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import com.intellij.xdebugger.impl.breakpoints.ui.AbstractBreakpointPanel; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider; import com.intellij.xdebugger.impl.breakpoints.ui.XBreakpointsPanel; +import com.intellij.xdebugger.impl.breakpoints.ui.grouping.XBreakpointFileGroupingRule; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -47,6 +49,12 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider myListeners = new CopyOnWriteArrayList(); + @Override + public void provideBreakpointsGroupingRules(Collection rules) { + rules.add(new XBreakpointGroupingByTypeRule()); + rules.add(new XBreakpointFileGroupingRule()); + } + @Override public void addListener(BreakpointsListener listener, Project project) { final MyXBreakpointListener listener1 = new MyXBreakpointListener(listener); @@ -129,13 +137,12 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider items) { + public void provideBreakpointItems(Project project, Collection items) { final XBreakpointType[] types = XBreakpointUtil.getBreakpointTypes(); final XBreakpointManager manager = XDebuggerManager.getInstance(project).getBreakpointManager(); for (XBreakpointType type : types) { final Collection> breakpoints = manager.getBreakpoints(type); if (breakpoints.isEmpty()) continue; - items.add(new SplitterItem(type.getTitle())); for (XBreakpoint breakpoint : breakpoints) { items.add(new XBreakpointItem(breakpoint)); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItemsTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItemsTree.java new file mode 100644 index 000000000000..7392d9e24881 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItemsTree.java @@ -0,0 +1,271 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.breakpoints.ui; + +import com.intellij.ide.util.treeView.TreeState; +import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.ui.CheckboxTree; +import com.intellij.ui.CheckedTreeNode; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.ui.tree.TreeUtil; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XBreakpointManager; +import com.intellij.xdebugger.breakpoints.XBreakpointType; +import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.util.*; + +/** + * @author nik, zajac + */ +public class BreakpointItemsTree extends CheckboxTree { + //private final TreeNodeComparator myComparator; + private final CheckedTreeNode myRoot; + private final Map myNodes = new HashMap(); + private List myGroupingRules; + private final Map myGroupNodes = new HashMap(); + + private BreakpointItemsTreeDelegate myDelegate; + + private final MultiValuesMap myGroups = new MultiValuesMap(); + + private BreakpointItemsTree(final CheckedTreeNode root, + Collection groupingRules) { + super(new BreakpointsTreeCellRenderer(), root); + myRoot = root; + //myComparator = new TreeNodeComparator(type, breakpointManager); + setGroupingRulesInternal(groupingRules); + + getEmptyText().setText("No Breakpoints"); + } + + public void setDelegate(BreakpointItemsTreeDelegate delegate) { + myDelegate = delegate; + } + + private void setGroupingRulesInternal(final Collection groupingRules) { + myGroupingRules = new ArrayList(groupingRules); + setShowsRootHandles(!groupingRules.isEmpty()); + } + + public static BreakpointItemsTree createTree(final Collection groupingRules) { + return new BreakpointItemsTree(new CheckedTreeNode("root"), groupingRules); + } + + public void buildTree(@NotNull Collection breakpoints) { + final TreeState state = TreeState.createOn(this, myRoot); + myRoot.removeAllChildren(); + myNodes.clear(); + myGroupNodes.clear(); + myGroups.clear(); + for (BreakpointItem breakpoint : breakpoints) { + BreakpointItemNode node = new BreakpointItemNode(breakpoint); + CheckedTreeNode parent = getParentNode(breakpoint); + parent.add(node); + myNodes.put(breakpoint, node); + } + //TreeUtil.sort(myRoot, myComparator); + ((DefaultTreeModel)getModel()).nodeStructureChanged(myRoot); + expandPath(new TreePath(myRoot)); + state.applyTo(this, myRoot); + } + + + @NotNull + private CheckedTreeNode getParentNode(final BreakpointItem breakpoint) { + CheckedTreeNode parent = myRoot; + for (int i = 0; i < myGroupingRules.size(); i++) { + XBreakpointGroup group = getGroup(breakpoint.getBreakpoint(), myGroupingRules.get(i)); + if (group != null) { + parent = getOrCreateGroupNode(parent, group, i); + } + } + return parent; + } + + private BreakpointsGroupNode getOrCreateGroupNode(CheckedTreeNode parent, final G group, + final int level) { + //noinspection unchecked + BreakpointsGroupNode groupNode = (BreakpointsGroupNode)myGroupNodes.get(group); + if (groupNode == null) { + groupNode = new BreakpointsGroupNode(group, level); + myGroupNodes.put(group, groupNode); + parent.add(groupNode); + } + return groupNode; + } + + @Override + protected void onDoubleClick(CheckedTreeNode node) { + if (node instanceof BreakpointItemNode) { + myDelegate.execute(((BreakpointItemNode)node).getBreakpointItem()); + } + } + + @Nullable + private XBreakpointGroup getGroup(final Object breakpoint, final XBreakpointGroupingRule groupingRule) { + //noinspection unchecked + Collection groups = myGroups.get(groupingRule); + if (groups == null) { + groups = Collections.emptyList(); + } + XBreakpointGroup group = groupingRule.getGroup(breakpoint, groups); + if (group != null) { + myGroups.put(groupingRule, group); + } + return group; + } + + @Override + protected void onNodeStateChanged(final CheckedTreeNode node) { + if (node instanceof BreakpointItemNode) { + ((BreakpointItemNode)node).getBreakpointItem().setEnabled(node.isChecked()); + } + } + + public void setGroupingRules(List groupingRules) { + List selectedBreakpoints = getSelectedBreakpoints(); + List allBreakpoints = new ArrayList(myNodes.keySet()); + + setGroupingRulesInternal(groupingRules); + buildTree(allBreakpoints); + + if (selectedBreakpoints.size() > 0) { + selectBreakpointItem(selectedBreakpoints.get(0)); + } + } + + public List getSelectedBreakpoints() { + final ArrayList list = new ArrayList(); + TreePath[] selectionPaths = getSelectionPaths(); + if (selectionPaths == null || selectionPaths.length == 0) return list; + + for (TreePath selectionPath : selectionPaths) { + TreeUtil.traverseDepth((TreeNode)selectionPath.getLastPathComponent(), new TreeUtil.Traverse() { + public boolean accept(final Object node) { + if (node instanceof BreakpointItemNode) { + list.add(((BreakpointItemNode)node).getBreakpointItem()); + } + return true; + } + }); + } + + return list; + } + + public void selectBreakpointItem(final BreakpointItem breakpoint) { + BreakpointItemNode node = myNodes.get(breakpoint); + if (node != null) { + TreeUtil.selectNode(this, node); + } + } + + private static class BreakpointsTreeCellRenderer extends CheckboxTreeCellRenderer { + @Override + public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + if (value instanceof BreakpointItemNode) { + BreakpointItemNode node = (BreakpointItemNode)value; + BreakpointItem breakpoint = node.getBreakpointItem(); + breakpoint.setupRenderer(getTextRenderer()); + } + else if (value instanceof BreakpointsGroupNode) { + XBreakpointGroup group = ((BreakpointsGroupNode)value).getGroup(); + getTextRenderer().setIcon(group.getIcon(expanded)); + getTextRenderer().append(group.getName(), SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES); + } + } + } + + private static class BreakpointsGroupNode extends CheckedTreeNode { + private final G myGroup; + private final int myLevel; + + private BreakpointsGroupNode(G group, int level) { + super(group); + myLevel = level; + setChecked(false); + myGroup = group; + } + + public G getGroup() { + return myGroup; + } + + public int getLevel() { + return myLevel; + } + } + + private static class BreakpointItemNode extends CheckedTreeNode { + private final BreakpointItem myBreakpoint; + + private BreakpointItemNode(final BreakpointItem breakpoint) { + super(breakpoint); + myBreakpoint = breakpoint; + setChecked(breakpoint.isEnabled()); + } + + public BreakpointItem getBreakpointItem() { + return myBreakpoint; + } + } + + private static class TreeNodeComparator> implements Comparator { + private final Comparator myBreakpointComparator; + private final XBreakpointManager myBreakpointManager; + + public TreeNodeComparator(final XBreakpointType type, XBreakpointManager breakpointManager) { + myBreakpointManager = breakpointManager; + myBreakpointComparator = type.getBreakpointComparator(); + } + + public int compare(final TreeNode o1, final TreeNode o2) { + if (o1 instanceof BreakpointItemNode && o2 instanceof BreakpointItemNode) { + //noinspection unchecked + B b1 = (B)((BreakpointItemNode)o1).getBreakpointItem(); + //noinspection unchecked + B b2 = (B)((BreakpointItemNode)o2).getBreakpointItem(); + boolean default1 = myBreakpointManager.isDefaultBreakpoint(b1); + boolean default2 = myBreakpointManager.isDefaultBreakpoint(b2); + if (default1 && !default2) return -1; + if (!default1 && default2) return 1; + return myBreakpointComparator.compare(b1, b2); + } + if (o1 instanceof BreakpointsGroupNode && o2 instanceof BreakpointsGroupNode) { + final BreakpointsGroupNode group1 = (BreakpointsGroupNode)o1; + final BreakpointsGroupNode group2 = (BreakpointsGroupNode)o2; + if (group1.getLevel() != group2.getLevel()) { + return group1.getLevel() - group2.getLevel(); + } + return group1.getGroup().compareTo(group2.getGroup()); + } + return o1 instanceof BreakpointsGroupNode ? -1 : 1; + } + } + + public interface BreakpointItemsTreeDelegate { + void execute(BreakpointItem item); + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java index b069579512b1..954a4ddcb564 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java @@ -20,7 +20,8 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.ui.popup.util.ItemWrapper; +import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,6 +32,8 @@ import java.util.Collection; */ public abstract class BreakpointPanelProvider { + public abstract void provideBreakpointsGroupingRules(Collection rules); + public interface BreakpointsListener { void breakpointsChanged(); } @@ -54,5 +57,5 @@ public abstract class BreakpointPanelProvider { public abstract void onDialogClosed(final Project project); - public abstract void provideBreakpointItems(Project project, Collection items); + public abstract void provideBreakpointItems(Project project, Collection items); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java index e845a7539448..e8ddf05d8e57 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java @@ -17,30 +17,33 @@ package com.intellij.xdebugger.impl.breakpoints.ui; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.actionSystem.ex.CheckboxAction; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager; +import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl; +import com.intellij.openapi.editor.markup.EffectType; +import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.JBPopupListener; import com.intellij.openapi.ui.popup.LightweightWindowEvent; -import com.intellij.ui.CheckBoxListListener; -import com.intellij.ui.components.JBList; -import com.intellij.ui.popup.util.ItemWrapper; +import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.popup.util.MasterDetailPopupBuilder; import com.intellij.util.IconUtil; import com.intellij.util.PlatformIcons; import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import com.intellij.xdebugger.impl.DebuggerSupport; +import com.intellij.xdebugger.ui.DebuggerColors; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; import java.awt.event.KeyEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; +import java.util.*; import java.util.List; /** @@ -50,12 +53,10 @@ import java.util.List; * Time: 3:11 AM * To change this template use File | Settings | File Templates. */ -public class BreakpointsMasterDetailPopupFactory implements CheckBoxListListener { +public class BreakpointsMasterDetailPopupFactory { private final List myBreakpointPanelProviders; private Project myProject; - private BreakpointListModel myModel; - private MasterDetailPopupBuilder myPopupBuilder; public BreakpointsMasterDetailPopupFactory(Project project) { myProject = project; @@ -71,36 +72,43 @@ public class BreakpointsMasterDetailPopupFactory implements CheckBoxListListener }); } - @Override - public void checkBoxSelectionChanged(int index, boolean value) { - final Object o = myModel.get(index); - if (o instanceof BreakpointItem) { - ((BreakpointItem)o).setEnabled(value); - } - } - public static BreakpointsMasterDetailPopupFactory getInstance(Project project) { return ServiceManager.getService(project, BreakpointsMasterDetailPopupFactory.class); } public JBPopup createPopup(@Nullable Object initialBreakpoint) { - final DefaultListSelectionModel selectionModel = new DefaultListSelectionModel(); - myModel = createBreakpointsItemsList(selectionModel); - final JBList list = new JBList(myModel); + MasterDetailPopupBuilder popupBuilder = new MasterDetailPopupBuilder(myProject); - list.setSelectionModel(selectionModel); + DefaultActionGroup actions = getActions(popupBuilder); - selectInitial(initialBreakpoint, myModel, list); + final Collection rules = new ArrayList(); - list.getEmptyText().setText("No Breakpoints"); + for (BreakpointPanelProvider provider : myBreakpointPanelProviders) { + provider.provideBreakpointsGroupingRules(rules); + } - DefaultActionGroup actions = getActions(list); + final BreakpointItemsTree tree = BreakpointItemsTree.createTree(rules); - myPopupBuilder = new MasterDetailPopupBuilder(myProject); - final JBPopup popup = myPopupBuilder. + final ArrayList breakpoints = collectItems(); + tree.buildTree(breakpoints); + + + + final BreakpointPanelProvider.BreakpointsListener listener = new BreakpointPanelProvider.BreakpointsListener() { + @Override + public void breakpointsChanged() { + tree.buildTree(collectItems()); + } + }; + + for (BreakpointPanelProvider provider : myBreakpointPanelProviders) { + provider.addListener(listener, myProject); + } + + final JBPopup popup = popupBuilder. setActionsGroup(actions). - setList(list). + setTree(tree). setDelegate(new MasterDetailPopupBuilder.Delegate() { @Override public String getTitle() { @@ -115,8 +123,27 @@ public class BreakpointsMasterDetailPopupFactory implements CheckBoxListListener public JComponent createAccessoryView(Project project) { return new JCheckBox(); } + + @Override + public Object[] getSelectedItemsInTree() { + final List res = tree.getSelectedBreakpoints(); + return res.toArray(new Object[res.size()]); + } }).setCloseOnEnter(false).createMasterDetailPopup(); + tree.setBorder(IdeBorderFactory.createBorder()); + + popupBuilder.getDetailView().setScheme(createScheme()); + + tree.setDelegate(new BreakpointItemsTree.BreakpointItemsTreeDelegate() { + @Override + public void execute(BreakpointItem item) { + item.execute(myProject, popup); + } + }); + + initSelection(initialBreakpoint, tree, breakpoints); + popup.addListener(new JBPopupListener() { @Override public void beforeShown(LightweightWindowEvent event) { @@ -125,26 +152,39 @@ public class BreakpointsMasterDetailPopupFactory implements CheckBoxListListener @Override public void onClosed(LightweightWindowEvent event) { - myModel.unsubscribe(); + for (BreakpointPanelProvider provider : myBreakpointPanelProviders) { + provider.removeListener(listener); + } } }); return popup; } - private void selectInitial(Object initialBreakpoint, BreakpointListModel model, JBList list) { - for (int i = 0, l = model.size(); i < l; ++i) { - final ItemWrapper item = (ItemWrapper)model.get(i); - if (item instanceof BreakpointItem) { - if (((BreakpointItem)item).getBreakpoint() == initialBreakpoint) { - list.setSelectedIndex(i); - break; - } + private void initSelection(Object initialBreakpoint, BreakpointItemsTree tree, ArrayList breakpoints) { + boolean found = false; + for (BreakpointItem breakpoint : breakpoints) { + if (breakpoint.getBreakpoint() == initialBreakpoint) { + tree.selectBreakpointItem(breakpoint); + found = true; + break; } } + + if (!found && !breakpoints.isEmpty()) { + tree.selectBreakpointItem(breakpoints.get(0)); + } } - private DefaultActionGroup getActions(final JBList list) { + private EditorColorsScheme createScheme() { + final EditorColorsScheme scheme = + new EditorColorsSchemeImpl(EditorColorsManager.getInstance().getGlobalScheme(), DefaultColorSchemesManager.getInstance()); + scheme.setName("abc"); + scheme.setAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES, new TextAttributes(Color.black, Color.CYAN, null, EffectType.BOXED, Font.BOLD)); + return scheme; + } + + private DefaultActionGroup getActions(final MasterDetailPopupBuilder builder) { DefaultActionGroup actions = new DefaultActionGroup(); final DefaultActionGroup breakpointTypes = new DefaultActionGroup(); for (BreakpointPanelProvider provider : myBreakpointPanelProviders) { @@ -156,105 +196,29 @@ public class BreakpointsMasterDetailPopupFactory implements CheckBoxListListener JBPopupFactory.getInstance() .createActionGroupPopup(null, breakpointTypes, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, false) - .showUnderneathOf(myPopupBuilder.getActionToolbar().getComponent()); + .showUnderneathOf(builder.getActionToolbar().getComponent()); } }); actions.add(new AnAction("Remove Breakpoint", null, PlatformIcons.DELETE_ICON) { @Override public void update(AnActionEvent e) { - e.getPresentation().setEnabled(MasterDetailPopupBuilder.allowedToRemoveSelectedItem(list, myProject)); + e.getPresentation().setEnabled(MasterDetailPopupBuilder.allowedToRemoveItems(builder.getSelectedItems())); } @Override public void actionPerformed(AnActionEvent e) { - MasterDetailPopupBuilder.removeSelectedItems(list, myProject); + builder.removeSelectedItems(myProject); } }); return actions; } - private BreakpointListModel createBreakpointsItemsList(DefaultListSelectionModel selectionModel) { - final BreakpointListModel model = new BreakpointListModel(); - final ArrayList items = collectItems(); - for (ItemWrapper item : items) { - model.addElement(item); - } - model.subscribe(selectionModel); - return model; - } - - - private ArrayList collectItems() { - ArrayList items = new ArrayList(); + private ArrayList collectItems() { + ArrayList items = new ArrayList(); for (BreakpointPanelProvider panelProvider : myBreakpointPanelProviders) { panelProvider.provideBreakpointItems(myProject, items); } return items; } - - private class BreakpointListModel extends DefaultListModel { - List myListeners = new ArrayList(); - - private void subscribe(DefaultListSelectionModel selectionModel) { - for (BreakpointPanelProvider panelProvider : myBreakpointPanelProviders) { - final BreakpointPanelProvider.BreakpointsListener listener = new MyBreakpointsListener(this, selectionModel); - panelProvider.addListener(listener, myProject); - myListeners.add(listener); - } - } - - public void unsubscribe() { - for (int i = 0, size = myListeners.size(); i < size; i++) { - BreakpointPanelProvider.BreakpointsListener listener = myListeners.get(i); - myBreakpointPanelProviders.get(i).removeListener(listener); - } - } - - private class MyBreakpointsListener implements BreakpointPanelProvider.BreakpointsListener { - private final DefaultListModel myModel; - private DefaultListSelectionModel mySelectionModel; - - public MyBreakpointsListener(DefaultListModel model, DefaultListSelectionModel selectionModel) { - myModel = model; - mySelectionModel = selectionModel; - } - - @Override - public void breakpointsChanged() { - final ArrayList items = collectItems(); - if (!reallyChanged(items, myModel)) { - return; - } - rebuildModel(items, mySelectionModel, myModel); - } - - } - } - - private static void rebuildModel(ArrayList items, ListSelectionModel model, DefaultListModel model1) { - final int index = model.getLeadSelectionIndex(); - model1.removeAllElements(); - for (ItemWrapper item : items) { - model1.addElement(item); - } - model.setLeadSelectionIndex(index); - } - - private static boolean reallyChanged(List items, DefaultListModel model) { - if (items.size() != model.size()) return true; - for (int i = 0; i < model.size(); i++) { - final ItemWrapper item1 = items.get(i); - final ItemWrapper item2 = (ItemWrapper)model.get(i); - if (item1.getClass() != item2.getClass()) { - return true; - } - if (item1 instanceof BreakpointItem) { - if (((BreakpointItem)item1).getBreakpoint() != ((BreakpointItem)item2).getBreakpoint()) { - return true; - } - } - } - return false; - } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java index c0318d811356..6c09cd0a2883 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java @@ -27,13 +27,17 @@ import java.util.Collection; /** * @author nik */ -public class XBreakpointFileGroupingRule> extends XBreakpointGroupingRule { +public class XBreakpointFileGroupingRule extends XBreakpointGroupingRule { public XBreakpointFileGroupingRule() { super("by-file", XDebuggerBundle.message("rule.name.group.by.file")); } public XBreakpointFileGroup getGroup(@NotNull final B breakpoint, @NotNull final Collection groups) { - XSourcePosition position = breakpoint.getSourcePosition(); + if (!(breakpoint instanceof XLineBreakpoint)) { + return null; + } + XSourcePosition position = ((XLineBreakpoint)breakpoint).getSourcePosition(); + if (position == null) return null; VirtualFile file = position.getFile(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java b/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java index 2d10d5529ec2..5ab72dbf62ce 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java +++ b/plugins/InspectionGadgets/src/com/siyeh/HardcodedMethodConstants.java @@ -15,6 +15,7 @@ */ package com.siyeh; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import org.jetbrains.annotations.NonNls; /** @@ -57,7 +58,7 @@ public class HardcodedMethodConstants { public static final String PRINT_STACK_TRACE = "printStackTrace"; public static final String REMOVE = "remove"; public static final String RUN = "run"; - public static final String SERIAL_VERSION_UID = "serialVersionUID"; + public static final String SERIAL_VERSION_UID = HighlightUtil.SERIAL_VERSION_UID_FIELD_NAME; public static final String SET = "set"; public static final String SIZE = "size"; public static final String STARTS_WITH = "startsWith"; diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.form b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.form index 9939252ad686..660726ca673b 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.form +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/AdvancedSettingsUI.form @@ -15,7 +15,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -120,7 +120,7 @@ - + diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index d9759cd5802e..41d59b6dc7a3 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -37,7 +37,6 @@ replace.switch.with.if.intention.name=Replace 'switch' with 'if' replace.switch.with.if.intention.family.name=Replace Switch with If simplify.variable.intention.name=Replace with Java-style array declaration simplify.variable.intention.family.name=Replace with Java Style Array Declaration -constant.expression.intention.name=Compute constant value constant.expression.intention.family.name=Compute Constant Value create.assert.intention.name=Create JUnit Assertion create.assert.intention.family.name=Create JUnit Assertion @@ -176,7 +175,7 @@ add.braces.intention.name=Add Braces to ''{0}'' statement remove.braces.intention.name=Remove braces from ''{0}'' statement flip.commutative.method.call.intention.name=Flip ''.{0}()'' flip.commutative.method.call.intention.name1=Flip ''.{0}()'' (may change semantics) -constant.subexpression.intention.name=Compute constant value of ''{0}'' +constant.expression.intention.name=Compute constant value of ''{0}'' status.bar.escape.highlighting.message=Press Escape to remove the highlighting 1.fully.qualified.name.status.bar.escape.highlighting.message=1 fully qualified name replaced with import (press Escape to remove highlighting) multiple.fully.qualified.names.status.bar.escape.highlighting.message={0} fully qualified names replaced with import (press Escape to remove highlighting) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java index ba3e54e0f2b9..4c597df5d2ba 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,24 @@ package com.siyeh.ipp.constant; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; import com.intellij.util.IncorrectOperationException; -import com.siyeh.ipp.base.Intention; +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ExpressionUtils; +import com.siyeh.ipp.psiutils.HighlightUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -public class ConstantExpressionIntention extends Intention { +public class ConstantExpressionIntention extends MutablyNamedIntention { + + @Override + protected String getTextForElement(PsiElement element) { + final String text = HighlightUtil.getPresentableText(element); + return IntentionPowerPackBundle.message("constant.expression.intention.name", text); + } @Override @NotNull @@ -33,22 +42,16 @@ public class ConstantExpressionIntention extends Intention { } @Override - public void processIntention(PsiElement element) - throws IncorrectOperationException { - final PsiExpression expression = - (PsiExpression)element; - final Object value = - ExpressionUtils.computeConstantExpression(expression); + public void processIntention(PsiElement element) throws IncorrectOperationException { + final PsiExpression expression = (PsiExpression)element; + final Object value = ExpressionUtils.computeConstantExpression(expression); @NonNls final String newExpression; if (value instanceof String) { final String string = (String)value; - newExpression = - '"' + StringUtil.escapeStringCharacters(string) + '"'; + newExpression = '"' + StringUtil.escapeStringCharacters(string) + '"'; } else if (value instanceof Character) { - newExpression = - '\'' + StringUtil.escapeStringCharacters(value.toString()) + - '\''; + newExpression = '\'' + StringUtil.escapeStringCharacters(value.toString()) + '\''; } else if (value instanceof Long) { newExpression = value.toString() + 'L'; diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java index 53a5fc14acdf..fad82cd3fa2d 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantExpressionPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,28 +24,34 @@ import com.siyeh.ipp.psiutils.ExpressionUtils; class ConstantExpressionPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiBinaryExpression)) { + if (!(element instanceof PsiPolyadicExpression)) { return false; } - if (element instanceof PsiLiteralExpression || - element instanceof PsiClassObjectAccessExpression) { + if (element instanceof PsiLiteralExpression || element instanceof PsiClassObjectAccessExpression) { return false; } - final PsiBinaryExpression expression = (PsiBinaryExpression)element; - final PsiExpression rhs = expression.getROperand(); - if (rhs == null) { + final PsiPolyadicExpression expression = (PsiPolyadicExpression)element; + final PsiType expressionType = expression.getType(); + if (expressionType == null || expressionType.equalsToText("java.lang.String")) { + // intention disabled for string concatenations because of performance issues on + // relatively common large string expressions. return false; } - final PsiType type = rhs.getType(); - if (type == null || type.equalsToText("java.lang.String")) { - return false; + final PsiExpression[] operands = expression.getOperands(); + for (PsiExpression operand : operands) { + if (operand == null) { + return false; + } + final PsiType type = operand.getType(); + if (type == null || type.equalsToText("java.lang.String")) { + return false; + } } if (!PsiUtil.isConstantExpression(expression)) { return false; } try { - final Object value = - ExpressionUtils.computeConstantExpression(expression, true); + final Object value = ExpressionUtils.computeConstantExpression(expression, true); if (value == null) { return false; } @@ -54,7 +60,6 @@ class ConstantExpressionPredicate implements PsiElementPredicate { return false; } final PsiElement parent = element.getParent(); - return !(parent instanceof PsiExpression && - PsiUtil.isConstantExpression((PsiExpression)parent)); + return !(parent instanceof PsiExpression) || !PsiUtil.isConstantExpression((PsiExpression)parent); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java index d638fc6a4ecf..3b02069a5913 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,13 @@ */ package com.siyeh.ipp.constant; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiBinaryExpression; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiJavaToken; +import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; -import com.siyeh.ipp.psiutils.ConcatenationUtils; import com.siyeh.ipp.psiutils.ExpressionUtils; +import com.siyeh.ipp.psiutils.HighlightUtil; import org.jetbrains.annotations.NotNull; public class ConstantSubexpressionIntention extends MutablyNamedIntention { @@ -38,108 +34,109 @@ public class ConstantSubexpressionIntention extends MutablyNamedIntention { @Override protected String getTextForElement(PsiElement element) { - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)element.getParent(); - assert binaryExpression != null; - final PsiExpression lhs = binaryExpression.getLOperand(); - final PsiExpression leftSide; - if (lhs instanceof PsiBinaryExpression) { - final PsiBinaryExpression lhsBinaryExpression = - (PsiBinaryExpression)lhs; - leftSide = lhsBinaryExpression.getROperand(); + final PsiJavaToken token; + if (element instanceof PsiJavaToken) { + token = (PsiJavaToken)element; + } else { + final PsiElement prevSibling = element.getPrevSibling(); + if (prevSibling instanceof PsiJavaToken) { + token = (PsiJavaToken)prevSibling; + } else { + throw new AssertionError(); + } } - else { - leftSide = lhs; - } - final PsiJavaToken operationSign = binaryExpression.getOperationSign(); - final PsiExpression rhs = binaryExpression.getROperand(); - assert rhs != null; - assert leftSide != null; - return IntentionPowerPackBundle.message( - "constant.subexpression.intention.name", leftSide.getText() + - ' ' + operationSign.getText() + ' ' + rhs.getText()); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)element.getParent(); + final PsiPolyadicExpression subexpression = ConstantSubexpressionPredicate.getSubexpression(polyadicExpression, token); + final String text = HighlightUtil.getPresentableText(subexpression); + return IntentionPowerPackBundle.message("constant.expression.intention.name", text); } @Override - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - final PsiExpression expression = (PsiExpression)element.getParent(); - assert expression != null; - String newExpression = ""; - final Object constantValue; - if (expression instanceof PsiBinaryExpression) { - final PsiBinaryExpression copy = - (PsiBinaryExpression)expression.copy(); - final PsiExpression lhs = copy.getLOperand(); - if (lhs instanceof PsiBinaryExpression) { - final PsiBinaryExpression lhsBinaryExpression = - (PsiBinaryExpression)lhs; - newExpression += getLeftSideText(lhsBinaryExpression); - final PsiExpression rightSide = - lhsBinaryExpression.getROperand(); - assert rightSide != null; - lhs.replace(rightSide); - } - if (ConcatenationUtils.isConcatenation(expression)) { - constantValue = computeConstantStringExpression(copy); - } - else { - constantValue = - ExpressionUtils.computeConstantExpression(copy); + public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + final PsiJavaToken token; + if (element instanceof PsiJavaToken) { + token = (PsiJavaToken)element; + } else { + final PsiElement prevSibling = element.getPrevSibling(); + if (prevSibling instanceof PsiJavaToken) { + token = (PsiJavaToken)prevSibling; + } else { + throw new AssertionError(); } } - else { - constantValue = - ExpressionUtils.computeConstantExpression(expression); - } - if (constantValue instanceof String) { - newExpression += '"' + StringUtil.escapeStringCharacters( - constantValue.toString()) + '"'; - } - else if (constantValue != null) { - if (constantValue instanceof Number) { - final Number number = (Number)constantValue; - if (0 > number.doubleValue()) { - newExpression += " "; + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)element.getParent(); + final PsiPolyadicExpression subexpression = ConstantSubexpressionPredicate.getSubexpression(polyadicExpression, token); + final Object value = ExpressionUtils.computeConstantExpression(subexpression); + final StringBuilder newExpressionText = new StringBuilder(); + final PsiExpression[] operands = polyadicExpression.getOperands(); + PsiExpression prevOperand = null; + PsiJavaToken prevToken = null; + for (PsiExpression operand : operands) { + final PsiJavaToken currentToken = polyadicExpression.getTokenBeforeOperand(operand); + if (token == currentToken) { + if (prevToken != null) { + newExpressionText.append(prevToken.getText()); } + if (newExpressionText.length() > 0) { + newExpressionText.append(' '); + } + if (value instanceof Long) { + newExpressionText.append(value).append('L'); + } else if (value instanceof Double) { + final double v = ((Double)value).doubleValue(); + if (Double.isNaN(v)) { + newExpressionText.append("java.lang.Double.NaN"); + } + else if (Double.isInfinite(v)) { + if (v > 0.0) { + newExpressionText.append("java.lang.Double.POSITIVE_INFINITY"); + } + else { + newExpressionText.append("java.lang.Double.NEGATIVE_INFINITY"); + } + } + else { + newExpressionText.append(Double.toString(v)); + } + } + else if (value instanceof Float) { + final float v = ((Float)value).floatValue(); + if (Float.isNaN(v)) { + newExpressionText.append("java.lang.Float.NaN"); + } + else if (Float.isInfinite(v)) { + if (v > 0.0F) { + newExpressionText.append("java.lang.Float.POSITIVE_INFINITY"); + } + else { + newExpressionText.append("java.lang.Float.NEGATIVE_INFINITY"); + } + } + else { + newExpressionText.append(Float.toString(v)).append('f'); + } + } else { + newExpressionText.append(value); + } + prevOperand = null; + prevToken = null; + } else { + if (prevToken != null) { + newExpressionText.append(prevToken.getText()); + } + if (prevOperand != null) { + newExpressionText.append(prevOperand.getText()); + } + prevOperand = operand; + prevToken = currentToken; } - newExpression += constantValue.toString(); } - replaceExpression(newExpression, expression); - } - - /** - * handles the specified expression as if it was part of a string expression - * (even if it's of another type) and computes a constant string expression - * from it. - */ - private static String computeConstantStringExpression( - PsiBinaryExpression expression) { - final PsiExpression lhs = expression.getLOperand(); - final String lhsText = lhs.getText(); - String result; - if (lhsText.charAt(0) == '\'' || lhsText.charAt(0) == '"') { - result = lhsText.substring(1, lhsText.length() - 1); + if (prevToken != null) { + newExpressionText.append(prevToken.getText()); } - else { - result = lhsText; + if (prevOperand != null) { + newExpressionText.append(prevOperand.getText()); } - final PsiExpression rhs = expression.getROperand(); - assert rhs != null; - final String rhsText = rhs.getText(); - if (rhsText.charAt(0) == '\'' || rhsText.charAt(0) == '"') { - result += rhsText.substring(1, rhsText.length() - 1); - } - else { - result += rhsText; - } - return result; - } - - private static String getLeftSideText( - PsiBinaryExpression binaryExpression) { - final PsiExpression lhs = binaryExpression.getLOperand(); - final PsiJavaToken sign = binaryExpression.getOperationSign(); - return lhs.getText() + sign.getText(); + replaceExpression(newExpressionText.toString(), polyadicExpression); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java index bbe065227f63..77be61f4118b 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/constant/ConstantSubexpressionPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,47 +19,71 @@ import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ExpressionUtils; -import org.jetbrains.annotations.Nullable; class ConstantSubexpressionPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiJavaToken) && - !(element.getPrevSibling() instanceof PsiJavaToken)) { - return false; + final PsiJavaToken token; + if (element instanceof PsiJavaToken) { + token = (PsiJavaToken)element; } + else { + final PsiElement prevSibling = element.getPrevSibling(); + if (prevSibling instanceof PsiJavaToken) { + token = (PsiJavaToken)prevSibling; + } + else { + return false; + } + } + final PsiElement parent = element.getParent(); - if (!(parent instanceof PsiBinaryExpression)) { + if (!(parent instanceof PsiPolyadicExpression)) { return false; } - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)parent; - final PsiType type = binaryExpression.getType(); + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent; + final PsiType type = polyadicExpression.getType(); if (type == null || type.equalsToText("java.lang.String")) { // handled by JoinConcatenatedStringLiteralsIntention return false; } - final PsiBinaryExpression subexpression = - getSubexpression(binaryExpression); + final PsiPolyadicExpression subexpression = getSubexpression(polyadicExpression, token); if (subexpression == null) { return false; } - if (binaryExpression.equals(subexpression) && - !isPartOfConstantExpression(binaryExpression)) { - // handled by ConstantExpressonIntention + if (!isPartOfLargerExpression(polyadicExpression)) { + // handled by ConstantExpressionIntention return false; } if (!PsiUtil.isConstantExpression(subexpression)) { return false; } - final Object value = - ExpressionUtils.computeConstantExpression(subexpression); + final Object value = ExpressionUtils.computeConstantExpression(subexpression); return value != null; } - private static boolean isPartOfConstantExpression( - PsiBinaryExpression binaryExpression) { - final PsiElement containingElement = binaryExpression.getParent(); + static PsiPolyadicExpression getSubexpression(PsiPolyadicExpression expression, PsiJavaToken token) { + final PsiExpression[] operands = expression.getOperands(); + if (operands.length == 2) { + return expression; + } + for (int i = 1; i < operands.length; i++) { + final PsiExpression operand = operands[i]; + final PsiJavaToken currentToken = expression.getTokenBeforeOperand(operand); + if (currentToken == token) { + final String binaryExpressionText = operands[i - 1].getText() + ' ' + token.getText() + ' ' + operand.getText(); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(expression.getProject()); + return (PsiPolyadicExpression)factory.createExpressionFromText(binaryExpressionText, expression); + } + } + throw new AssertionError(); + } + + private static boolean isPartOfLargerExpression(PsiPolyadicExpression expression) { + if (expression.getOperands().length > 2) { + return true; + } + final PsiElement containingElement = expression.getParent(); if (containingElement instanceof PsiExpression) { final PsiExpression containingExpression = (PsiExpression)containingElement; @@ -72,38 +96,4 @@ class ConstantSubexpressionPredicate implements PsiElementPredicate { } return true; } - - /** - * Returns the smallest subexpression (if precendence allows it). example: - * variable + 2 + 3 normally gets evaluated left to right -> (variable + 2) - * + 3 this method returns the right most legal subexpression -> 2 + 3 - */ - @Nullable - private static PsiBinaryExpression getSubexpression( - PsiBinaryExpression expression) { - final PsiExpression rhs = expression.getROperand(); - if (rhs == null) { - return null; - } - final PsiExpression lhs = expression.getLOperand(); - if (!(lhs instanceof PsiBinaryExpression)) { - return expression; - } - final PsiBinaryExpression lhsBinaryExpression = - (PsiBinaryExpression)lhs; - final PsiExpression leftSide = lhsBinaryExpression.getROperand(); - if (leftSide == null) { - return null; - } - try { - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)expression.copy(); - final PsiExpression lOperand = binaryExpression.getLOperand(); - lOperand.replace(leftSide); - return binaryExpression; - } - catch (Throwable ignore) { - return null; - } - } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java index c7350f7cce1a..e03c5c876868 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/psiutils/HighlightUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2007-2011 Bas Leijdekkers + * Copyright 2007-2012 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -51,32 +52,24 @@ public class HighlightUtil { final Application application = ApplicationManager.getApplication(); application.invokeLater(new Runnable() { public void run() { - final PsiElement[] elements = - PsiUtilBase.toPsiElementArray(elementCollection); + final PsiElement[] elements = PsiUtilCore.toPsiElementArray(elementCollection); final PsiElement firstElement = elements[0]; if (!firstElement.isValid()) { return; } final Project project = firstElement.getProject(); - final FileEditorManager editorManager = - FileEditorManager.getInstance(project); - final EditorColorsManager editorColorsManager = - EditorColorsManager.getInstance(); + final FileEditorManager editorManager = FileEditorManager.getInstance(project); + final EditorColorsManager editorColorsManager = EditorColorsManager.getInstance(); final Editor editor = editorManager.getSelectedTextEditor(); if (editor == null) { return; } - final EditorColorsScheme globalScheme = - editorColorsManager.getGlobalScheme(); - final TextAttributes textattributes = - globalScheme.getAttributes( + final EditorColorsScheme globalScheme = editorColorsManager.getGlobalScheme(); + final TextAttributes textattributes = globalScheme.getAttributes( EditorColors.SEARCH_RESULT_ATTRIBUTES); - final HighlightManager highlightManager = - HighlightManager.getInstance(project); - highlightManager.addOccurrenceHighlights( - editor, elements, textattributes, true, null); - final FindManager findmanager = - FindManager.getInstance(project); + final HighlightManager highlightManager = HighlightManager.getInstance(project); + highlightManager.addOccurrenceHighlights(editor, elements, textattributes, true, null); + final FindManager findmanager = FindManager.getInstance(project); FindModel findmodel = findmanager.getFindNextModel(); if (findmodel == null) { findmodel = findmanager.getFindInFileModel(); @@ -86,11 +79,11 @@ public class HighlightUtil { findmanager.setFindNextModel(findmodel); application.invokeLater(new Runnable() { public void run() { - final WindowManager windowManager = - WindowManager.getInstance(); - final StatusBar statusBar = - windowManager.getStatusBar(project); - statusBar.setInfo(statusBarText); + final WindowManager windowManager = WindowManager.getInstance(); + final StatusBar statusBar = windowManager.getStatusBar(project); + if (statusBar != null) { + statusBar.setInfo(statusBarText); + } } }); } @@ -102,4 +95,27 @@ public class HighlightUtil { final List elements = Collections.singletonList(element); highlightElements(elements, statusBarText); } + + public static String getPresentableText(PsiElement element) { + return getPresentableText(element, new StringBuilder()).toString(); + } + + private static StringBuilder getPresentableText(PsiElement element, StringBuilder builder) { + if (element == null) { + return builder; + } + if (element instanceof PsiWhiteSpace) { + return builder.append(' '); + } + final PsiElement[] children = element.getChildren(); + if (children.length != 0) { + for (PsiElement child : children) { + getPresentableText(child, builder); + } + } + else { + builder.append(element.getText()); + } + return builder; + } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpAssign.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpAssign.java new file mode 100644 index 000000000000..ca45c9670725 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpAssign.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.opassign.assignment; + +class ByteOpassign { + + void foo(byte b) { + b += 1; + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpAssign_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpAssign_after.java new file mode 100644 index 000000000000..af4441527704 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpAssign_after.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.opassign.assignment; + +class ByteOpassign { + + void foo(byte b) { + b = (byte) (b + 1); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpassign.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpassign.java deleted file mode 100644 index ce6c0daca40f..000000000000 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpassign.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.siyeh.ipp.opassign.assignment; - -class ByteOpassign { - - void foo(byte b) { - b += 1; - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpassign_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpassign_after.java deleted file mode 100644 index e4daf05d38e4..000000000000 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/ByteOpassign_after.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.siyeh.ipp.opassign.assignment; - -class ByteOpassign { - - void foo(byte b) { - b = (byte) (b + 1); - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpAssign.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpAssign.java new file mode 100644 index 000000000000..2e8a0e5ba7a5 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpAssign.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.opassign.assignment; + +class DoubleOpassign { + + void foo(double d) { + d += 0.5; + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpAssign_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpAssign_after.java new file mode 100644 index 000000000000..fe005f3c66d2 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpAssign_after.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.opassign.assignment; + +class DoubleOpassign { + + void foo(double d) { + d = d + 0.5; + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpassign.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpassign.java deleted file mode 100644 index fb159c964e3b..000000000000 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpassign.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.siyeh.ipp.opassign.assignment; - -class DoubleOpassign { - - void foo(double d) { - d += 0.5; - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpassign_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpassign_after.java deleted file mode 100644 index fabb55a2a1c3..000000000000 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/DoubleOpassign_after.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.siyeh.ipp.opassign.assignment; - -class DoubleOpassign { - - void foo(double d) { - d = d + 0.5; - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpAssign.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpAssign.java index 71e98aacca73..eb953906a9be 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpAssign.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpAssign.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.siyeh.ipp.opassign.assignment; class StringOpassign { diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpAssign_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpAssign_after.java new file mode 100644 index 000000000000..feab030b8d20 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpAssign_after.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.opassign.assignment; + +class StringOpassign { + + void foo(String s) { + s = s + 1.0; + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpassign_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpassign_after.java deleted file mode 100644 index 5457c890258b..000000000000 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/opassign/assignment/StringOpassign_after.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.siyeh.ipp.opassign.assignment; - -class StringOpassign { - - void foo(String s) { - s = s + 1.0; - } -} \ No newline at end of file diff --git a/plugins/android-designer/src/META-INF/plugin.xml b/plugins/android-designer/src/META-INF/plugin.xml index 6fc6233692a6..e14f2545aae2 100644 --- a/plugins/android-designer/src/META-INF/plugin.xml +++ b/plugins/android-designer/src/META-INF/plugin.xml @@ -11,6 +11,7 @@ com.intellij.ui-designer-new + superComponentClass = componentClass.getSuperclass(); if (superComponentClass != null) { superComponentClass = configureClass(superComponentClass); + MetaModel superModel = myMetaManager.getModelByTarget(superComponentClass.getName()); - List superProperties = loadWidgetProperties(superComponentClass, - myMetaManager.getModelByTarget(superComponentClass.getName())); + if (model != null && superModel != null && model.getInplaceProperties().isEmpty()) { + model.setInplaceProperties(superModel.getInplaceProperties()); + } + + List superProperties = loadWidgetProperties(superComponentClass, superModel); for (Property superProperty : superProperties) { if (PropertyTable.findProperty(properties, superProperty) == -1) { if (model == null) { diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java index 6ce1ff5a0ced..986c1ecf75eb 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java @@ -22,6 +22,7 @@ import com.intellij.designer.model.MetaManager; import com.intellij.designer.model.MetaModel; import com.intellij.designer.model.RadComponent; import com.intellij.designer.propertyTable.Property; +import com.intellij.designer.propertyTable.PropertyTable; import com.intellij.openapi.module.Module; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.text.StringUtil; @@ -50,32 +51,6 @@ public class RadCustomViewComponent extends RadViewComponent implements IConfigu "\"/>"; } - @Override - public MetaModel getMetaModelForProperties() throws Exception { - MetaModel metaModel = getClientProperty(MODEL_KEY); - - if (metaModel == null) { - Module module = getRoot().getClientProperty(ModelParser.MODULE_KEY); - MetaManager metaManager = ViewsMetaManager.getInstance(module.getProject()); - PsiClass viewClass = ChooseClassDialog.findClass(module, getViewClass()); - - while (viewClass != null) { - metaModel = metaManager.getModelByTarget(viewClass.getQualifiedName()); - if (metaModel != null) { - break; - } - viewClass = viewClass.getSuperClass(); - } - if (metaModel == null) { - metaModel = myMetaModel; - } - - setClientProperty(MODEL_KEY, metaModel); - } - - return metaModel; - } - @Override public void configure(RadComponent rootComponent) throws Exception { String view = chooseView(rootComponent); @@ -126,6 +101,52 @@ public class RadCustomViewComponent extends RadViewComponent implements IConfigu } } + @Override + public MetaModel getMetaModelForProperties() throws Exception { + MetaModel metaModel = getClientProperty(MODEL_KEY); + + if (metaModel == null) { + Module module = getRoot().getClientProperty(ModelParser.MODULE_KEY); + MetaManager metaManager = ViewsMetaManager.getInstance(module.getProject()); + PsiClass viewClass = ChooseClassDialog.findClass(module, getViewClass()); + + while (viewClass != null) { + metaModel = metaManager.getModelByTarget(viewClass.getQualifiedName()); + if (metaModel != null) { + break; + } + viewClass = viewClass.getSuperClass(); + } + if (metaModel == null) { + metaModel = myMetaModel; + } + + setClientProperty(MODEL_KEY, metaModel); + } + + return metaModel; + } + + @Override + public List getInplaceProperties() throws Exception { + List properties = new ArrayList(); + MetaModel metaModel = getMetaModelForProperties(); + List allProperties = getProperties(); + + properties.add(CLASS_PROPERTY); + + for (String name : metaModel.getInplaceProperties()) { + Property property = PropertyTable.findProperty(allProperties, name); + if (property != null) { + properties.add(property); + } + } + + properties.add(PropertyTable.findProperty(allProperties, "id")); + + return properties; + } + @Override public void setProperties(List properties) { List oldProperties = getProperties(); diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java index 953db64cab8b..7a3ff434924f 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java @@ -17,6 +17,7 @@ package com.intellij.android.designer.model; import com.intellij.android.designer.propertyTable.FragmentProperty; import com.intellij.android.designer.propertyTable.IdProperty; +import com.intellij.android.designer.propertyTable.JavadocParser; import com.intellij.android.designer.propertyTable.editors.ChooseClassDialog; import com.intellij.android.designer.propertyTable.editors.ResourceEditor; import com.intellij.designer.model.RadComponent; @@ -45,15 +46,17 @@ public class RadFragment extends RadViewComponent implements IConfigurableCompon setValue(fragment); } } - }, "Supply the name of the fragment class to instantiate."); + }, JavadocParser.build("name", "Supply the name of the fragment class to instantiate.")); private static final Property TAG_PROPERTY = new FragmentProperty("tag", new TextEditor(), - "Use device-admin as the root tag of the XML resource that\n" + - "describes a\n" + - " {@link android.app.admin.DeviceAdminReceiver}, which is\n" + - " referenced from its\n" + - " {@link android.app.admin.DeviceAdminReceiver#DEVICE_ADMIN_META_DATA}\n" + - " meta-data entry. Described here are the attributes that can be\n" + - " included in that tag."); + JavadocParser.build( + "tag", + "Use device-admin as the root tag of the XML resource that\n" + + "describes a\n" + + " {@link android.app.admin.DeviceAdminReceiver}, which is\n" + + " referenced from its\n" + + " {@link android.app.admin.DeviceAdminReceiver#DEVICE_ADMIN_META_DATA}\n" + + " meta-data entry. Described here are the attributes that can be\n" + + " included in that tag.")); private static final String NAME_KEY = "fragment.name"; @Override diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java index a472aa3aaf51..1242352fdc87 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewComponent.java @@ -19,6 +19,7 @@ import com.android.ide.common.rendering.api.ViewInfo; import com.intellij.designer.model.RadComponent; import com.intellij.designer.model.RadVisualComponent; import com.intellij.designer.propertyTable.Property; +import com.intellij.designer.propertyTable.PropertyTable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.xml.XmlAttribute; @@ -196,6 +197,16 @@ public class RadViewComponent extends RadVisualComponent { myProperties = properties; } + @Override + public List getInplaceProperties() throws Exception { + List properties = super.getInplaceProperties(); + Property idProperty = PropertyTable.findProperty(myProperties, "id"); + if (idProperty != null) { + properties.add(idProperty); + } + return properties; + } + @Override public void copyTo(Element parent) throws Exception { // skip root diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java index a087b5511066..41c8ab813f2e 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/CenterProperty.java @@ -25,6 +25,7 @@ import com.intellij.designer.propertyTable.renderers.LabelPropertyRenderer; import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.xml.XmlTag; import com.intellij.util.ArrayUtil; +import com.intellij.android.designer.propertyTable.JavadocParser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,6 +36,8 @@ public class CenterProperty extends Property { private static final String[] COMBO_ITEMS = {"horizontal", "vertical", "both"}; private static final String[] ATTR_ITEMS = {"android:layout_centerHorizontal", "android:layout_centerVertical", "android:layout_centerInParent"}; + private static final String JAVA_DOC = + JavadocParser.build("layout:centerInParent", "Set centers this child horizontally or vertically within its parent."); private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null); private final PropertyEditor myEditor = new StringsComboEditor(COMBO_ITEMS); @@ -116,6 +119,6 @@ public class CenterProperty extends Property { @Override public String getJavadocText() { - return "Set centers this child horizontally or vertically within its parent."; + return JAVA_DOC; } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java index 555ee8f16ad4..7130485d77f7 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/layout/relative/RadRelativeLayout.java @@ -22,6 +22,7 @@ import com.intellij.android.designer.designSurface.layout.relative.RelativeDecor import com.intellij.android.designer.model.PropertyParser; import com.intellij.android.designer.model.RadViewLayoutWithData; import com.intellij.android.designer.model.layout.actions.AllGravityAction; +import com.intellij.android.designer.propertyTable.JavadocParser; import com.intellij.designer.componentTree.TreeEditOperation; import com.intellij.designer.designSurface.*; import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator; @@ -54,7 +55,9 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD @Override public void configureProperties(List properties) { CompoundProperty alignComponent = - new CompoundProperty("layout:alignComponent", "Positions the edges of this view to the edges of the another view."); + new CompoundProperty("layout:alignComponent", + JavadocParser + .build("layout:alignComponent", "Positions the edges of this view to the edges of the another view.")); PropertyParser.moveProperties(properties, alignComponent, "layout:alignTop", "top:top", "layout:below", "top:bottom", @@ -68,7 +71,8 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD properties.add(alignComponent); CompoundProperty alignParent = - new CompoundProperty("layout:alignParent", "Positions the edges of this view to the edges of the parent."); + new CompoundProperty("layout:alignParent", + JavadocParser.build("layout:alignParent", "Positions the edges of this view to the edges of the parent.")); PropertyParser.moveProperties(properties, alignParent, "layout:alignParentTop", "top", "layout:alignParentLeft", "left", diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml index 815dac81094a..ece7ef65ba27 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml +++ b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml @@ -27,6 +27,8 @@ + + + + @@ -70,6 +74,7 @@ tooltip="Displays text to the user and optionally allows them to edit it."/> @@ -95,6 +100,7 @@ tooltip="Represents a push-button widget."/> @@ -111,7 +117,8 @@ - + - + + + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1156,7 +1180,9 @@ class="android.widget.SlidingDrawer" tag="SlidingDrawer"> - + @@ -1195,7 +1221,8 @@ - @@ -1294,7 +1321,8 @@ class="android.widget.GridLayout" tag="GridLayout"> - @@ -1317,7 +1345,8 @@ class="android.widget.RelativeLayout" tag="RelativeLayout"> - + diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java index f768db303a3c..46bdbda27916 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/AttributeProperty.java @@ -41,6 +41,7 @@ public class AttributeProperty extends Property { protected final AttributeDefinition myDefinition; private final PropertyRenderer myRenderer; private final PropertyEditor myEditor; + private String myJavadocText; public AttributeProperty(@NotNull String name, @NotNull AttributeDefinition definition) { this(null, name, definition); @@ -137,6 +138,12 @@ public class AttributeProperty extends Property { @Override public String getJavadocText() { - return myDefinition.getDocValue(); + if (myJavadocText == null) { + String javadocText = myDefinition.getDocValue(); + if (javadocText != null) { + myJavadocText = JavadocParser.build(getName(), javadocText); + } + } + return myJavadocText; } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java index 8d02639ad0b0..17e4d2c2f96a 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/CustomViewProperty.java @@ -37,6 +37,7 @@ import java.util.List; * @author Alexander Lobas */ public class CustomViewProperty extends Property { + private static final String JAVA_DOC = JavadocParser.build("view:class", "The fully qualified name of the class."); private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null); private final PropertyEditor myEditor = new ResourceEditor(null, Collections.emptySet(), null) { @Override @@ -122,6 +123,6 @@ public class CustomViewProperty extends Property { @Override public String getJavadocText() { - return "The fully qualified name of the class."; + return JAVA_DOC; } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java index 200478958a73..461cfea30707 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/FlagProperty.java @@ -40,6 +40,7 @@ public class FlagProperty extends Property implements IPropert private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null); protected final AttributeDefinition myDefinition; protected final List> myOptions = new ArrayList>(); + private String myJavadocText; public FlagProperty(@NotNull String name, @NotNull AttributeDefinition definition) { super(null, name); @@ -163,7 +164,13 @@ public class FlagProperty extends Property implements IPropert @Override public String getJavadocText() { - return myDefinition.getDocValue(); + if (myJavadocText == null) { + String javadocText = myDefinition.getDocValue(); + if (javadocText != null) { + myJavadocText = JavadocParser.build(getName(), javadocText); + } + } + return myJavadocText; } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java index 1835911adbfb..7d3a9f789577 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/IncludeLayoutProperty.java @@ -41,6 +41,7 @@ public class IncludeLayoutProperty extends Property { public static ResourceType[] TYPES = new ResourceType[]{ResourceType.LAYOUT}; private static final Set FORMATS = EnumSet.of(AttributeFormat.Reference); public static final Property INSTANCE = new IncludeLayoutProperty(); + private static final String JAVA_DOC = JavadocParser.build(NAME, "Reference to the layout file you wish to include."); private final PropertyRenderer myRenderer = new ResourceRenderer(FORMATS); private final PropertyEditor myEditor = new ResourceEditor(TYPES, FORMATS, null); @@ -91,6 +92,6 @@ public class IncludeLayoutProperty extends Property { @Override public String getJavadocText() { - return "Reference to the layout file you wish to include."; + return JAVA_DOC; } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/JavadocParser.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/JavadocParser.java new file mode 100644 index 000000000000..422675316b7e --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/JavadocParser.java @@ -0,0 +1,86 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.android.designer.propertyTable; + +import com.intellij.codeInsight.documentation.DocumentationManager; +import org.jetbrains.annotations.NotNull; + +/** + * @author Alexander Lobas + */ +public class JavadocParser { + private static final String[] TAGS = {"{see ", "{@see ", "{@link "}; + + @NotNull + public static String build(@NotNull String title, @NotNull String javadoc) { + StringBuilder buffer = new StringBuilder(); + + buffer.append(""); + buffer.append("

").append(title).append(" - "); + + for (String tag : TAGS) { + javadoc = convertLink(javadoc, tag); + } + + javadoc = javadoc.replaceAll("", ""); + javadoc = javadoc.replaceAll("", ""); + + buffer.append(javadoc); + + return buffer.append("").toString(); + } + + private static String convertLink(String javadoc, String tag) { + StringBuilder buffer = new StringBuilder(); + int length = javadoc.length(); + int start = 0; + + while (true) { + int index = javadoc.indexOf(tag, start); + + if (index == -1) { + buffer.append(javadoc.substring(start, length)); + break; + } + else { + buffer.append(javadoc.substring(start, index)); + + int linkStart = index + tag.length(); + int end = javadoc.indexOf('}', linkStart); + String linkValue = javadoc.substring(linkStart, end).trim(); + String href; + String text; + + int spaceIndex = linkValue.indexOf(' '); + if (spaceIndex != -1) { + href = linkValue.substring(0, spaceIndex); + text = linkValue.substring(spaceIndex + 1); + } + else { + href = text = linkValue; + } + + text = text.replace('#', '.'); + + DocumentationManager.createHyperlink(buffer, href, text, true); + + start = end + 1; + } + } + + return buffer.toString(); + } +} \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java index bd6ccc16c2d7..d5c4269ed3d1 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java @@ -18,6 +18,7 @@ package com.intellij.android.designer.propertyTable.editors; import com.android.resources.ResourceType; import com.intellij.android.designer.model.ModelParser; import com.intellij.designer.model.RadComponent; +import com.intellij.designer.propertyTable.InplaceContext; import com.intellij.designer.propertyTable.PropertyEditor; import com.intellij.designer.propertyTable.editors.ComboEditor; import com.intellij.openapi.module.Module; @@ -26,11 +27,14 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ComboboxWithBrowseButton; +import com.intellij.ui.DocumentAdapter; import org.jetbrains.android.dom.attrs.AttributeFormat; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.DocumentEvent; +import java.awt.*; import java.awt.event.*; import java.util.EnumSet; import java.util.Set; @@ -51,7 +55,12 @@ public class ResourceEditor extends PropertyEditor { myTypes = types; if (formats.contains(AttributeFormat.Enum) || formats.contains(AttributeFormat.Boolean)) { - ComboboxWithBrowseButton editor = new ComboboxWithBrowseButton(); + ComboboxWithBrowseButton editor = new ComboboxWithBrowseButton() { + @Override + public Dimension getPreferredSize() { + return getComponentPreferredSize(); + } + }; final JComboBox comboBox = editor.getComboBox(); DefaultComboBoxModel model; @@ -78,18 +87,32 @@ public class ResourceEditor extends PropertyEditor { comboBox.setSelectedIndex(0); } else { - myEditor = new TextFieldWithBrowseButton(); + myEditor = new TextFieldWithBrowseButton() { + @Override + public Dimension getPreferredSize() { + return getComponentPreferredSize(); + } + }; myEditor.registerKeyboardAction(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { } }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - getComboText().addActionListener(new ActionListener() { + + JTextField textField = getComboText(); + textField.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { fireValueCommitted(true, true); } }); + textField.getDocument().addDocumentListener( + new DocumentAdapter() { + protected void textChanged(final DocumentEvent e) { + preferredSizeChanged(); + } + } + ); } myEditor.addActionListener(new ActionListener() { @@ -106,6 +129,12 @@ public class ResourceEditor extends PropertyEditor { }); } + private Dimension getComponentPreferredSize() { + Dimension size1 = myEditor.getChildComponent().getPreferredSize(); + Dimension size2 = myEditor.getButton().getPreferredSize(); + return new Dimension(size1.width + size2.width + 5, size1.height); + } + private static ResourceType[] convertTypes(Set formats) { Set types = EnumSet.noneOf(ResourceType.class); for (AttributeFormat format : formats) { @@ -141,13 +170,24 @@ public class ResourceEditor extends PropertyEditor { @NotNull @Override - public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) { + public JComponent getComponent(@NotNull RadComponent rootComponent, + @Nullable RadComponent component, + Object value, + @Nullable InplaceContext inplaceContext) { myRootComponent = rootComponent; JTextField text = getComboText(); text.setText((String)value); + if (inplaceContext != null && inplaceContext.isStartChar()) { + text.setText(inplaceContext.getText(text.getText())); + } return myEditor; } + @Override + public JComponent getPreferredFocusedComponent() { + return getComboText(); + } + @Override public Object getValue() throws Exception { String value = getComboText().getText(); diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java index 0cff35b05c96..949b97356e1a 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java @@ -16,7 +16,7 @@ package com.intellij.android.designer.propertyTable.editors; import com.intellij.designer.model.RadComponent; -import com.intellij.designer.propertyTable.PropertyEditor; +import com.intellij.designer.propertyTable.InplaceContext; import com.intellij.designer.propertyTable.editors.ComboEditor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,7 +54,10 @@ public class StringsComboEditor extends ComboEditor { @NotNull @Override - public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) { + public JComponent getComponent(@NotNull RadComponent rootComponent, + @Nullable RadComponent component, + Object value, + @Nullable InplaceContext inplaceContext) { myCombo.setSelectedItem(value); return myCombo; } diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacet.groovy b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacet.groovy index d7d04ba87dab..7f9d3dddb6a9 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacet.groovy +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidFacet.groovy @@ -92,7 +92,7 @@ class AndroidFacet extends Facet { } if (lookInContentRoot) { - module.contentRoots.each {String contentRoot -> + for (String contentRoot in module.contentRoots) { def absPath = FileUtil.toSystemIndependentName(contentRoot + relativePath) def f = new File(absPath) diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSourceGeneratingBuilder.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSourceGeneratingBuilder.java index c982ef16a5ae..265845566c92 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSourceGeneratingBuilder.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidSourceGeneratingBuilder.java @@ -584,6 +584,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder { if (!FileUtil.moveDirWithContent(tmpOutputDir, aptOutputDirectory)) { context.processMessage(new CompilerMessage(ANDROID_APT_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle .message("android.jps.errors.cannot.move.content", tmpOutputDir.getPath(), aptOutputDirectory.getPath()))); + success = false; continue; } markDirtyRecursively(aptOutputDirectory, context, ANDROID_APT_COMPILER); diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java index 350ba76c09e4..254d6b90beb2 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidFacetConfiguration.java @@ -27,7 +27,6 @@ import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jdom.Element; @@ -97,15 +96,10 @@ public class AndroidFacetConfiguration implements FacetConfiguration { } public void init(@NotNull Module module, @NotNull String baseDirectoryPath) { - String moduleDirPath = AndroidRootUtil.getModuleDirPath(module); - if (moduleDirPath == null) { + final String s = AndroidRootUtil.getPathRelativeToModuleDir(module, baseDirectoryPath); + if (s == null || s.length() == 0) { return; } - if (moduleDirPath.equals(baseDirectoryPath)) { - return; - } - - String s = FileUtil.getRelativePath(moduleDirPath, baseDirectoryPath, '/'); GEN_FOLDER_RELATIVE_PATH_APT = '/' + s + GEN_FOLDER_RELATIVE_PATH_APT; GEN_FOLDER_RELATIVE_PATH_AIDL = '/' + s + GEN_FOLDER_RELATIVE_PATH_AIDL; diff --git a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java index c24eed85f9a6..6eeb95037884 100644 --- a/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java +++ b/plugins/android/src/org/jetbrains/android/facet/AndroidRootUtil.java @@ -514,4 +514,16 @@ public class AndroidRootUtil { String moduleDirPath = getModuleDirPath(facet.getModule()); return moduleDirPath != null ? FileUtil.toSystemDependentName(moduleDirPath + path) : null; } + + @Nullable + public static String getPathRelativeToModuleDir(@NotNull Module module, @NotNull String path) { + String moduleDirPath = getModuleDirPath(module); + if (moduleDirPath == null) { + return null; + } + if (moduleDirPath.equals(path)) { + return ""; + } + return FileUtil.getRelativePath(moduleDirPath, path, '/'); + } } diff --git a/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java b/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java index 2eaa9968d45e..7aa809d188e1 100644 --- a/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java +++ b/plugins/android/src/org/jetbrains/android/maven/AndroidFacetImporterBase.java @@ -389,9 +389,13 @@ public abstract class AndroidFacetImporterBase extends FacetImporter 0 ? '/' + s + '/' : "/"; + configuration.RES_FOLDER_RELATIVE_PATH = s + AndroidMavenUtil.APK_LIB_ARTIFACT_RES_DIR; + configuration.LIBS_FOLDER_RELATIVE_PATH = s + AndroidMavenUtil.APK_LIB_ARTIFACT_NATIVE_LIBS_DIR; + configuration.MANIFEST_FILE_RELATIVE_PATH = s + AndroidMavenUtil.APK_LIB_ARTIFACT_MANIFEST_FILE; + } importSdkAndDependenciesForApklibArtifact(project, rootModelAdapter, apklibModuleModel, modelsProvider, mavenTree, artifact, mavenProject2ModuleName); diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationPanel.form b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationPanel.form index 57f73e2ada0b..d3bee8216de1 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationPanel.form +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/config/ui/CvsConfigurationPanel.form @@ -23,7 +23,7 @@ - + @@ -71,7 +71,7 @@ - + diff --git a/plugins/devkit/src/dom/impl/IdeaPluginImpl.java b/plugins/devkit/src/dom/impl/IdeaPluginImpl.java index 198bcd3eb31a..bb213490e9c2 100644 --- a/plugins/devkit/src/dom/impl/IdeaPluginImpl.java +++ b/plugins/devkit/src/dom/impl/IdeaPluginImpl.java @@ -26,6 +26,10 @@ import org.jetbrains.idea.devkit.dom.IdeaPlugin; public abstract class IdeaPluginImpl implements IdeaPlugin { public String getPluginId() { final XmlTag tag = getXmlTag(); + if (tag == null) { + return null; + } + final XmlTag idTag = tag.findFirstSubTag("id"); if (idTag != null) { return idTag.getValue().getTrimmedText(); diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importWizard/EclipseWorkspaceRootStep.form b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importWizard/EclipseWorkspaceRootStep.form index d44ab2b9ad3b..62cbc596e177 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importWizard/EclipseWorkspaceRootStep.form +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importWizard/EclipseWorkspaceRootStep.form @@ -28,7 +28,7 @@ - + diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index 41db3cd4f414..4c4879a483ab 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -298,6 +298,9 @@ public class GitUtil { * @return git root for the file * @throws IllegalArgumentException if the file is not under git * @throws VcsException if the file is not under git + * + * @deprecated because uses the java.io.File. + * @use GitRepositoryManager#getRepositoryForFile(). */ public static VirtualFile getGitRoot(final FilePath filePath) throws VcsException { VirtualFile root = getGitRootOrNull(filePath); @@ -312,7 +315,11 @@ public class GitUtil { * * @param filePath a file path * @return git root for the file or null if the file is not under git + * + * @deprecated because uses the java.io.File. + * @use GitRepositoryManager#getRepositoryForFile(). */ + @Deprecated @Nullable public static VirtualFile getGitRootOrNull(final FilePath filePath) { return getGitRootOrNull(filePath.getIOFile()); @@ -322,6 +329,11 @@ public class GitUtil { return file != null && file.exists() && file.isDirectory() && new File(file, DOT_GIT).exists(); } + /** + * @deprecated because uses the java.io.File. + * @use GitRepositoryManager#getRepositoryForFile(). + */ + @Deprecated @Nullable public static VirtualFile getGitRootOrNull(final File file) { File root = file; @@ -337,6 +349,9 @@ public class GitUtil { * @param file the file to check * @return git root for the file * @throws VcsException if the file is not under git + * + * @deprecated because uses the java.io.File. + * @use GitRepositoryManager#getRepositoryForFile(). */ public static VirtualFile getGitRoot(@NotNull final VirtualFile file) throws VcsException { final VirtualFile root = gitRootOrNull(file); @@ -353,6 +368,9 @@ public class GitUtil { * * @param file the file to check * @return git root for the file or null if the file is not not under Git + * + * @deprecated because uses the java.io.File. + * @use GitRepositoryManager#getRepositoryForFile(). */ @Nullable public static VirtualFile gitRootOrNull(final VirtualFile file) { @@ -376,6 +394,9 @@ public class GitUtil { * @param project the project * @param vcs the git Vcs * @return the list of the roots + * + * @deprecated because uses the java.io.File. + * @use GitRepositoryManager#getRepositoryForFile(). */ @NotNull public static List getGitRoots(Project project, GitVcs vcs) throws VcsException { diff --git a/plugins/git4idea/src/git4idea/config/GitVcsPanel.form b/plugins/git4idea/src/git4idea/config/GitVcsPanel.form index 3feefe8e52be..33f5acc95a39 100644 --- a/plugins/git4idea/src/git4idea/config/GitVcsPanel.form +++ b/plugins/git4idea/src/git4idea/config/GitVcsPanel.form @@ -15,7 +15,7 @@ - + diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryManagerImpl.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryManagerImpl.java index e0ee250f464e..c266d7e185a1 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryManagerImpl.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryManagerImpl.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.VcsRoot; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import git4idea.GitUtil; @@ -97,9 +98,18 @@ public class GitRepositoryManagerImpl extends AbstractProjectComponent implement @Override @Nullable public GitRepository getRepositoryForFile(@NotNull VirtualFile file) { - final VirtualFile vcsRoot = myVcsManager.getVcsRootFor(file); + final VcsRoot vcsRoot = myVcsManager.getVcsRootObjectFor(file); if (vcsRoot == null) { return null; } - return getRepositoryForRoot(vcsRoot); + final AbstractVcs vcs = vcsRoot.getVcs(); + if (!myVcs.equals(vcs)) { + if (vcs != null) { + // if null, the file is just not under version control, nothing interesting; + // otherwise log, because Git method is requested not for a Git-controlled file + LOG.info(String.format("getRepositoryForFile returned non-Git (%s) root for file %s", vcs.getDisplayName(), file)); + } + return null; + } + return getRepositoryForRoot(vcsRoot.getPath()); } @Override diff --git a/plugins/git4idea/src/git4idea/status/GitChangeProvider.java b/plugins/git4idea/src/git4idea/status/GitChangeProvider.java index ab5754660478..94b3e69e7e47 100644 --- a/plugins/git4idea/src/git4idea/status/GitChangeProvider.java +++ b/plugins/git4idea/src/git4idea/status/GitChangeProvider.java @@ -62,6 +62,11 @@ public class GitChangeProvider implements ChangeProvider { final ChangelistBuilder builder, final ProgressIndicator progress, final ChangeListManagerGate addGate) throws VcsException { + final GitVcs vcs = GitVcs.getInstance(myProject); + if (vcs == null) { + // already disposed or not yet initialized => ignoring + return; + } final Collection affected = dirtyScope.getAffectedContentRootsWithCheck(); if (dirtyScope.getAffectedContentRoots().size() != affected.size()) { @@ -78,8 +83,10 @@ public class GitChangeProvider implements ChangeProvider { myFileDocumentManager, myVcsManager); for (VirtualFile root : roots) { GitChangesCollector collector = isNewGitChangeProviderAvailable() - ? GitNewChangesCollector.collect(myProject, myGit, myChangeListManager, dirtyScope, root) - : GitOldChangesCollector.collect(myProject, myChangeListManager, dirtyScope, root); + ? GitNewChangesCollector.collect(myProject, myGit, myChangeListManager, myVcsManager, + vcs, dirtyScope, root) + : GitOldChangesCollector.collect(myProject, myChangeListManager, myVcsManager, + vcs, dirtyScope, root); holder.changed(collector.getChanges()); for (Change file : collector.getChanges()) { builder.processChange(file, GitVcs.getKey()); @@ -90,11 +97,10 @@ public class GitChangeProvider implements ChangeProvider { } holder.feedBuilder(builder); } - } catch (VcsException e) {// most probably the error happened because git is not configured - final GitVcs vcs = GitVcs.getInstance(myProject); - if (vcs != null) { - vcs.getExecutableValidator().showNotificationOrThrow(e); - } + } + catch (VcsException e) { + // most probably the error happened because git is not configured + vcs.getExecutableValidator().showNotificationOrThrow(e); } } diff --git a/plugins/git4idea/src/git4idea/status/GitChangesCollector.java b/plugins/git4idea/src/git4idea/status/GitChangesCollector.java index 92058bc189d0..df204a34f5a2 100644 --- a/plugins/git4idea/src/git4idea/status/GitChangesCollector.java +++ b/plugins/git4idea/src/git4idea/status/GitChangesCollector.java @@ -17,13 +17,12 @@ package git4idea.status; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vcs.FilePathImpl; +import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vcs.changes.ContentRevision; import com.intellij.openapi.vcs.changes.VcsDirtyScope; import com.intellij.openapi.vfs.VirtualFile; -import git4idea.GitUtil; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -37,18 +36,21 @@ import java.util.*; * @author Kirill Likhodedov */ abstract class GitChangesCollector { - protected final Project myProject; - protected final VirtualFile myVcsRoot; - private final ChangeListManager myChangeListManager; - private final VcsDirtyScope myDirtyScope; + @NotNull protected final Project myProject; + @NotNull protected final VirtualFile myVcsRoot; + + @NotNull private final VcsDirtyScope myDirtyScope; + @NotNull private final ChangeListManager myChangeListManager; + @NotNull private final ProjectLevelVcsManager myVcsManager; + @NotNull private AbstractVcs myVcs; - GitChangesCollector(@NotNull Project project, - @NotNull ChangeListManager changeListManager, - @NotNull VcsDirtyScope dirtyScope, - @NotNull VirtualFile vcsRoot) { + GitChangesCollector(@NotNull Project project, @NotNull ChangeListManager changeListManager, @NotNull ProjectLevelVcsManager vcsManager, + @NotNull AbstractVcs vcs, @NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) { myProject = project; myChangeListManager = changeListManager; + myVcsManager = vcsManager; + myVcs = vcs; myDirtyScope = dirtyScope; myVcsRoot = vcsRoot; } @@ -80,27 +82,24 @@ abstract class GitChangesCollector { } if (includeChanges) { - try { - for (Change c : myChangeListManager.getChangesIn(myVcsRoot)) { - switch (c.getType()) { - case NEW: - case DELETED: - case MOVED: - if (c.getAfterRevision() != null) { - addToPaths(c.getAfterRevision().getFile(), allPaths); - } - if (c.getBeforeRevision() != null) { - addToPaths(c.getBeforeRevision().getFile(), allPaths); - } - case MODIFICATION: - default: - // do nothing - } + for (Change c : myChangeListManager.getChangesIn(myVcsRoot)) { + switch (c.getType()) { + case NEW: + case DELETED: + case MOVED: + ContentRevision afterRevision = c.getAfterRevision(); + if (afterRevision != null) { + addToPaths(afterRevision.getFile(), allPaths); + } + ContentRevision beforeRevision = c.getBeforeRevision(); + if (beforeRevision != null) { + addToPaths(beforeRevision.getFile(), allPaths); + } + case MODIFICATION: + default: + // do nothing } } - catch (Exception t) { - // ignore exceptions - } } removeCommonParents(allPaths); @@ -114,9 +113,9 @@ abstract class GitChangesCollector { } protected void addToPaths(FilePath pathToAdd, List paths) { - File file = pathToAdd.getIOFile(); - if (myVcsRoot.equals(GitUtil.getGitRootOrNull(file))) { - paths.add(file.getPath()); + VcsRoot fileRoot = myVcsManager.getVcsRootObjectFor(pathToAdd); + if (fileRoot != null && fileRoot.getVcs() != null && myVcs.equals(fileRoot.getVcs()) && myVcsRoot.equals(fileRoot.getPath())) { + paths.add(pathToAdd.getPath()); } } diff --git a/plugins/git4idea/src/git4idea/status/GitNewChangesCollector.java b/plugins/git4idea/src/git4idea/status/GitNewChangesCollector.java index 983e493813cf..6d1afc991059 100644 --- a/plugins/git4idea/src/git4idea/status/GitNewChangesCollector.java +++ b/plugins/git4idea/src/git4idea/status/GitNewChangesCollector.java @@ -18,9 +18,7 @@ package git4idea.status; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vcs.FileStatus; -import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ContentRevision; @@ -70,8 +68,9 @@ class GitNewChangesCollector extends GitChangesCollector { */ @NotNull static GitNewChangesCollector collect(@NotNull Project project, @NotNull Git git, @NotNull ChangeListManager changeListManager, + @NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs, @NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) throws VcsException { - return new GitNewChangesCollector(project, git, changeListManager, dirtyScope, vcsRoot); + return new GitNewChangesCollector(project, git, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot); } @Override @@ -87,9 +86,10 @@ class GitNewChangesCollector extends GitChangesCollector { } private GitNewChangesCollector(@NotNull Project project, @NotNull Git git, @NotNull ChangeListManager changeListManager, + @NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs, @NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) throws VcsException { - super(project, changeListManager, dirtyScope, vcsRoot); + super(project, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot); myGit = git; myRepository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(vcsRoot); diff --git a/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java b/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java index 52ed9458f353..518efac8ca8d 100644 --- a/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java +++ b/plugins/git4idea/src/git4idea/status/GitOldChangesCollector.java @@ -16,9 +16,7 @@ package git4idea.status; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vcs.FileStatus; -import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ContentRevision; @@ -104,11 +102,10 @@ class GitOldChangesCollector extends GitChangesCollector { * This may be lengthy. */ @NotNull - static GitOldChangesCollector collect(@NotNull Project project, - @NotNull ChangeListManager changeListManager, - @NotNull VcsDirtyScope dirtyScope, - @NotNull VirtualFile vcsRoot) throws VcsException { - return new GitOldChangesCollector(project, changeListManager, dirtyScope, vcsRoot); + static GitOldChangesCollector collect(@NotNull Project project, @NotNull ChangeListManager changeListManager, + @NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs, + @NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) throws VcsException { + return new GitOldChangesCollector(project, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot); } @NotNull @@ -123,11 +120,10 @@ class GitOldChangesCollector extends GitChangesCollector { return myChanges; } - private GitOldChangesCollector(@NotNull Project project, - @NotNull ChangeListManager changeListManager, - @NotNull VcsDirtyScope dirtyScope, + private GitOldChangesCollector(@NotNull Project project, @NotNull ChangeListManager changeListManager, + @NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs, @NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) throws VcsException { - super(project, changeListManager, dirtyScope, vcsRoot); + super(project, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot); updateIndex(); collectUnmergedAndUnversioned(); collectDiffChanges(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java index cdd5e6d8436c..bab6c05bdeb5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/NewGroovyClassAction.java @@ -32,6 +32,7 @@ import com.intellij.psi.JavaDirectoryService; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyBundle; @@ -112,6 +113,7 @@ public class NewGroovyClassAction extends JavaCreateTemplateInPackageAction - + @@ -46,7 +46,7 @@ - + diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java index 35c3ef69e993..ecceca01bfe8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java @@ -332,8 +332,8 @@ public abstract class HgUtil { public static @NotNull List getHgRepositories(@NotNull Project project) { final List repos = new LinkedList(); for (VcsRoot root : ProjectLevelVcsManager.getInstance(project).getAllVcsRoots()) { - if (HgVcs.VCS_NAME.equals(root.vcs.getName())) { - repos.add(root.path); + if (HgVcs.VCS_NAME.equals(root.getVcs().getName())) { + repos.add(root.getPath()); } } return repos; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java index 5504b7517e4c..c125e65db08e 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleNameMapper.java @@ -18,7 +18,6 @@ package org.jetbrains.idea.maven.importing; import com.intellij.ide.highlighter.ModuleFileType; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.text.StringUtil; -import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.model.MavenId; import org.jetbrains.idea.maven.project.MavenProject; diff --git a/plugins/rearranger/src/com/wrq/rearranger/defaultConfiguration.xml b/plugins/rearranger/src/com/wrq/rearranger/defaultConfiguration.xml index ff91276bbcac..237a8739e877 100644 --- a/plugins/rearranger/src/com/wrq/rearranger/defaultConfiguration.xml +++ b/plugins/rearranger/src/com/wrq/rearranger/defaultConfiguration.xml @@ -27,9 +27,7 @@ ShowMatchedRules="false" ShowComments="false" RemoveBlanksInsideCodeBlocks="true"> \n//\ ------------------------------\ FIELDS\ - ------------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// ------------------------------ FIELDS ------------------------------\n @@ -108,9 +106,7 @@ \n//\ --------------------------\ STATIC\ METHODS\ - --------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// -------------------------- STATIC METHODS --------------------------\n @@ -133,9 +129,7 @@ \n//\ ---------------------------\ CONSTRUCTORS\ - ---------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// --------------------------- CONSTRUCTORS ---------------------------\n @@ -179,9 +173,7 @@ \n//\ ---------------------\ GETTER\ /\ SETTER\ METHODS\ - ---------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// --------------------- GETTER / SETTER METHODS ---------------------\n @@ -204,9 +196,7 @@ \n//\ ------------------------\ CANONICAL\ METHODS\ - ------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// ------------------------ CANONICAL METHODS ------------------------\n @@ -229,17 +219,13 @@ \n//\ ------------------------\ INTERFACE\ METHODS\ - ------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// ------------------------ INTERFACE METHODS ------------------------\n \n//\ ---------------------\ Interface\ %IF%\ - ---------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// --------------------- Interface %IF% ---------------------\n \n//\ --------------------------\ OTHER\ METHODS\ - --------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// -------------------------- OTHER METHODS --------------------------\n @@ -272,9 +256,7 @@ \n//\ --------------------------\ ENUMERATIONS\ - --------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n//\ -------------------------- ENUMERATIONS --------------------------\n @@ -285,9 +267,7 @@ \n//\ --------------------------\ INNER\ CLASSES\ - --------------------------\n - + fillString="" useProjectWidthForFill="true" fillWidth="0">\n// -------------------------- INNER CLASSES --------------------------\n diff --git a/plugins/rearranger/src/com/wrq/rearranger/rearrangement/Spacer.java b/plugins/rearranger/src/com/wrq/rearranger/rearrangement/Spacer.java index acbb698009a0..e088053fe281 100644 --- a/plugins/rearranger/src/com/wrq/rearranger/rearrangement/Spacer.java +++ b/plugins/rearranger/src/com/wrq/rearranger/rearrangement/Spacer.java @@ -21,6 +21,7 @@ */ package com.wrq.rearranger.rearrangement; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.psi.*; @@ -86,9 +87,11 @@ public class Spacer { private static void handleBadPsiElementException(String desc, PsiElement element) throws AbortRespacingException { - JOptionPane.showMessageDialog(null, - "Spacing could not be performed due to a syntax error:\n" + - desc + element.getText(), "Spacing Error", JOptionPane.ERROR_MESSAGE); + if (!ApplicationManager.getApplication().isUnitTestMode()) { + JOptionPane.showMessageDialog(null, + "Spacing could not be performed due to a syntax error:\n" + + desc + element.getText(), "Spacing Error", JOptionPane.ERROR_MESSAGE); + } throw new AbortRespacingException(); } diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/InteractiveTest.java b/plugins/rearranger/test/src/com/wrq/rearranger/InteractiveTest.java index 09beffce623b..78865f5de646 100644 --- a/plugins/rearranger/test/src/com/wrq/rearranger/InteractiveTest.java +++ b/plugins/rearranger/test/src/com/wrq/rearranger/InteractiveTest.java @@ -30,11 +30,8 @@ import com.wrq.rearranger.settings.RearrangerSettings; * Date: Mar 30, 2004 */ @SkipInHeadlessEnvironment -public class InteractiveTest - extends LightCodeInsightFixtureTestCase -{ - public static final String DEFAULT_CONFIGURATION_ROOT = ".."; // up one level from test - public static final String DEFAULT_CONFIGURATION = DEFAULT_CONFIGURATION_ROOT + "/src/com/wrq/rearranger/defaultConfiguration.xml"; +public class InteractiveTest extends LightCodeInsightFixtureTestCase { + public static final String DEFAULT_CONFIGURATION = "/src/com/wrq/rearranger/defaultConfiguration.xml"; private RearrangerSettings mySettings; @Override diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/RearrangerTest.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/RearrangerTest.groovy index 47f437e26fda..df55096c0da7 100644 --- a/plugins/rearranger/test/src/com/wrq/rearranger/RearrangerTest.groovy +++ b/plugins/rearranger/test/src/com/wrq/rearranger/RearrangerTest.groovy @@ -23,13 +23,20 @@ package com.wrq.rearranger; import com.intellij.openapi.application.ApplicationManager +import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiMethod import com.intellij.psi.PsiModifier +import com.intellij.testFramework.PlatformTestUtil import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase import com.wrq.rearranger.settings.CommentRule import com.wrq.rearranger.settings.RearrangerSettings import com.wrq.rearranger.settings.RelatedMethodsSettings import com.wrq.rearranger.settings.attributeGroups.GetterSetterDefinition +import com.wrq.rearranger.settings.attributeGroups.InterfaceAttributes +import com.wrq.rearranger.settings.attributeGroups.RegexUtil import com.wrq.rearranger.util.CommentRuleBuilder +import com.wrq.rearranger.util.SettingsConfigurationBuilder import org.jetbrains.annotations.NotNull import org.jetbrains.annotations.Nullable import com.wrq.rearranger.util.java.* @@ -37,13 +44,15 @@ import com.wrq.rearranger.util.java.* /** JUnit tests for the rearranger plugin. */ class RearrangerTest extends LightCodeInsightFixtureTestCase { - private RearrangerSettings mySettings - private JavaClassRuleBuilder classRule - private JavaInnerClassRuleBuilder innerClassRule - private JavaFieldRuleBuilder fieldRule - private JavaMethodRuleBuilder methodRule - private CommentRuleBuilder commentRule - private JavaSpacingRule spacingRule + private RearrangerSettings mySettings + private SettingsConfigurationBuilder settings + private JavaClassRuleBuilder classRule + private JavaInterfaceRuleBuilder interfaceRule + private JavaInnerClassRuleBuilder innerClassRule + private JavaFieldRuleBuilder fieldRule + private JavaMethodRuleBuilder methodRule + private CommentRuleBuilder commentRule + private JavaSpacingRule spacingRule @Override protected String getBasePath() { @@ -61,7 +70,13 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { mySettings.showRules = true mySettings.rearrangeInnerClasses = true + prepareBuilders(mySettings) + } + + private void prepareBuilders(RearrangerSettings mySettings) { + settings = new SettingsConfigurationBuilder(settings: mySettings) classRule = new JavaClassRuleBuilder(settings: mySettings) + interfaceRule = new JavaInterfaceRuleBuilder(settings: mySettings) innerClassRule = new JavaInnerClassRuleBuilder(settings: mySettings) fieldRule = new JavaFieldRuleBuilder(settings: mySettings) methodRule = new JavaMethodRuleBuilder(settings: mySettings) @@ -75,15 +90,13 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { public final void testPublicFieldRearrangement() throws Exception { doTest('RearrangementTest', 'RearrangementResult2') { - fieldRule.create { - modifier( PsiModifier.PUBLIC ) - } } } + fieldRule.modifier PsiModifier.PUBLIC + } } public final void testNotPublicFieldRearrangement() throws Exception { doTest('RearrangementTest', 'RearrangementResult3') { - fieldRule.create { - modifier( PsiModifier.PUBLIC, invert: true ) - } } } + fieldRule.modifier PsiModifier.PUBLIC, invert: true + } } public final void testConstructorRearrangement() throws Exception { doTest('RearrangementTest', 'RearrangementResult4') { @@ -126,7 +139,7 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest('RearrangementTest', 'RearrangementResult9') { methodRule.create { target([ MethodType.GETTER_OR_SETTER, MethodType.OTHER ]) - sort(SortType.BY_NAME) + 'sort by'( SortOption.NAME ) } } } public final void testSimpleComment() throws Exception { @@ -151,12 +164,12 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { public final void testMultipleRuleCommentMatch() throws Exception { doTest('RearrangementTest11', 'RearrangementResult11') { - commentRule.create { comment('// FIELDS:', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: false) } - commentRule.create { comment('// FINAL FIELDS:', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: false, - subsequentRulesToMatch: 1) } + commentRule.create { comment('// FIELDS:', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': false) } + commentRule.create { comment('// FINAL FIELDS:', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': false, + 'subsequent rules to match': 1) } fieldRule.create { modifier(PsiModifier.FINAL) } - commentRule.create { comment('// NON-FINAL FIELDS:', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: true, - subsequentRulesToMatch: 1) } + commentRule.create { comment('// NON-FINAL FIELDS:', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': true, + 'subsequent rules to match': 1) } fieldRule.create { modifier(PsiModifier.FINAL, invert: true) } } } @@ -182,56 +195,56 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest(srcFilename, compareFilename) { commentRule.create { comment('//************************************** PUBLIC STATIC FIELDS *************************************', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: false, allPreceding: true, - subsequentRulesToMatch: 2, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': false, 'all preceding': true, + 'subsequent rules to match': 2, 'preceding rules to match': 1) } fieldRule.create { modifier([ PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL ]) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } fieldRule.create { modifier([ PsiModifier.PUBLIC, PsiModifier.STATIC ]) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('//************************************** PUBLIC FIELDS *****************************************', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: true, allPreceding: true, - subsequentRulesToMatch: 1, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': true, 'all preceding': true, + 'subsequent rules to match': 1, 'preceding rules to match': 1) } fieldRule.create { modifier( PsiModifier.PUBLIC ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('//*********************************** PROTECTED/PACKAGE FIELDS **************************************', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: false, allPreceding: true, - subsequentRulesToMatch: 3, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': false, 'all preceding': true, + 'subsequent rules to match': 3, 'preceding rules to match': 1) } fieldRule.create { modifier([ PsiModifier.PROTECTED, PsiModifier.PACKAGE_LOCAL, PsiModifier.STATIC, PsiModifier.FINAL ]) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } fieldRule.create { modifier([ PsiModifier.PROTECTED, PsiModifier.PACKAGE_LOCAL, PsiModifier.STATIC ]) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } fieldRule.create { modifier([ PsiModifier.PROTECTED, PsiModifier.PACKAGE_LOCAL ]) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('//************************************** PRIVATE FIELDS *****************************************', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: false, allPreceding: true, - subsequentRulesToMatch: 1, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': false, 'all preceding': true, + 'subsequent rules to match': 1, 'preceding rules to match': 1) } fieldRule.create { modifier( PsiModifier.PRIVATE ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('//************************************** CONSTRUCTORS ************************************* ', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: false, allPreceding: true, - subsequentRulesToMatch: 2, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': false, 'all preceding': true, + 'subsequent rules to match': 2, 'preceding rules to match': 1) } methodRule.create { modifier( PsiModifier.PUBLIC ) @@ -240,54 +253,54 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { methodRule.create { target( MethodType.CONSTRUCTOR ) } commentRule.create { comment('//*********************************** GETTERS AND SETTERS ********************************** ', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: false, allPreceding: true, - subsequentRulesToMatch: 2, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': false, 'all preceding': true, + 'subsequent rules to match': 2, 'preceding rules to match': 1) } methodRule.create { modifier( PsiModifier.PUBLIC ) target( MethodType.GETTER_OR_SETTER ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } methodRule.create { target( MethodType.GETTER_OR_SETTER ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } def text = '//************************************** PUBLIC METHODS ************************************* ' if (doublePublicMethods) { text += "\n// PUBLIC METHODS LINE 2"; } commentRule.create { - comment(text, condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: true, allPreceding: true, - subsequentRulesToMatch: 1, precedingRulesToMatch: 1) + comment(text, condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': true, 'all preceding': true, + 'subsequent rules to match': 1, 'preceding rules to match': 1) } methodRule.create { modifier( PsiModifier.PUBLIC ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('//********************************* PACKAGE/PROTECTED METHODS ******************************** ', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: true, allPreceding: true, - subsequentRulesToMatch: 1, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': true, 'all preceding': true, + 'subsequent rules to match': 1, 'preceding rules to match': 1) } methodRule.create { modifier([ PsiModifier.PROTECTED, PsiModifier.PACKAGE_LOCAL ]) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('//************************************** PRIVATE METHODS *************************************', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: true, allPreceding: true, - subsequentRulesToMatch: 1, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': true, 'all preceding': true, + 'subsequent rules to match': 1, 'preceding rules to match': 1) } methodRule.create { modifier( PsiModifier.PRIVATE ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('//************************************** INNER CLASSES ************************************* ', - condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, allSubsequent: true, allPreceding: true, - subsequentRulesToMatch: 1, precedingRulesToMatch: 1) + condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': true, 'all preceding': true, + 'subsequent rules to match': 1, 'preceding rules to match': 1) } - innerClassRule.create { sort(SortType.BY_NAME ) } + innerClassRule.create { 'sort by'(SortOption.NAME ) } mySettings.extractedMethodsSettings.moveExtractedMethods = false if (doGlobalPattern) { @@ -298,61 +311,46 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { public final void testReturnTypeMatch() throws Exception { doTest('RearrangementTest12', 'RearrangementResult12') { - methodRule.create { returnType( 'void' ) } - fieldRule.create { type( 'int' ) } - methodRule.create { returnType( '.*je.*' ) } - methodRule.create { returnType( /Integer\[\]/) } - methodRule.create { returnType( 'int' ) } + methodRule.create { 'return type'( 'void' ) } + fieldRule.create { type( 'int' ) } + methodRule.create { 'return type'( '.*je.*' ) } + methodRule.create { 'return type'( /Integer\[\]/) } + methodRule.create { 'return type'( 'int' ) } } } public final void testRelatedMethodsDepthOriginal() throws Exception { doTest('RearrangementTest13', 'RearrangementResult13DO') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = true - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.RETAIN_ORIGINAL_ORDER + settings.'extracted methods'( 'depth-first order': true, order: RelatedMethodsSettings.RETAIN_ORIGINAL_ORDER ) } } public final void testRelatedMethodsDepthAlphabetical() throws Exception { doTest('RearrangementTest13', 'RearrangementResult13DA') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = true - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.ALPHABETICAL_ORDER + settings.'extracted methods'( 'depth-first order': true, order: RelatedMethodsSettings.ALPHABETICAL_ORDER ) } } public final void testRelatedMethodsDepthInvocation() throws Exception { doTest('RearrangementTest13', 'RearrangementResult13DI') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = true - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.INVOCATION_ORDER + settings.'extracted methods'( 'depth-first order': true, order: RelatedMethodsSettings.INVOCATION_ORDER ) } } public final void testRelatedMethodsBreadthOriginal() throws Exception { doTest('RearrangementTest13', 'RearrangementResult13BO') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = false - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.RETAIN_ORIGINAL_ORDER + settings.'extracted methods'( 'depth-first order': false, order: RelatedMethodsSettings.RETAIN_ORIGINAL_ORDER ) } } public final void testRelatedMethodsBreadthAlphabetical() throws Exception { doTest('RearrangementTest13', 'RearrangementResult13BA') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = false - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.ALPHABETICAL_ORDER + settings.'extracted methods'( 'depth-first order': false, order: RelatedMethodsSettings.ALPHABETICAL_ORDER) } } public final void testRelatedMethodsBreadthInvocation() throws Exception { doTest('RearrangementTest13', 'RearrangementResult13BI') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = false - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.INVOCATION_ORDER + settings.'extracted methods'( 'depth-first order': false, order: RelatedMethodsSettings.INVOCATION_ORDER) } } private void doTestEmitComments(args) { doTest(args.initial?: 'RearrangementTest13', args.expected) { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = args.depthFirst - mySettings.extractedMethodsSettings.ordering = args.orderType - mySettings.extractedMethodsSettings.commentType = args.commentType + settings.'extracted methods'( 'depth-first order': args.depthFirst, order: args.orderType, commentType: args.commentType ) def precedingCommentRule = new CommentRule() precedingCommentRule.commentText = '''\ @@ -373,161 +371,156 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { public final void testEmitTLCommentsRelatedMethodsBreadthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13BITLC', - depthFirst: false, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_TOP_LEVEL + expected: 'RearrangementResult13BITLC', + depthFirst: false, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_TOP_LEVEL ) } public final void testEmitEMCommentsRelatedMethodsBreadthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13BIEMC', - depthFirst: false, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_METHOD + expected: 'RearrangementResult13BIEMC', + depthFirst: false, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_METHOD ) } public final void testEmitELCommentsRelatedMethodsBreadthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13BIELC', - depthFirst: false, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_LEVEL + expected: 'RearrangementResult13BIELC', + depthFirst: false, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_LEVEL ) } public final void testEmitNFCommentsRelatedMethodsBreadthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13BINFC', - depthFirst: false, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_NEW_FAMILY + expected: 'RearrangementResult13BINFC', + depthFirst: false, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_NEW_FAMILY ) } public final void testEmitTLCommentsRelatedMethodsDepthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13DITLC', - depthFirst: true, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_TOP_LEVEL + expected: 'RearrangementResult13DITLC', + depthFirst: true, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_TOP_LEVEL ) } public final void testEmitEMCommentsRelatedMethodsDepthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13DIEMC', - depthFirst: true, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_METHOD + expected: 'RearrangementResult13DIEMC', + depthFirst: true, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_METHOD ) } public final void testEmitELCommentsRelatedMethodsDepthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13BIELC', - depthFirst: false, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_LEVEL + expected: 'RearrangementResult13BIELC', + depthFirst: false, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_LEVEL ) } public final void testEmitNFCommentsRelatedMethodsDepthInvocation() throws Exception { doTestEmitComments( - expected: 'RearrangementResult13DINFC', - depthFirst: true, - orderType: RelatedMethodsSettings.INVOCATION_ORDER, - commentType: RelatedMethodsSettings.COMMENT_TYPE_NEW_FAMILY + expected: 'RearrangementResult13DINFC', + depthFirst: true, + orderType: RelatedMethodsSettings.INVOCATION_ORDER, + commentType: RelatedMethodsSettings.COMMENT_TYPE_NEW_FAMILY ) } public final void testRelatedMethodsException() throws Exception { doTest('RearrangementTest13', 'RearrangementResult13Ex') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = true - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.RETAIN_ORIGINAL_ORDER + settings.'extracted methods'( 'depth-first order': true, order: RelatedMethodsSettings.RETAIN_ORIGINAL_ORDER ) methodRule.create { name('GF') } } } public final void testKeepOverloadedMethodsTogether() throws Exception { doTest('RearrangementTest14', 'RearrangementResult14') { - mySettings.extractedMethodsSettings.moveExtractedMethods = true - mySettings.extractedMethodsSettings.depthFirstOrdering = false - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.INVOCATION_ORDER - mySettings.keepOverloadedMethodsTogether = true - } } + settings.configure { + 'extracted methods'( 'depth-first order': false, order: RelatedMethodsSettings.INVOCATION_ORDER ) + 'keep together'( 'overloaded' ) + } } } public final void testXML() throws Exception { doTest('RearrangementTest17', 'RearrangementTest17', 'xml') } public final void testKeepGSTogether() throws Exception { doTest('RearrangementTest18', 'RearrangementResult18') { - mySettings.keepGettersSettersTogether = true - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.ALPHABETICAL_ORDER + settings.configure { + 'extracted methods'( order: RelatedMethodsSettings.INVOCATION_ORDER ) + 'keep together'( 'getters and setters' ) + } fieldRule.create {} methodRule.create { target( MethodType.CONSTRUCTOR ) } methodRule.create { target( MethodType.GETTER_OR_SETTER ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } } } public final void testKeepGSWithProperty() throws Exception { doTest('RearrangementTest18', 'RearrangementResult18A') { - mySettings.keepGettersSettersTogether = true - mySettings.keepGettersSettersWithProperty = true - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.ALPHABETICAL_ORDER + settings.configure { + 'extracted methods'( order: RelatedMethodsSettings.ALPHABETICAL_ORDER ) + 'keep together'([ 'getters and setters', 'getters and setters with property' ]) + } fieldRule.create { } methodRule.create { target(MethodType.CONSTRUCTOR) } methodRule.create { target( MethodType.GETTER_OR_SETTER ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } } } public final void testKeepGSWithPropertyElseTogether() throws Exception { doTest('RearrangementTest18B', 'RearrangementResult18B') { - mySettings.keepGettersSettersTogether = true - mySettings.keepGettersSettersWithProperty = true - mySettings.extractedMethodsSettings.ordering = RelatedMethodsSettings.ALPHABETICAL_ORDER + settings.configure { + 'extracted methods'( order: RelatedMethodsSettings.ALPHABETICAL_ORDER ) + 'keep together'([ 'getters and setters', 'getters and setters with property' ]) + } fieldRule.create { } commentRule.create { comment('// Getters/Setters', condition: CommentRule.EMIT_ALWAYS) } methodRule.create { target( MethodType.GETTER_OR_SETTER ) - getterCriteria( + 'getter criteria'( name: GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX, body: GetterSetterDefinition.GETTER_BODY_IMMATERIAL ) - setterCriteria( + 'setter criteria'( name: GetterSetterDefinition.SETTER_NAME_CORRECT_PREFIX, body: GetterSetterDefinition.SETTER_BODY_IMMATERIAL ) - sort( SortType.BY_NAME ) + 'sort by'( SortOption.NAME ) } commentRule.create { comment('// Other Methods', condition: CommentRule.EMIT_ALWAYS) } - methodRule.create { sort( SortType.BY_NAME ) } + methodRule.create { 'sort by'( SortOption.NAME ) } } } public final void testKeepOverloadsTogetherOriginalOrder() throws Exception { doTest('RearrangementTest19', 'RearrangementResult19A') { - mySettings.extractedMethodsSettings.moveExtractedMethods = false - mySettings.keepOverloadedMethodsTogether = true - mySettings.overloadedOrder = RearrangerSettings.OVERLOADED_ORDER_RETAIN_ORIGINAL + settings.'overloaded methods'( 'keep together': true, order: RearrangerSettings.OVERLOADED_ORDER_RETAIN_ORIGINAL ) } } public final void testKeepOverloadsTogetherAscendingOrder() throws Exception { doTest('RearrangementTest19', 'RearrangementResult19B') { - mySettings.extractedMethodsSettings.moveExtractedMethods = false - mySettings.keepOverloadedMethodsTogether = true - mySettings.overloadedOrder = RearrangerSettings.OVERLOADED_ORDER_ASCENDING_PARAMETERS + settings.'overloaded methods'( 'keep together': true, order: RearrangerSettings.OVERLOADED_ORDER_ASCENDING_PARAMETERS ) } } public final void testKeepOverloadsTogetherDescendingOrder() throws Exception { doTest('RearrangementTest19', 'RearrangementResult19C') { - mySettings.extractedMethodsSettings.moveExtractedMethods = false - mySettings.keepOverloadedMethodsTogether = true - mySettings.overloadedOrder = RearrangerSettings.OVERLOADED_ORDER_DESCENDING_PARAMETERS + settings.'overloaded methods'( 'keep together': true, order: RearrangerSettings.OVERLOADED_ORDER_DESCENDING_PARAMETERS ) } } public final void testInnerClassReferenceToChild() throws Exception { @@ -537,7 +530,7 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { public final void testMultipleFieldDecl() throws Exception { doTest('RearrangementTest21', 'RearrangementResult21') { - fieldRule.create { sort( SortType.BY_NAME ) } + fieldRule.create { 'sort by'( SortOption.NAME ) } } } public final void testRemoveBlankLines() throws Exception { @@ -602,7 +595,7 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest('GetterDefinitionTest', 'GetPrefixImmaterialResult') { methodRule.create { target( MethodType.GETTER_OR_SETTER ) - getterCriteria( + 'getter criteria'( name: GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX, body: GetterSetterDefinition.GETTER_BODY_IMMATERIAL ) } } } @@ -611,7 +604,7 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest('GetterDefinitionTest', 'GetPrefixReturnsResult') { methodRule.create { target( MethodType.GETTER_OR_SETTER ) - getterCriteria( + 'getter criteria'( name: GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX, body: GetterSetterDefinition.GETTER_BODY_RETURNS ) } } } @@ -620,7 +613,7 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest('GetterDefinitionTest', 'GetPrefixReturnsFieldResult') { methodRule.create { target( MethodType.GETTER_OR_SETTER ) - getterCriteria( + 'getter criteria'( name: GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX, body: GetterSetterDefinition.GETTER_BODY_RETURNS_FIELD ) } } } @@ -629,7 +622,7 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest('GetterDefinitionTest', 'GetFieldReturnsResult') { methodRule.create { target( MethodType.GETTER_OR_SETTER ) - getterCriteria( + 'getter criteria'( name: GetterSetterDefinition.GETTER_NAME_MATCHES_FIELD, body: GetterSetterDefinition.GETTER_BODY_RETURNS ) } } } @@ -638,7 +631,7 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest('GetterDefinitionTest', 'GetFieldReturnsFieldResult') { methodRule.create { target( MethodType.GETTER_OR_SETTER ) - getterCriteria( + 'getter criteria'( name: GetterSetterDefinition.GETTER_NAME_MATCHES_FIELD, body: GetterSetterDefinition.GETTER_BODY_RETURNS_FIELD ) } } } @@ -647,1003 +640,474 @@ class RearrangerTest extends LightCodeInsightFixtureTestCase { doTest('RearrangementTest22', 'RearrangementResult22') { methodRule.create { target( MethodType.GETTER_OR_SETTER ) - getterCriteria( + 'getter criteria'( name: GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX, body: GetterSetterDefinition.GETTER_BODY_RETURNS ) - setterCriteria( + 'setter criteria'( name: GetterSetterDefinition.SETTER_NAME_CORRECT_PREFIX, body: GetterSetterDefinition.SETTER_BODY_IMMATERIAL ) } mySettings.keepGettersSettersTogether = true } } -// public void testInterfaceNoNameNotAlphabeticalNoExcludeMethodAlphabetical() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest23.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(false); -// InterfaceAttributes ia = new InterfaceAttributes(); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Header ****/"); -// ia.setPrecedingComment(cr); -// cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Trailer ***/"); -// ia.setTrailingComment(cr); -// ia.setNoExtractedMethods(true); -// ia.setMethodOrder(InterfaceAttributes.METHOD_ORDER_ALPHABETICAL); -// ia.setAlphabetizeInterfaces(false); -// rs.addItem(ia, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult23NNNANXMA.java"); -// } -// -// public void testInterfaceNoNameNotAlphabeticalNoExcludeMethodEncountered() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest23.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(false); -// InterfaceAttributes ia = new InterfaceAttributes(); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Header ****/"); -// ia.setPrecedingComment(cr); -// cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Trailer ***/"); -// ia.setTrailingComment(cr); -// ia.setNoExtractedMethods(true); -// ia.setMethodOrder(InterfaceAttributes.METHOD_ORDER_ENCOUNTERED); -// ia.setAlphabetizeInterfaces(false); -// rs.addItem(ia, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult23NNNANXME.java"); -// } -// -// public void testInterfaceNoNameNotAlphabeticalNoExcludeMethodInterfaceOrder() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest23.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(false); -// InterfaceAttributes ia = new InterfaceAttributes(); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Header ****/"); -// ia.setPrecedingComment(cr); -// cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Trailer ***/"); -// ia.setTrailingComment(cr); -// ia.setNoExtractedMethods(true); -// ia.setMethodOrder(InterfaceAttributes.METHOD_ORDER_INTERFACE_ORDER); -// ia.setAlphabetizeInterfaces(false); -// rs.addItem(ia, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult23NNNANXMI.java"); -// } -// -// public void testInterfaceByNameNotAlphabeticalNoExcludeMethodEncountered() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest23.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(false); -// InterfaceAttributes ia = new InterfaceAttributes(); -// ia.getNameAttr().setMatch(true); -// ia.getNameAttr().setExpression("IFace1"); -// ia.setNoExtractedMethods(true); -// ia.setMethodOrder(InterfaceAttributes.METHOD_ORDER_ENCOUNTERED); -// ia.setAlphabetizeInterfaces(false); -// rs.addItem(ia, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult23BNNANXME.java"); -// } -// -// public void testInterfaceIsAlphabeticalNoExcludeMethodEncountered() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest23.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(false); -// InterfaceAttributes ia = new InterfaceAttributes(); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Header ****/"); -// ia.setPrecedingComment(cr); -// cr = new CommentRule(); -// cr.setCommentText("/**** Interface %IF% Trailer ***/"); -// ia.setTrailingComment(cr); -// ia.setNoExtractedMethods(true); -// ia.setMethodOrder(InterfaceAttributes.METHOD_ORDER_ENCOUNTERED); -// ia.setAlphabetizeInterfaces(true); -// rs.addItem(ia, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult23NNIANXME.java"); -// } -// -// public void testNPE24() throws Exception { -// // submitted by Nathan Brown. Caused NPE in Rearranger plugin version 1.7. -// int itemIndex = 0; -// configureByFile("/com/wrq/rearranger/RearrangementTest24.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(true); -// rs.setKeepOverloadedMethodsTogether(true); -//// rs.setAskBeforeRearranging(false); -// rs.setOverloadedOrder(1); -// rs.setGlobalCommentPattern(""); -// rs.setRemoveBlanksInsideCodeBlocks(false); -// FieldAttributes fa; -// fa = new FieldAttributes(); -// fa.getSortAttr().setByName(false); -// fa.getPlAttr().setPlPublic(true); -// fa.getPlAttr().setPlPrivate(true); -// fa.getPlAttr().setPlProtected(true); -// fa.getPlAttr().setPlPackage(true); -// fa.getPlAttr().setInvertProtectionLevel(false); -// fa.getStAttr().setValue(true); -// fa.getStAttr().setInvert(false); -// rs.addItem(fa, itemIndex++); -// fa = new FieldAttributes(); -// fa.getStAttr().setValue(true); -// fa.getStAttr().setInvert(true); -// fa.getInitToAnonClassAttr().setValue(true); -// fa.getInitToAnonClassAttr().setInvert(true); -// rs.addItem(fa, itemIndex++); -// fa = new FieldAttributes(); -// fa.getInitToAnonClassAttr().setValue(true); -// rs.addItem(fa, itemIndex++); -// MethodAttributes ma; -// ma = new MethodAttributes(); -// ma.getStaticInitAttr().setValue(true); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.setConstructorMethodType(true); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.getNameAttr().setMatch(true); -// ma.getNameAttr().setExpression("clone"); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.getNameAttr().setMatch(true); -// ma.getNameAttr().setExpression("dispose"); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.getNameAttr().setMatch(true); -// ma.getNameAttr().setExpression("_dispose"); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.getNameAttr().setMatch(true); -// ma.getNameAttr().setExpression("build"); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.getAbstractAttr().setValue(true); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.getStAttr().setValue(true); -// ma.getStAttr().setInvert(true); -// ma.getAbstractAttr().setValue(true); -// ma.getAbstractAttr().setInvert(true); -// ma.setOtherMethodType(true); -// rs.addItem(ma, itemIndex++); -// ma = new MethodAttributes(); -// ma.setGetterSetterMethodType(true); -// rs.addItem(ma, itemIndex++); -// InnerClassAttributes ica = new InnerClassAttributes(); -// rs.addItem(ica, itemIndex++); -// ma = new MethodAttributes(); -// ma.getStAttr().setValue(true); -// rs.addItem(ma, itemIndex); -// rs.getExtractedMethodsSettings().setMoveExtractedMethods(true); -// rs.getExtractedMethodsSettings().setBelowFirstCaller(false); -// rs.getExtractedMethodsSettings().setDepthFirstOrdering(true); -// rs.getExtractedMethodsSettings().setOrdering(0); -// rs.getExtractedMethodsSettings().setNonPrivateTreatment(2); -// rs.getExtractedMethodsSettings().setCommentType(0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// } -// -// public void testSpacingOptions() throws Exception { -// /** -// * From Thomas Singer: -// * I've enabled -// * - Force 0 blank lines before class close brace "}" -// * - Force 0 blank lines before method close brace "}" -// * - Remove initial and final blank lines inside code block -// * but in the code below the blank lines don't get removed when invoking -// * Rearrager from editor's context menu: -// */ -// configureByFile("/com/wrq/rearranger/RearrangementTest25.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.getBeforeClassRBrace().setForce(true); -// rs.getBeforeClassRBrace().setnBlankLines(0); -// rs.getBeforeMethodRBrace().setForce(true); -// rs.getBeforeMethodRBrace().setnBlankLines(0); -// rs.setRemoveBlanksInsideCodeBlocks(true); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult25.java"); -// } -// -// public void testPriority() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// MethodAttributes ma; -// ma = new MethodAttributes(); -// ma.setPriority(1); -// rs.addItem(ma, 0); -// ma = new MethodAttributes(); -// ma.setPriority(2); -// ma.getNameAttr().setMatch(true); -// ma.getNameAttr().setExpression("method.*"); -// rs.addItem(ma, 1); -// ma = new MethodAttributes(); -// ma.setPriority(2); -// ma.getNameAttr().setMatch(true); -// ma.getNameAttr().setExpression(".*Method"); -// rs.addItem(ma, 2); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult1A.java"); -// } -// -// public void testGSRuleWithClassInitializer() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest26.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// MethodAttributes ma; -// ma = new MethodAttributes(); -// ma.setGetterSetterMethodType(true); -// rs.addItem(ma, 0); -// rs.setKeepGettersSettersTogether(true); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult26.java"); -// } -// -// public void testKeepGSTogetherAndExtractedMethods() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest27.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(true); -// rs.setKeepOverloadedMethodsTogether(true); -// rs.getExtractedMethodsSettings().setMoveExtractedMethods(true); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult27.java"); -// } -// -// public void testRegexEscape() throws Exception { -// String s = "// ********* start of fields *********"; -// String result = RegexUtil.escape(s); -// assertEquals("sequence reduction failed", "// \\*{9} start of fields \\*{9}", result); -// s = "// \\ backslash \n \t \\d [...] (^...$)"; -// result = RegexUtil.escape(s); -// assertEquals("special character escape failed", "// \\\\ backslash \\n \\t \\\\d \\[\\.\\.\\.\\]" + -// " \\(\\^\\.\\.\\.\\$\\)", result); -// } -// -// public void testRegexCombine() throws Exception { -// String p1 = RegexUtil.escape("// ********* start of fields *********"); -// String p2 = RegexUtil.escape("// ********* start of methods *********"); -// List list = new ArrayList(); -// list.add(p1); -// list.add(p2); -// String result = RegexUtil.combineExpressions(list); -// assertEquals("combination failed", "// \\*{9} start of (fiel|metho)ds \\*{9}", result); -// String p3 = RegexUtil.escape("// ***** start of interfaces *******"); -// list.add(p3); -// result = RegexUtil.combineExpressions(list); -// assertEquals("combination failed", "// (\\*{9} start of (fiel|metho)ds \\*{9}|" + -// "\\*{5} start of interfaces \\*{7})", result); -// } -// -// public void testVariousComments() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest28.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(true); -// rs.setKeepOverloadedMethodsTogether(true); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("// start of fields"); -// cr.setEmitCondition(CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE); -// cr.setAllSubsequentRules(true); -// cr.setnSubsequentRulesToMatch(1); -// rs.addItem(cr, 0); -// FieldAttributes fa = new FieldAttributes(); -// rs.addItem(fa, 1); -// cr = new CommentRule(); -// cr.setCommentText("// end of fields"); -// cr.setEmitCondition(CommentRule.EMIT_IF_ITEMS_MATCH_PRECEDING_RULE); -// cr.setAllPrecedingRules(true); -// cr.setnPrecedingRulesToMatch(1); -// rs.addItem(cr, 2); -// InterfaceAttributes ia = new InterfaceAttributes(); -// ia.setMethodOrder(InterfaceAttributes.METHOD_ORDER_ENCOUNTERED); -// ia.setAlphabetizeInterfaces(false); -// ia.setNoExtractedMethods(false); -// cr = new CommentRule(); -// cr.setCommentText("// start of interface %IF%"); -// ia.setPrecedingComment(cr); -// cr = new CommentRule(); -// cr.setCommentText("// end of interface %IF%"); -// ia.setTrailingComment(cr); -// rs.addItem(ia, 3); -// rs.getExtractedMethodsSettings().setBelowFirstCaller(false); -// rs.getExtractedMethodsSettings().setMoveExtractedMethods(true); -// rs.getExtractedMethodsSettings().setCommentType(RelatedMethodsSettings.COMMENT_TYPE_EACH_LEVEL); -// rs.getExtractedMethodsSettings().setNonPrivateTreatment(RelatedMethodsSettings.NON_PRIVATE_EXTRACTED_ANY_CALLERS); -// rs.getExtractedMethodsSettings().setDepthFirstOrdering(true); -// cr = new CommentRule(); -// cr.setCommentText("// Level %LV% methods"); -// rs.getExtractedMethodsSettings().setPrecedingComment(cr); -// cr = new CommentRule(); -// cr.setCommentText("// end Level %LV% methods"); -// rs.getExtractedMethodsSettings().setTrailingComment(cr); -// // should work with or without the global comment pattern -//// rs.setGlobalCommentPattern("// (((start|end) of (fields|interface [A-Za-z_0-9]+))|(end|)Level [0-9]+ methods)"); -// rah.rearrangeDocument(getProject(), file, rs, doc); // note - blank lines end up "reversed" -// // where a blank line, generated comment, and method occur in order; the generated comment is removed -// // and the blank line precedes the method; when the new comment is generated, it is inserted before -// // the blank line. -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult28.java"); -// } -// -// public void testParseBugInfiniteLoop() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest29.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementTest29.java"); -// } -// -// public void testSpacingBug() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest30.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.getAfterClassLBrace().setForce(true); -// rs.getAfterClassLBrace().setnBlankLines(0); -// rs.getAfterClassRBrace().setForce(true); -// rs.getAfterClassRBrace().setnBlankLines(1); -// rs.getAfterMethodLBrace().setForce(true); -// rs.getAfterMethodLBrace().setnBlankLines(0); -// rs.getAfterMethodRBrace().setForce(true); -// rs.getAfterMethodRBrace().setnBlankLines(1); -// rs.getBeforeClassRBrace().setForce(true); -// rs.getBeforeClassRBrace().setnBlankLines(0); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// rs.setRemoveBlanksInsideCodeBlocks(true); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult30.java"); -// } -// -// public void testSpacingBug2() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest31.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.getAfterClassLBrace().setForce(true); -// rs.getAfterClassLBrace().setnBlankLines(0); -// rs.getAfterClassRBrace().setForce(true); -// rs.getAfterClassRBrace().setnBlankLines(1); -// rs.getAfterMethodLBrace().setForce(true); -// rs.getAfterMethodLBrace().setnBlankLines(0); -// rs.getAfterMethodRBrace().setForce(true); -// rs.getAfterMethodRBrace().setnBlankLines(1); -// rs.getBeforeClassRBrace().setForce(true); -// rs.getBeforeClassRBrace().setnBlankLines(0); -// rs.getBeforeMethodRBrace().setForce(true); -// rs.getBeforeMethodRBrace().setnBlankLines(0); -// rs.setRemoveBlanksInsideCodeBlocks(true); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult31.java"); -// } -// -// public void testSpacingBug3() throws Exception { -// configureByFile("/com/wrq/rearranger/DomainExpanderTest.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.getAfterClassLBrace().setForce(true); -// rs.getAfterClassLBrace().setnBlankLines(0); -// rs.getAfterClassRBrace().setForce(true); -// rs.getAfterClassRBrace().setnBlankLines(1); -// rs.getAfterMethodLBrace().setForce(true); -// rs.getAfterMethodLBrace().setnBlankLines(0); -// rs.getAfterMethodRBrace().setForce(true); -// rs.getAfterMethodRBrace().setnBlankLines(0); -// rs.getBeforeClassRBrace().setForce(true); -// rs.getBeforeClassRBrace().setnBlankLines(0); -// rs.getBeforeMethodRBrace().setForce(true); -// rs.getBeforeMethodRBrace().setnBlankLines(0); -// rs.setRemoveBlanksInsideCodeBlocks(true); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/DomainExpanderResult.java"); -// } -// -// /** -// * Bug occurs when one or more blank lines precede a generated comment. -// * When comment is removed, blank lines now precede the item. Comment is inserted -// * at the beginning (i.e. before the blank lines) and a newline character is -// * prefixed to the comment. Net effect is that new blank line(s) appear after the comment. -// * -// * @throws Exception test exception -// */ -// public void testGeneratedCommentSpacingBug() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest32.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult32.java"); -// } -// -// public void testGeneratedCommentSpacing() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest32.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult32.java"); -// } -// -// public void testInnerClassComments() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest34.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.setRearrangeInnerClasses(true); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("// ----- OUTER CLASS -----\n"); -// rs.getClassOrderAttributeList().add(0, cr); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult34.java"); -// } -// -// public void testInnerClassCommentsNoRearrangement() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest34.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.setRearrangeInnerClasses(false); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("// ----- OUTER CLASS -----\n"); -// rs.getClassOrderAttributeList().add(0, cr); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult34B.java"); -// } -// -// public void testFirstInsertionOfComment() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest35.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// CommentRule cr = new CommentRule(); -// cr.setCommentText("// ----- FIELDS -----\n"); -// FieldAttributes fa = new FieldAttributes(); -// rs.addItem(cr, 0); -// rs.addItem(fa, 1); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult35.java"); -// } -// -// public void testExcludeFromExtraction() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest36.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementTest36.java"); -// } -// -// public void testInterferingGSNames() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest37.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(true); -// rs.getDefaultGSDefinition().setGetterBodyCriterion(GetterSetterDefinition.GETTER_BODY_IMMATERIAL); -// rs.getDefaultGSDefinition().setGetterNameCriterion(GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX); -// rs.getDefaultGSDefinition().setSetterBodyCriterion(GetterSetterDefinition.SETTER_BODY_IMMATERIAL); -// rs.getDefaultGSDefinition().setSetterNameCriterion(GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult37.java"); -// } -// -// public void testInterferingGSNamesNoKGSTogether() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest37.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.setKeepGettersSettersTogether(false); -// rs.getDefaultGSDefinition().setGetterBodyCriterion(GetterSetterDefinition.GETTER_BODY_IMMATERIAL); -// rs.getDefaultGSDefinition().setGetterNameCriterion(GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX); -// rs.getDefaultGSDefinition().setSetterBodyCriterion(GetterSetterDefinition.SETTER_BODY_IMMATERIAL); -// rs.getDefaultGSDefinition().setSetterNameCriterion(GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementTest37.java"); -// } -// -// public void testRemoveBlankLineInsideMethodBug() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest38.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// File settingsFile = new File(InteractiveTest.DEFAULT_CONFIGURATION_ROOT + -// "/test/testData/com/wrq/rearranger/RearrangementTest38cfg.xml"); -// rs = RearrangerSettings.getSettingsFromFile(settingsFile); -// rs.setAskBeforeRearranging(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementTest38.java"); -// } -// -// public void testSortFieldsByTypeAndName() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest39.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getSortAttr().setByType(true); -// fa.getSortAttr().setByName(true); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult39B.java"); -// } -// -// public void testSortFieldsByType() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest39.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getSortAttr().setByType(true); -// fa.getSortAttr().setByName(false); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult39C.java"); -// } -// -// public void testSortFieldsByTypeICAndName() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest39.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getSortAttr().setByType(true); -// fa.getSortAttr().setTypeCaseInsensitive(true); -// fa.getSortAttr().setByName(true); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult39.java"); -// } -// -// public void testSortFieldsByTypeIC() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest39.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getSortAttr().setByType(true); -// fa.getSortAttr().setTypeCaseInsensitive(true); -// fa.getSortAttr().setByName(false); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult39A.java"); -// } -// -// /** -// * test detection of method overrides/overridden/implements/implemented attributes. -// * -// * @throws Exception test exception -// */ -// public void testOverImpl() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest40.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult40.java"); -// } -// -// public final void testRemoveBlankLinesBeforeMethod() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest41.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rs.getAfterClassLBrace().setForce(true); -// rs.getAfterClassLBrace().setnBlankLines(0); -// rs.getBeforeMethodLBrace().setForce(true); -// rs.getBeforeMethodLBrace().setnBlankLines(0); -// rs.getAfterMethodLBrace().setForce(true); -// rs.getAfterMethodLBrace().setnBlankLines(0); -// rs.getBeforeMethodRBrace().setForce(true); -// rs.getBeforeMethodRBrace().setnBlankLines(0); -// rs.getAfterMethodRBrace().setForce(true); -// rs.getAfterMethodRBrace().setnBlankLines(0); -// rs.getBeforeClassRBrace().setForce(true); -// rs.getBeforeClassRBrace().setnBlankLines(0); -// rs.getAfterClassRBrace().setForce(true); -// rs.getAfterClassRBrace().setnBlankLines(0); -// rs.setRemoveBlanksInsideCodeBlocks(true); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult41.java"); -// } -// -// public final void testEnumClass() throws Exception { -// final Project project = getProject(); -// final LanguageLevelProjectExtension llpExtension = LanguageLevelProjectExtension.getInstance(project); -// LanguageLevel oldLevel = llpExtension.getLanguageLevel(); -// llpExtension.setLanguageLevel(LanguageLevel.JDK_1_5); -// configureByFile("/com/wrq/rearranger/RearrangementTest42.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult42.java"); -// llpExtension.setLanguageLevel(oldLevel); -// } -// -// public final void testNumParameters() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest43.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// MethodAttributes ma; -// ma = new MethodAttributes(); -// ma.getMinParamsAttr().setMatch(true); -// ma.getMinParamsAttr().setValue(2); -// ma.getMaxParamsAttr().setMatch(true); -// ma.getMaxParamsAttr().setValue(3); -// rs.addItem(ma, 0); -// ma = new MethodAttributes(); -// ma.getMinParamsAttr().setMatch(true); -// ma.getMinParamsAttr().setValue(1); -// rs.addItem(ma, 1); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult43.java"); -// } -// -// public final void testGeneratedComment() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest44.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// CommentRule cr = new CommentRule(); -// CommentFillString cfs = cr.getCommentFillString(); -// cfs.setFillString("-+"); -// cfs.setUseProjectWidthForFill(false); -// cfs.setFillWidth(30); -// cr.setEmitCondition(CommentRule.EMIT_ALWAYS); -// cr.setCommentText("// %FS% METHODS %FS%"); -// rs.addItem(cr, 0); -// MethodAttributes ma; -// ma = new MethodAttributes(); // match all methods -// rs.addItem(ma, 1); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult44.java"); -// } -// -// public void testEnum1() throws Exception { -// final Project project = getProject(); -// final LanguageLevelProjectExtension llpExtension = LanguageLevelProjectExtension.getInstance(project); -// LanguageLevel oldLevel = llpExtension.getLanguageLevel(); -// llpExtension.setLanguageLevel(LanguageLevel.JDK_1_5); -// configureByFile("/com/wrq/rearranger/Enum1Test.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(project).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// rs.setRearrangeInnerClasses(true); -// rs.getExtractedMethodsSettings().setBelowFirstCaller(true); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(project, file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/Enum1Result.java"); -// llpExtension.setLanguageLevel(oldLevel); -// } -// -// public void testEnum2() throws Exception { -// final Project project = getProject(); -// final LanguageLevelProjectExtension llpExtension = LanguageLevelProjectExtension.getInstance(project); -// LanguageLevel oldLevel = llpExtension.getLanguageLevel(); -// llpExtension.setLanguageLevel(LanguageLevel.JDK_1_5); -// configureByFile("/com/wrq/rearranger/Enum2Test.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(project).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.setRearrangeInnerClasses(true); -// rs.getAfterClassRBrace().setForce(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(project, file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/Enum2Result.java"); -// llpExtension.setLanguageLevel(oldLevel); -// } -// -// public void testEnum2A() throws Exception { -// final Project project = getProject(); -// final LanguageLevelProjectExtension llpExtension = LanguageLevelProjectExtension.getInstance(project); -// LanguageLevel oldLevel = llpExtension.getLanguageLevel(); -// llpExtension.setLanguageLevel(LanguageLevel.JDK_1_5); -// configureByFile("/com/wrq/rearranger/Enum2Test.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(project).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.setRearrangeInnerClasses(false); -// rs.getAfterClassRBrace().setForce(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(project, file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/Enum2AResult.java"); -// llpExtension.setLanguageLevel(oldLevel); -// } -// -// public void testRearrangementIncompleteLastLine() throws Exception { -// configureByFile("/com/wrq/rearranger/IncompleteLineTest.java"); -// final PsiFile file = getFile(); -// Project project = getProject(); -// final Document doc = PsiDocumentManager.getInstance(project).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(project, file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/IncompleteLineResult.java"); -// } -// -// public void testOverloadedMethodCategorization() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest45.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File(InteractiveTest.DEFAULT_CONFIGURATION)); -// rs.setAskBeforeRearranging(false); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(1); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult45.java"); -// } -// -// public void testSuperclassAlgorithm() throws Exception { -// final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(getProject()); -// final PsiClass aClass = -// psiFacade.getElementFactory(). -// createClassFromText("public String toString() {return null;}", null); -// final PsiMethod method = aClass.getMethods()[0]; -// final PsiMethod[] superMethods = method.findSuperMethods(); -// assertEquals(1, superMethods.length); -// PsiClass psiClass = superMethods[0].getContainingClass(); -// if (psiClass == null) { -// fail("missing containing class"); -// } -// else { -// assertEquals("java.lang.Object", psiClass.getQualifiedName()); -// } -// } -// -// public void testSortingOriginalOrder() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest46.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getPlAttr().setPlProtected(true); -// fa.getSortAttr().setByModifiers(false); -// fa.getSortAttr().setByType(false); -// fa.getSortAttr().setTypeCaseInsensitive(false); -// fa.getSortAttr().setByName(false); -// fa.getSortAttr().setNameCaseInsensitive(false); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult46A.java"); -// } -// -// public void testSortingModifierOrder() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest46.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getPlAttr().setPlProtected(true); -// fa.getSortAttr().setByModifiers(true); -// fa.getSortAttr().setByType(false); -// fa.getSortAttr().setTypeCaseInsensitive(false); -// fa.getSortAttr().setByName(false); -// fa.getSortAttr().setNameCaseInsensitive(false); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult46B.java"); -// } -// -// public void testSortingTypeOrder() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest46.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getPlAttr().setPlProtected(true); -// fa.getSortAttr().setByModifiers(false); -// fa.getSortAttr().setByType(true); -// fa.getSortAttr().setTypeCaseInsensitive(false); -// fa.getSortAttr().setByName(false); -// fa.getSortAttr().setNameCaseInsensitive(false); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult46C.java"); -// } -// -// public void testSortingTypeOrderCI() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest46.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getPlAttr().setPlProtected(true); -// fa.getSortAttr().setByModifiers(false); -// fa.getSortAttr().setByType(true); -// fa.getSortAttr().setTypeCaseInsensitive(true); -// fa.getSortAttr().setByName(false); -// fa.getSortAttr().setNameCaseInsensitive(false); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult46D.java"); -// } -// -// public void testSortingMTNOrderCI() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest46.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getPlAttr().setPlProtected(true); -// fa.getSortAttr().setByModifiers(true); -// fa.getSortAttr().setByType(true); -// fa.getSortAttr().setTypeCaseInsensitive(true); -// fa.getSortAttr().setByName(true); -// fa.getSortAttr().setNameCaseInsensitive(true); -// rs.addItem(fa, 0); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult46E.java"); -// } -// -// public void testEnumSelection() throws Exception { -// configureByFile("/com/wrq/rearranger/RearrangementTest47.java"); -// final PsiFile file = getFile(); -// final Project project = getProject(); -// final LanguageLevelProjectExtension llpExtension = LanguageLevelProjectExtension.getInstance(project); -// LanguageLevel oldLevel = llpExtension.getLanguageLevel(); -// llpExtension.setLanguageLevel(LanguageLevel.JDK_1_5); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// FieldAttributes fa = new FieldAttributes(); -// fa.getStAttr().setValue(true); -// rs.addItem(fa, 0); -// InnerClassAttributes ica = new InnerClassAttributes(); -// ica.getEnumAttr().setValue(true); -// rs.addItem(ica, 1); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/RearrangementResult47.java"); -// llpExtension.setLanguageLevel(oldLevel); -// } -// -// public void testOverloaded1() throws Exception { -// configureByFile("/com/wrq/rearranger/OverloadedTest1.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File("testData/com/wrq/rearranger/OverloadedConfig.xml")); -// rs.setAskBeforeRearranging(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/OverloadedResult1.java"); -// } -// -// public void testGenerics1() throws Exception { -// configureByFile("/com/wrq/rearranger/GenericsTest1.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File("testData/com/wrq/rearranger/OverloadedConfig.xml")); -// rs.setAskBeforeRearranging(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/GenericsResult1.java"); -// } -// -// public void testInterface1() throws Exception { -// configureByFile("/com/wrq/rearranger/InterfaceTest1.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// FieldAttributes fa = new FieldAttributes(); -// fa.getPlAttr().setPlPublic(true); // match all public fields; in an interface, all constants are regarded as public -// fa.getStAttr().setValue(true); // match all static fields; in an interface, all constants are regarded as public -// rs.addItem(fa, 0); -// MethodAttributes ma = new MethodAttributes(); -// ma.getPlAttr().setPlPublic(true); // match all public methods; in an interface, all methods are regarded as public -// rs.addItem(ma, 1); -// rs.setAskBeforeRearranging(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/InterfaceResult1.java"); -// } -// -// public void testCorruptRespacing() throws Exception { -// configureByFile("/com/wrq/rearranger/CorruptRespacingTest.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// rs = RearrangerSettings.getSettingsFromFile(new File("testData/com/wrq/rearranger/CorruptionConfig.xml")); -// rs.setAskBeforeRearranging(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/CorruptRespacingResult.java"); -// } -// -// public void testCommentSeparator1() throws Exception { -// configureByFile("/com/wrq/rearranger/CommentSeparatorTest1.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final CommentRule c = new CommentRule(); -// c.setCommentText("\n\t// Fields %FS%\n"); -// c.setEmitCondition(CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE); -// CommentFillString cfs = new CommentFillString(); -// cfs.setFillString("="); -// cfs.setUseProjectWidthForFill(false); -// cfs.setFillWidth(80); -// c.setCommentFillString(cfs); -// rs.addItem(c, 0); -// FieldAttributes fa = new FieldAttributes(); -// fa.getPlAttr().setPlPublic(true); -// rs.addItem(fa, 1); -// rs.setAskBeforeRearranging(false); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.setTabSize(4); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/CommentSeparatorResult1.java"); -// } -// -// public void testEmptySetter() throws Exception { -// configureByFile("/com/wrq/rearranger/BitFieldTest.java"); -// final PsiFile file = getFile(); -// final Document doc = PsiDocumentManager.getInstance(getProject()).getDocument(file); -// final File physFile = new File(InteractiveTest.DEFAULT_CONFIGURATION); -// rs = RearrangerSettings.getSettingsFromFile(physFile); -// rs.setAskBeforeRearranging(false); -// rs.getAfterClassRBrace().setnBlankLines(2); -// rs.getAfterClassRBrace().setForce(true); -// rs.getNewlinesAtEOF().setForce(true); -// rs.getNewlinesAtEOF().setnBlankLines(3); -// final RearrangerActionHandler rah = new RearrangerActionHandler(); -// rah.rearrangeDocument(getProject(), file, rs, doc); -// super.checkResultByFile("/com/wrq/rearranger/BitFieldResult.java"); -// } + public void testInterfaceNoNameNotAlphabeticalNoExcludeMethodAlphabetical() throws Exception { + doTest('RearrangementTest23', 'RearrangementResult23NNNANXMA') { + mySettings.keepGettersSettersTogether = false + interfaceRule.create { + 'preceding comment'( '/**** Interface %IF% Header ****/' ) + 'trailing comment'( '/**** Interface %IF% Trailer ***/' ) + setup( "don't group extracted methods": false, order: InterfaceAttributes.METHOD_ORDER_ALPHABETICAL, alphabetize: false ) + } } } + + public void testInterfaceNoNameNotAlphabeticalNoExcludeMethodEncountered() throws Exception { + doTest('RearrangementTest23', 'RearrangementResult23NNNANXME') { + mySettings.keepGettersSettersTogether = false + interfaceRule.create { + 'preceding comment'( '/**** Interface %IF% Header ****/' ) + 'trailing comment'( '/**** Interface %IF% Trailer ***/' ) + setup( "don't group extracted methods": false, order: InterfaceAttributes.METHOD_ORDER_ENCOUNTERED, alphabetize: false ) + } } } + + public void testInterfaceNoNameNotAlphabeticalNoExcludeMethodInterfaceOrder() throws Exception { + doTest('RearrangementTest23', 'RearrangementResult23NNNANXMI') { + mySettings.keepGettersSettersTogether = false + interfaceRule.create { + 'preceding comment'( '/**** Interface %IF% Header ****/' ) + 'trailing comment'( '/**** Interface %IF% Trailer ***/' ) + setup( "don't group extracted methods": false, order: InterfaceAttributes.METHOD_ORDER_INTERFACE_ORDER, alphabetize: false ) + } } } + + public void testInterfaceByNameNotAlphabeticalNoExcludeMethodEncountered() throws Exception { + doTest('RearrangementTest23', 'RearrangementResult23BNNANXME') { + mySettings.keepGettersSettersTogether = false + interfaceRule.setup( "don't group extracted methods": true, order: InterfaceAttributes.METHOD_ORDER_ENCOUNTERED, + alphabetize: false, name : 'IFace1' + ) } } + + public void testInterfaceIsAlphabeticalNoExcludeMethodEncountered() throws Exception { + doTest('RearrangementTest23', 'RearrangementResult23NNIANXME') { + interfaceRule.create { + 'preceding comment'( '/**** Interface %IF% Header ****/' ) + 'trailing comment'( '/**** Interface %IF% Trailer ***/' ) + setup( "don't group extracted methods": true, order: InterfaceAttributes.METHOD_ORDER_ENCOUNTERED, alphabetize: true ) + } } } + + public void testSpacingOptions() throws Exception { + /* + * From Thomas Singer: + * I've enabled + * - Force 0 blank lines before class close brace "}" + * - Force 0 blank lines before method close brace "}" + * - Remove initial and final blank lines inside code block + * but in the code below the blank lines don't get removed when invoking + * Rearranger from editor's context menu: + */ + doTest('RearrangementTest25', 'RearrangementResult25') { + spacingRule.spacing(anchor: [ SpacingAnchor.BEFORE_CLASS_RBRACE, SpacingAnchor.BEFORE_METHOD_RBRACE ], + lines: 0, 'remove blank lines': true + ) } } + + public void testPriority() throws Exception { + doTest('RearrangementTest', 'RearrangementResult1A') { + methodRule.create { priority( 1 ) } + methodRule.create { + priority( 2 ) + name( 'method.*' ) + } + methodRule.create { + priority( 2 ) + name( '.*Method' ) + } } } + + public void testGSRuleWithClassInitializer() throws Exception { + doTest('RearrangementTest26', 'RearrangementResult26') { + mySettings.keepOverloadedMethodsTogether = true + methodRule.create { + target( MethodType.GETTER_OR_SETTER ) + } } } + + public void testKeepGSTogetherAndExtractedMethods() throws Exception { + doTest('RearrangementTest27', 'RearrangementResult27') { + settings.configure { + 'keep together'([ 'getters and setters', 'overloaded' ]) + 'extracted methods' move: true + } } } + + public void testRegexEscape() throws Exception { + String s = "// ********* start of fields *********"; + String result = RegexUtil.escape(s); + assertEquals("sequence reduction failed", "// \\*{9} start of fields \\*{9}", result); + s = "// \\ backslash \n \t \\d [...] (^...\$)"; + result = RegexUtil.escape(s); + assertEquals("special character escape failed", "// \\\\ backslash \\n \\t \\\\d \\[\\.\\.\\.\\]" + + " \\(\\^\\.\\.\\.\\\$\\)", result); + } + + public void testRegexCombine() throws Exception { + String p1 = RegexUtil.escape("// ********* start of fields *********"); + String p2 = RegexUtil.escape("// ********* start of methods *********"); + List list = new ArrayList(); + list.add(p1); + list.add(p2); + String result = RegexUtil.combineExpressions(list); + assertEquals("combination failed", "// \\*{9} start of (fiel|metho)ds \\*{9}", result); + String p3 = RegexUtil.escape("// ***** start of interfaces *******"); + list.add(p3); + result = RegexUtil.combineExpressions(list); + assertEquals("combination failed", "// (\\*{9} start of (fiel|metho)ds \\*{9}|" + + "\\*{5} start of interfaces \\*{7})", result); + } + + public void testVariousComments() throws Exception { + doTest('RearrangementTest28', 'RearrangementResult28') { + settings.configure{ + 'keep together'([ 'getters and setters', 'overloaded' ]) + 'extracted methods'( 'depth-first order': true, commentType: RelatedMethodsSettings.COMMENT_TYPE_EACH_LEVEL, + 'below first caller': false, + 'non-private treatment': RelatedMethodsSettings.NON_PRIVATE_EXTRACTED_ANY_CALLERS, + 'preceding comment': '// Level %LV% methods', 'trailing comment': '// end Level %LV% methods' ) + } + commentRule.create { + comment('// start of fields', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'all subsequent': true, + 'subsequent rules to match': 1) + } + fieldRule.create { } + commentRule.create { + comment('// end of fields', condition: CommentRule.EMIT_IF_ITEMS_MATCH_PRECEDING_RULE, 'all preceding': true, + 'preceding rules to match': 1) + } + interfaceRule.configure { + 'preceding comment'( '// start of interface %IF%' ) + 'trailing comment'( '// end of interface %IF%' ) + setup( methodOrder: InterfaceAttributes.METHOD_ORDER_ENCOUNTERED, alphabetize: false, 'group extracted methods': false ) + } } + // where a blank line, generated comment, and method occur in order; the generated comment is removed + // and the blank line precedes the method; when the new comment is generated, it is inserted before + // the blank line. + } + + public void testParseBugInfiniteLoop() throws Exception { doTest('RearrangementTest29', 'RearrangementTest29') } + + public void testSpacingBug() throws Exception { + doTest('RearrangementTest30', 'RearrangementResult30') { + spacingRule.create { + spacing( anchor: [ SpacingAnchor.AFTER_CLASS_LBRACE, SpacingAnchor.AFTER_METHOD_LBRACE, SpacingAnchor.BEFORE_CLASS_RBRACE ], + lines: 0 ) + spacing( anchor: [ SpacingAnchor.AFTER_CLASS_RBRACE, SpacingAnchor.AFTER_METHOD_RBRACE, SpacingAnchor.EOF ], + lines: 1 ) + spacing ( 'remove blank lines': true ) + } } } + + public void testSpacingBug2() throws Exception { + doTest('RearrangementTest31', 'RearrangementResult31') { + spacingRule.create { + spacing( anchor: [ SpacingAnchor.AFTER_CLASS_LBRACE, SpacingAnchor.AFTER_METHOD_LBRACE, SpacingAnchor.BEFORE_CLASS_RBRACE, + SpacingAnchor.BEFORE_METHOD_RBRACE ], + lines: 0 ) + spacing( anchor: [ SpacingAnchor.AFTER_CLASS_RBRACE, SpacingAnchor.AFTER_METHOD_RBRACE, SpacingAnchor.EOF ], + lines: 1 ) + spacing ( 'remove blank lines': true ) + } } } + + public void testSpacingBug3() throws Exception { + doTest('DomainExpanderTest', 'DomainExpanderResult') { + spacingRule.create { + spacing( anchor: [ SpacingAnchor.AFTER_CLASS_LBRACE, SpacingAnchor.AFTER_METHOD_LBRACE, + SpacingAnchor.BEFORE_CLASS_RBRACE, SpacingAnchor.BEFORE_METHOD_RBRACE], + lines: 0 ) + spacing( anchor: [ SpacingAnchor.AFTER_CLASS_RBRACE, SpacingAnchor.EOF, SpacingAnchor.AFTER_METHOD_RBRACE ], + lines: 1 ) + spacing ( 'remove blank lines': true ) + } } } + + private void setupSettings(@NotNull String relativePath) { + // Using concat() because simple '+' here produces weird groovy.lang.MissingMethodException: No signature of method: + // java.lang.String.positive() is applicable for argument types: () values: [] + def path = PlatformTestUtil.getCommunityPath().replace(File.separator, '/').concat("/plugins/rearranger") + .concat(relativePath) + mySettings = RearrangerSettings.getSettingsFromFile(new File(path)); + mySettings.askBeforeRearranging = false + + prepareBuilders(mySettings) + } + + /** + * Bug occurs when one or more blank lines precede a generated comment. + * When comment is removed, blank lines now precede the item. Comment is inserted + * at the beginning (i.e. before the blank lines) and a newline character is + * prefixed to the comment. Net effect is that new blank line(s) appear after the comment. + * + * @throws Exception test exception + */ + public void testGeneratedCommentSpacingBug() throws Exception { + doTest('RearrangementTest32', 'RearrangementResult32') { + setupSettings(InteractiveTest.DEFAULT_CONFIGURATION) + spacingRule.spacing(anchor: SpacingAnchor.EOF, lines: 1) + } } + + public void testGeneratedCommentSpacing() throws Exception { + doTest('RearrangementTest32', 'RearrangementResult32') { + setupSettings(InteractiveTest.DEFAULT_CONFIGURATION) + spacingRule.spacing(anchor: SpacingAnchor.EOF, lines: 1) + } } + + public void testInnerClassComments() throws Exception { + doTest('RearrangementTest34', 'RearrangementResult34') { + setupSettings(InteractiveTest.DEFAULT_CONFIGURATION) + spacingRule.spacing(anchor: SpacingAnchor.EOF, lines: 1) + settings.configure( 'rearrange inner classes': true, 'class comment': '// ----- OUTER CLASS -----\n' ) + } } + + public void testInnerClassCommentsNoRearrangement() throws Exception { + doTest('RearrangementTest34', 'RearrangementResult34B') { + setupSettings(InteractiveTest.DEFAULT_CONFIGURATION) + spacingRule.spacing(anchor: SpacingAnchor.EOF, lines: 1) + settings.configure( 'rearrange inner classes': false, 'class comment': '// ----- OUTER CLASS -----\n' ) + } } + + public void testFirstInsertionOfComment() throws Exception { + doTest('RearrangementTest35', 'RearrangementResult35') { + commentRule.comment('// ----- FIELDS -----\n') + fieldRule.create { } + } } + + public void testExcludeFromExtraction() throws Exception { doTest('RearrangementTest36', 'RearrangementTest36') } + + public void testInterferingGSNames() throws Exception { + doTest('RearrangementTest37', 'RearrangementResult37') { + settings.configure { + 'keep together'( 'getters and setters' ) + 'getter criteria'( + name: GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX, + body: GetterSetterDefinition.GETTER_BODY_IMMATERIAL + ) + 'setter criteria'( + name: GetterSetterDefinition.SETTER_NAME_CORRECT_PREFIX, + body: GetterSetterDefinition.SETTER_BODY_IMMATERIAL + ) + } } } + + public void testInterferingGSNamesNoKGSTogether() throws Exception { + doTest('RearrangementTest37', 'RearrangementTest37') { + settings.configure { + 'getter criteria'( + name: GetterSetterDefinition.GETTER_NAME_CORRECT_PREFIX, + body: GetterSetterDefinition.GETTER_BODY_IMMATERIAL + ) + 'setter criteria'( + name: GetterSetterDefinition.SETTER_NAME_CORRECT_PREFIX, + body: GetterSetterDefinition.SETTER_BODY_IMMATERIAL + ) + } } } + + public void testRemoveBlankLineInsideMethodBug() throws Exception { + doTest('RearrangementTest38', 'RearrangementTest38') { + setupSettings('/test/testData/com/wrq/rearranger/RearrangementTest38cfg.xml') + } } + + public void testSortFieldsByTypeAndName() throws Exception { + doTest('RearrangementTest39', 'RearrangementResult39B') { + fieldRule.create { + 'sort by'([ SortOption.NAME, SortOption.TYPE ]) + } } } + + public void testSortFieldsByType() throws Exception { + doTest('RearrangementTest39', 'RearrangementResult39C') { + fieldRule.create { + 'sort by' SortOption.TYPE + 'not sort by' SortOption.NAME + } + } } + + public void testSortFieldsByTypeICAndName() throws Exception { + doTest('RearrangementTest39', 'RearrangementResult39') { + fieldRule.create { + 'sort by'([ SortOption.NAME, SortOption.TYPE, SortOption.TYPE_CASE_INSENSITIVE ]) + } } } + + public void testSortFieldsByTypeIC() throws Exception { + doTest('RearrangementTest39', 'RearrangementResult39A') { + fieldRule.create { + 'sort by'([ SortOption.TYPE, SortOption.TYPE_CASE_INSENSITIVE ]) + 'not sort by' SortOption.NAME + } } } + + /** + * test detection of method overrides/overridden/implements/implemented attributes. + * + * @throws Exception test exception + */ + public void testOverImpl() throws Exception { doTest('RearrangementTest40', 'RearrangementResult40') } + + public final void testRemoveBlankLinesBeforeMethod() throws Exception { + doTest('RearrangementTest41', 'RearrangementResult41') { + spacingRule.create { + spacing(anchor: [ SpacingAnchor.AFTER_CLASS_LBRACE, SpacingAnchor.BEFORE_METHOD_LBRACE, SpacingAnchor.AFTER_METHOD_LBRACE, + SpacingAnchor.BEFORE_METHOD_RBRACE, SpacingAnchor.AFTER_METHOD_RBRACE, SpacingAnchor.BEFORE_CLASS_RBRACE, + SpacingAnchor.AFTER_CLASS_RBRACE], + lines: 0, 'remove blank lines': true) + } + } + } + + public final void testEnumClass() throws Exception { doTest('RearrangementTest42', 'RearrangementResult42') } + + public final void testNumParameters() throws Exception { + doTest('RearrangementTest43', 'RearrangementResult43') { + methodRule.create { + 'arguments number' ( from: 2, to: 3) + } + methodRule.create { + 'arguments number' ( from: 1) + } } } + + public final void testGeneratedComment() throws Exception { + doTest('RearrangementTest44', 'RearrangementResult44') { + commentRule.comment('// %FS% METHODS %FS%', condition: CommentRule.EMIT_ALWAYS, 'fill string': '-+', + 'use project width for fill': false, 'fill width': 30) + methodRule.create { } // match all methods + } } + + public void testEnum1() throws Exception { + doTest('Enum1Test', 'Enum1Result') { + setupSettings( InteractiveTest.DEFAULT_CONFIGURATION ) + spacingRule.create { + spacing( anchor: SpacingAnchor.EOF, lines: 1 ) + } + settings.configure('rearrange inner classes': true ) + settings.'extracted methods'( 'below first caller': true ) + } } + + public void testEnum2() throws Exception { + doTest('Enum2Test', 'Enum2Result') { + setupSettings( InteractiveTest.DEFAULT_CONFIGURATION ) + settings.configure('rearrange inner classes': true ) + mySettings.afterClassRBrace.force = false + } } + + public void testEnum2A() throws Exception { + doTest('Enum2Test', 'Enum2AResult') { + setupSettings( InteractiveTest.DEFAULT_CONFIGURATION ) + settings.configure('rearrange inner classes': false ) + mySettings.afterClassRBrace.force = false + } } + + public void testRearrangementIncompleteLastLine() throws Exception { + doTest('IncompleteLineTest', 'IncompleteLineResult') { + setupSettings( InteractiveTest.DEFAULT_CONFIGURATION ) + } } + + public void testOverloadedMethodCategorization() throws Exception { + doTest('RearrangementTest45', 'RearrangementResult45') { + setupSettings( InteractiveTest.DEFAULT_CONFIGURATION ) + spacingRule.create { + spacing( anchor: SpacingAnchor.EOF, lines: 1 ) + } } } + + public void testSuperclassAlgorithm() throws Exception { + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(getProject()); + final PsiClass aClass = + psiFacade.getElementFactory(). + createClassFromText("public String toString() {return null;}", null); + final PsiMethod method = aClass.getMethods()[0]; + final PsiMethod[] superMethods = method.findSuperMethods(); + assertEquals(1, superMethods.length); + PsiClass psiClass = superMethods[0].getContainingClass(); + if (psiClass == null) { + fail("missing containing class"); + } + else { + assertEquals("java.lang.Object", psiClass.getQualifiedName()); + } + } + + public void testSortingOriginalOrder() throws Exception { + doTest('RearrangementTest46', 'RearrangementResult46A') { + fieldRule.create { + modifier( PsiModifier.PROTECTED ) + 'not sort by' ([ SortOption.TYPE, SortOption.NAME, SortOption.TYPE_CASE_INSENSITIVE, + SortOption.NAME_CASE_INSENSITIVE, SortOption.MODIFIER ]) + } } } + + public void testSortingModifierOrder() throws Exception { + doTest('RearrangementTest46', 'RearrangementResult46B') { + fieldRule.create { + modifier( PsiModifier.PROTECTED ) + 'sort by' ( SortOption.MODIFIER ) + 'not sort by' ([ SortOption.TYPE, SortOption.NAME, SortOption.TYPE_CASE_INSENSITIVE, SortOption.NAME_CASE_INSENSITIVE ]) + } } } + + public void testSortingTypeOrder() throws Exception { + doTest('RearrangementTest46', 'RearrangementResult46C') { + fieldRule.create { + modifier( PsiModifier.PROTECTED ) + 'sort by' ( SortOption.TYPE ) + 'not sort by' ([ SortOption.MODIFIER, SortOption.NAME, SortOption.TYPE_CASE_INSENSITIVE, SortOption.NAME_CASE_INSENSITIVE ]) + } } } + + public void testSortingTypeOrderCI() throws Exception { + doTest('RearrangementTest46', 'RearrangementResult46D') { + fieldRule.create { + modifier( PsiModifier.PROTECTED ) + 'sort by' ([ SortOption.TYPE, SortOption.TYPE_CASE_INSENSITIVE ]) + 'not sort by' ([ SortOption.MODIFIER, SortOption.NAME, SortOption.NAME_CASE_INSENSITIVE ]) + } } } + + public void testSortingMTNOrderCI() throws Exception { + doTest('RearrangementTest46', 'RearrangementResult46E') { + fieldRule.create { + modifier( PsiModifier.PROTECTED ) + 'sort by' ([ SortOption.MODIFIER, SortOption.TYPE, SortOption.TYPE_CASE_INSENSITIVE, SortOption.NAME, + SortOption.NAME_CASE_INSENSITIVE ]) + } } } + + public void testEnumSelection() throws Exception { + doTest('RearrangementTest47', 'RearrangementResult47') { + fieldRule.create { modifier( PsiModifier.STATIC ) } + innerClassRule.create ( 'enum': true ) + } } + + public void testOverloaded1() throws Exception { + doTest('OverloadedTest1', 'OverloadedResult1') { + setupSettings('/test/testData/com/wrq/rearranger/OverloadedConfig.xml') + } } + + public void testGenerics1() throws Exception { + doTest('GenericsTest1', 'GenericsResult1') { + setupSettings('/test/testData/com/wrq/rearranger/OverloadedConfig.xml') + } } + + public void testInterface1() throws Exception { + doTest('InterfaceTest1', 'InterfaceResult1') { + // Match all public fields; in an interface, all constants are regarded as public + fieldRule.create { modifier([ PsiModifier.PUBLIC, PsiModifier.STATIC ]) } + + // Match all public methods; in an interface, all methods are regarded as public + methodRule.create { modifier( PsiModifier.PUBLIC ) } + } } + + public void testCommentSeparator1() throws Exception { + doTest('CommentSeparatorTest1', 'CommentSeparatorResult1') { + commentRule.create { + comment('\n\t// Fields %FS%\n', condition: CommentRule.EMIT_IF_ITEMS_MATCH_SUBSEQUENT_RULE, 'fill string': '=', + 'use project width for fill': false, 'fill width': 80) + } + fieldRule.create { modifier( PsiModifier.PUBLIC ) } + } } + + public void testEmptySetter() throws Exception { + doTest('BitFieldTest', 'BitFieldResult') { + setupSettings(InteractiveTest.DEFAULT_CONFIGURATION) + spacingRule.create { + spacing( anchor: SpacingAnchor.AFTER_CLASS_RBRACE, lines: 2 ) + spacing( anchor: SpacingAnchor.EOF, lines: 3 ) + } } } private void doTest(@NotNull String srcFileName, @Nullable String expectedResultFileName, @Nullable Closure adjustment = null) { doTest(srcFileName, expectedResultFileName, 'java', adjustment) } - private void doTest(@NotNull String srcFileName, @Nullable String expectedResultFileName, @Nullable String extension, @Nullable Closure adjustment = null) { diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/AbstractRuleBuilder.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/AbstractRuleBuilder.groovy index 2b3452f0fe91..a9051a28862f 100644 --- a/plugins/rearranger/test/src/com/wrq/rearranger/util/AbstractRuleBuilder.groovy +++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/AbstractRuleBuilder.groovy @@ -18,6 +18,7 @@ import org.junit.Assert public abstract class AbstractRuleBuilder extends BuilderSupport { @NotNull def RearrangerSettings settings + private int depth /** * Holds rule customization handlers in the form {@code 'property id -> closure'} where 'property id' @@ -30,25 +31,33 @@ public abstract class AbstractRuleBuilder extends BuilderSupport { { key -> Assert.fail("No handler for the rule attribute '${key}'") } } + @Override + protected Object getCurrent() { + if (!super.current) { + current = createRule() + } + super.current + } + @Override protected void nodeCompleted(Object parent, Object node) { - if (!parent && node) { + if (--depth <= 0) { + // Top level call on the build object has been reached. registerRule(settings, node as T) + current = null } } @Override protected void setParent(Object parent, Object child) { + depth++ } @Override protected Object createNode(Object name) { - if (name == 'create') { - return createRule() - } createNode(name, [:], []) } - + @Override protected Object createNode(Object name, Object value) { createNode(name, [:], value) @@ -61,6 +70,9 @@ public abstract class AbstractRuleBuilder extends BuilderSupport { @Override protected Object createNode(Object name, Map attributes, Object value) { + if (!myHandlers.containsKey(name)) { + return current + } if (value) { for (i in [value].flatten()) { myHandlers[name](i, attributes, current) @@ -70,7 +82,7 @@ public abstract class AbstractRuleBuilder extends BuilderSupport { myHandlers[name](null, attributes, current) } - getCurrent() + current } @Nullable @@ -83,7 +95,7 @@ public abstract class AbstractRuleBuilder extends BuilderSupport { *

* Example: *

-   *   register('modifier', PsiModifier.FINAL, { rule, value, attributes ->
+   *   register('modifier', PsiModifier.FINAL, { value, attributes, rule ->
    *       rule.finalAttribute.value = value
    *       if (attributes.invert) rule.finalAttribute.invert = true
    *   })
@@ -143,10 +155,4 @@ public abstract class AbstractRuleBuilder extends BuilderSupport {
       rule."$propertyName".expression = value
     }
   }
-  
-  protected static void setIf(@NotNull RearrangerTestDsl dslProperty, map, rulePropertyName, rule) {
-    if (map.containsKey(dslProperty.value)) {
-      rule."$rulePropertyName" = map[dslProperty.value]
-    }
-  }
 }
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/CommentRuleBuilder.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/CommentRuleBuilder.groovy
index 80f06617fc57..0c9b4a4ac17b 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/CommentRuleBuilder.groovy
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/CommentRuleBuilder.groovy
@@ -13,11 +13,18 @@ class CommentRuleBuilder extends AbstractRuleBuilder {
   {
     registerHandler(RearrangerTestDsl.COMMENT, { data, attributes, rule ->
       rule.commentText = data
-      setIf(RearrangerTestDsl.CONDITION, attributes, 'emitCondition', rule)
-      setIf(RearrangerTestDsl.ALL_SUBSEQUENT, attributes, 'allSubsequentRules', rule)
-      setIf(RearrangerTestDsl.ALL_PRECEDING, attributes, 'allPrecedingRules', rule)
-      setIf(RearrangerTestDsl.SUBSEQUENT_RULES_TO_MATCH, attributes, 'NSubsequentRulesToMatch', rule)
-      setIf(RearrangerTestDsl.PRECEDING_RULES_TO_MATCH, attributes, 'NPrecedingRulesToMatch', rule)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.CONDITION,                          attributes, 'emitCondition', rule)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.ALL_SUBSEQUENT,                     attributes, 'allSubsequentRules', rule)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.ALL_PRECEDING,                      attributes, 'allPrecedingRules', rule)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.SUBSEQUENT_RULES_TO_MATCH,          attributes, 'NSubsequentRulesToMatch', rule)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.PRECEDING_RULES_TO_MATCH,           attributes, 'NPrecedingRulesToMatch', rule)
+      
+      def fillString = rule.commentFillString
+      RearrangerTestUtil.setIf(RearrangerTestDsl.USE_PROJECT_WIDTH_FOR_COMMENT_FILL, attributes, 'useProjectWidthForFill', fillString)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.FILL_WIDTH,                         attributes, 'fillWidth', fillString)
+      if (attributes[RearrangerTestDsl.FILL_STRING.value]) {
+        rule.commentFillString.fillString = attributes[RearrangerTestDsl.FILL_STRING.value]
+      }
     })
   }
   
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/RearrangerTestDsl.java b/plugins/rearranger/test/src/com/wrq/rearranger/util/RearrangerTestDsl.java
index c6a46cbeb636..cf1562dfffe9 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/RearrangerTestDsl.java
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/RearrangerTestDsl.java
@@ -9,7 +9,19 @@ import org.jetbrains.annotations.NotNull;
  * @since 5/17/12 12:57 PM
  */
 public enum RearrangerTestDsl {
+
+  // Settings
+  EXTRACTED_METHODS("extracted methods"),
+  OVERLOADED_METHODS("overloaded methods"),
+  DEPTH_FIRST_ORDER("depth-first order"),
+  ORDER,
+  COMMENT_TYPE("commentType"),
+  KEEP_TOGETHER("keep together"),
+  OVERLOADED,
+  GETTERS_SETTERS("getters and setters"),
+  GETTERS_SETTERS_WITH_PROPERTY("getters and setters with property"),
   
+  // Rules
   NAME,
   MODIFIER,
   /** Field initializer type. */
@@ -17,23 +29,42 @@ public enum RearrangerTestDsl {
   /** Method target type (e.g. constructor). */
   TARGET,
   TYPE,
-  RETURN_TYPE("returnType"),
-  SORT,
+  RETURN_TYPE("return type"),
+  SORT("sort by"),
+  NOT_SORT("not sort by"),
   COMMENT,
-  GETTER_CRITERIA("getterCriteria"),
-  SETTER_CRITERIA("setterCriteria"),
+  GETTER_CRITERIA("getter criteria"),
+  SETTER_CRITERIA("setter criteria"),
   SPACING,
+  PRECEDING_COMMENT("preceding comment"),
+  TRAILING_COMMENT("trailing comment"),
+  SETUP,
+  GROUP_EXTRACTED_METHODS("group extracted methods"),
+  ALPHABETIZE,
+  PRIORITY,
   
   // Attributes
   INVERT,
   CONDITION,
-  ALL_SUBSEQUENT("allSubsequent"),
-  ALL_PRECEDING("allPreceding"),
-  SUBSEQUENT_RULES_TO_MATCH("subsequentRulesToMatch"),
-  PRECEDING_RULES_TO_MATCH("precedingRulesToMatch"),
+  ALL_SUBSEQUENT("all subsequent"),
+  ALL_PRECEDING("all preceding"),
+  SUBSEQUENT_RULES_TO_MATCH("subsequent rules to match"),
+  PRECEDING_RULES_TO_MATCH("preceding rules to match"),
   BODY,
   ANCHOR,
-  BLANK_LINES("lines");
+  BLANK_LINES("lines"),
+  REMOVE_BLANK_LINES("remove blank lines"),
+  BELOW_FIRST_CALLER("below first caller"),
+  NON_PRIVATE_TREATMENT("non-private treatment"),
+  REARRANGE_INNER_CLASSES("rearrange inner classes"),
+  CLASS_COMMENT("class comment"),
+  ARGUMENTS_NUMBER("arguments number"),
+  FROM,
+  TO,
+  FILL_STRING("fill string"),
+  USE_PROJECT_WIDTH_FOR_COMMENT_FILL("use project width for fill"),
+  FILL_WIDTH("fill width"),
+  ENUM;
 
   @NotNull private final String myValue;
   
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/RearrangerTestUtil.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/RearrangerTestUtil.groovy
new file mode 100644
index 000000000000..64e0dc28f6e3
--- /dev/null
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/RearrangerTestUtil.groovy
@@ -0,0 +1,19 @@
+package com.wrq.rearranger.util
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Denis Zhdanov
+ * @since 5/22/12 11:11 AM
+ */
+public class RearrangerTestUtil {
+
+  private RearrangerTestUtil() {
+  }
+
+  public static void setIf(@NotNull RearrangerTestDsl dslProperty, map, rulePropertyName, rule) {
+    if (map.containsKey(dslProperty.value)) {
+      rule."$rulePropertyName" = map[dslProperty.value]
+    }
+  }
+}
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/SettingsConfigurationBuilder.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/SettingsConfigurationBuilder.groovy
new file mode 100644
index 000000000000..4a5bcdc5ecc6
--- /dev/null
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/SettingsConfigurationBuilder.groovy
@@ -0,0 +1,89 @@
+package com.wrq.rearranger.util
+
+import com.wrq.rearranger.settings.CommentRule
+import com.wrq.rearranger.settings.RearrangerSettings
+
+import static com.wrq.rearranger.util.RearrangerTestUtil.setIf
+
+/**
+ * @author Denis Zhdanov
+ * @since 5/22/12 11:07 AM
+ */
+class SettingsConfigurationBuilder extends BuilderSupport {
+  
+  def RearrangerSettings settings
+  
+  @Override
+  protected void setParent(Object parent, Object child) {
+  }
+
+  @Override
+  protected Object createNode(Object name) {
+    createNode(name, [:], [])
+  }
+
+  @Override
+  protected Object createNode(Object name, Object value) {
+    createNode(name, [:], value)
+  }
+
+  @Override
+  protected Object createNode(Object name, Map attributes) {
+    createNode(name, attributes, [])
+  }
+
+  @Override
+  protected Object createNode(Object name, Map attributes, Object value) {
+    def commentHandler = { RearrangerTestDsl dslName, propertyName ->
+      if (attributes.containsKey(dslName.value)) {
+        def comment = new CommentRule()
+        comment.commentText = attributes[dslName.value]
+        settings.extractedMethodsSettings."$propertyName" = comment
+      }
+    }
+    
+    switch (name) {
+      case RearrangerTestDsl.EXTRACTED_METHODS.value:
+        settings.extractedMethodsSettings.moveExtractedMethods = true
+        setIf(RearrangerTestDsl.DEPTH_FIRST_ORDER,     attributes, 'depthFirstOrdering',  settings.extractedMethodsSettings)
+        setIf(RearrangerTestDsl.ORDER,                 attributes, 'ordering',            settings.extractedMethodsSettings)
+        setIf(RearrangerTestDsl.COMMENT_TYPE,          attributes, 'commentType',         settings.extractedMethodsSettings)
+        setIf(RearrangerTestDsl.BELOW_FIRST_CALLER,    attributes, 'belowFirstCaller',    settings.extractedMethodsSettings)
+        setIf(RearrangerTestDsl.NON_PRIVATE_TREATMENT, attributes, 'nonPrivateTreatment', settings.extractedMethodsSettings)
+        
+        commentHandler(RearrangerTestDsl.PRECEDING_COMMENT, 'precedingComment')
+        commentHandler(RearrangerTestDsl.TRAILING_COMMENT,  'trailingComment')
+        break
+      case RearrangerTestDsl.KEEP_TOGETHER.value:
+        def m = [
+          (RearrangerTestDsl.OVERLOADED.value)                    : 'keepOverloadedMethodsTogether',
+          (RearrangerTestDsl.GETTERS_SETTERS.value)               : 'keepGettersSettersTogether',
+          (RearrangerTestDsl.GETTERS_SETTERS_WITH_PROPERTY.value) : 'keepGettersSettersWithProperty'
+        ]
+        for (i in [value].flatten()) {
+          settings."${m[i]}" = true
+        }
+        break
+      case RearrangerTestDsl.OVERLOADED_METHODS.value:
+        setIf(RearrangerTestDsl.ORDER,         attributes, 'overloadedOrder',               settings)
+        setIf(RearrangerTestDsl.KEEP_TOGETHER, attributes, 'keepOverloadedMethodsTogether', settings)
+        break
+      case RearrangerTestDsl.GETTER_CRITERIA.value:
+        setIf(RearrangerTestDsl.NAME, attributes, 'getterNameCriterion', settings.defaultGSDefinition)
+        setIf(RearrangerTestDsl.BODY, attributes, 'getterBodyCriterion', settings.defaultGSDefinition)
+        break
+      case RearrangerTestDsl.SETTER_CRITERIA.value:
+        setIf(RearrangerTestDsl.NAME, attributes, 'setterNameCriterion', settings.defaultGSDefinition)
+        setIf(RearrangerTestDsl.BODY, attributes, 'setterBodyCriterion', settings.defaultGSDefinition)
+        break
+      default:
+        setIf(RearrangerTestDsl.REARRANGE_INNER_CLASSES, attributes, 'rearrangeInnerClasses', settings)
+        if (attributes[RearrangerTestDsl.CLASS_COMMENT.value]) {
+          def comment = new CommentRule()
+          comment.commentText = attributes[RearrangerTestDsl.CLASS_COMMENT.value]
+          settings.classOrderAttributeList.add(0, comment)
+        }
+    }
+    settings
+  }
+}
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/AbstractJavaRuleBuilder.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/AbstractJavaRuleBuilder.groovy
index a7e53e599332..78c5c797cc2c 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/AbstractJavaRuleBuilder.groovy
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/AbstractJavaRuleBuilder.groovy
@@ -18,10 +18,19 @@ abstract class AbstractJavaRuleBuilder extends AbstractRuleBuilder {{
   })
   
   // Sort
-  def sortOptions = [ (SortType.BY_NAME) : "byName"]
+  def sortOptions = [
+    (SortOption.NAME)               : 'byName',
+    (SortOption.TYPE)               : 'byType',
+    (SortOption.TYPE_CASE_INSENSITIVE) : 'typeCaseInsensitive',
+    (SortOption.NAME_CASE_INSENSITIVE) : 'nameCaseInsensitive',
+    (SortOption.MODIFIER)              : 'byModifiers'
+  ]
   registerHandler(RearrangerTestDsl.SORT, { data, attributes, rule ->
     rule.sortOptions."${sortOptions[data]}" = true
   })
+  registerHandler(RearrangerTestDsl.NOT_SORT, { data, attributes, rule ->
+    rule.sortOptions."${sortOptions[data]}" = false
+  })
   
   // Modifiers
   //   Visibility
@@ -48,4 +57,9 @@ abstract class AbstractJavaRuleBuilder extends AbstractRuleBuilder {{
       genericHandlers[value](attributes, rule)
     }
   })
+  
+  // Priority.
+  registerHandler(RearrangerTestDsl.PRIORITY, { value, attributes, rule ->
+    rule.priority = value
+  })
 }}
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaInnerClassRuleBuilder.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaInnerClassRuleBuilder.groovy
index 22b3422a5eba..5d0515f1015c 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaInnerClassRuleBuilder.groovy
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaInnerClassRuleBuilder.groovy
@@ -2,13 +2,18 @@ package com.wrq.rearranger.util.java
 
 import com.wrq.rearranger.settings.attributeGroups.InnerClassAttributes
 import com.wrq.rearranger.settings.RearrangerSettings
+import com.wrq.rearranger.util.RearrangerTestDsl
 
 /** 
  * @author Denis Zhdanov
  * @since 5/18/12 8:51 AM
  */
 class JavaInnerClassRuleBuilder extends AbstractJavaRuleBuilder {
-
+  
+  {
+    registerHandler(RearrangerTestDsl.ENUM, createBooleanAttributeHandler('enumAttr'))
+  }
+  
   @Override
   protected InnerClassAttributes createRule() {
     new InnerClassAttributes()
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaInterfaceRuleBuilder.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaInterfaceRuleBuilder.groovy
new file mode 100644
index 000000000000..083138816896
--- /dev/null
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaInterfaceRuleBuilder.groovy
@@ -0,0 +1,45 @@
+package com.wrq.rearranger.util.java
+
+import com.wrq.rearranger.settings.attributeGroups.InterfaceAttributes
+import com.wrq.rearranger.settings.RearrangerSettings
+import com.wrq.rearranger.util.RearrangerTestDsl
+import com.wrq.rearranger.settings.CommentRule
+import com.wrq.rearranger.util.RearrangerTestUtil
+
+/** 
+ * @author Denis Zhdanov
+ * @since 5/22/12 11:56 AM
+ */
+class JavaInterfaceRuleBuilder extends AbstractJavaRuleBuilder {
+  
+  {
+    def commentHandler = { rule, commentText, propertyName ->
+      def comment = new CommentRule()
+      comment.commentText = commentText
+      rule."$propertyName" = comment
+    }
+    
+    def nameHandler = createStringAttributeHandler('nameAttr')
+    
+    registerHandler(RearrangerTestDsl.PRECEDING_COMMENT, { value, attributes, rule -> commentHandler(rule, value, 'precedingComment') })
+    registerHandler(RearrangerTestDsl.TRAILING_COMMENT, { value, attributes, rule -> commentHandler(rule, value, 'trailingComment') })
+    registerHandler(RearrangerTestDsl.SETUP, { value, attributes, rule -> 
+      RearrangerTestUtil.setIf(RearrangerTestDsl.GROUP_EXTRACTED_METHODS, attributes, 'noExtractedMethods', rule)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.ORDER, attributes, 'methodOrder', rule)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.ALPHABETIZE, attributes, 'alphabetizeInterfaces', rule)
+      if (attributes[RearrangerTestDsl.NAME.value]) {
+        nameHandler(attributes[RearrangerTestDsl.NAME.value], attributes, rule)
+      }
+    })
+  }
+  
+  @Override
+  protected InterfaceAttributes createRule() {
+    new InterfaceAttributes()
+  }
+
+  @Override
+  protected void registerRule(RearrangerSettings settings, InterfaceAttributes rule) {
+    settings.addItem(rule) 
+  }
+}
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaMethodRuleBuilder.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaMethodRuleBuilder.groovy
index c83323449342..215e912de1bf 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaMethodRuleBuilder.groovy
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaMethodRuleBuilder.groovy
@@ -4,6 +4,7 @@ import com.wrq.rearranger.settings.RearrangerSettings
 import com.wrq.rearranger.settings.attributeGroups.MethodAttributes
 import org.jetbrains.annotations.NotNull
 import com.wrq.rearranger.util.RearrangerTestDsl
+import com.wrq.rearranger.util.RearrangerTestUtil
 
 /** 
  * @author Denis Zhdanov
@@ -13,19 +14,37 @@ class JavaMethodRuleBuilder extends AbstractJavaRuleBuilder {
   
   {
     def handlers = [
-      (MethodType.CONSTRUCTOR) : createRawBooleanAttributeHandler('constructorMethodType'),
+      (MethodType.CONSTRUCTOR)      : createRawBooleanAttributeHandler('constructorMethodType'),
       (MethodType.GETTER_OR_SETTER) : createRawBooleanAttributeHandler('getterSetterMethodType'),
-      (MethodType.OTHER) : createRawBooleanAttributeHandler('otherMethodType')
+      (MethodType.OTHER)            : createRawBooleanAttributeHandler('otherMethodType')
     ]
     registerHandler(RearrangerTestDsl.TARGET, { data, attributes, rule -> handlers[data](attributes, rule) })
     registerHandler(RearrangerTestDsl.RETURN_TYPE, createStringAttributeHandler('returnTypeAttr'))
+    
+    // Getters & setters criteria.
     registerHandler(RearrangerTestDsl.GETTER_CRITERIA, { data, attributes, rule ->
-      setIf(RearrangerTestDsl.NAME, attributes, 'getterNameCriterion', rule.getterSetterDefinition)
-      setIf(RearrangerTestDsl.BODY, attributes, 'getterBodyCriterion', rule.getterSetterDefinition)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.NAME, attributes, 'getterNameCriterion', rule.getterSetterDefinition)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.BODY, attributes, 'getterBodyCriterion', rule.getterSetterDefinition)
     })
     registerHandler(RearrangerTestDsl.SETTER_CRITERIA, { data, attributes, rule ->
-      setIf(RearrangerTestDsl.NAME, attributes, 'setterNameCriterion', rule.getterSetterDefinition)
-      setIf(RearrangerTestDsl.BODY, attributes, 'setterBodyCriterion', rule.getterSetterDefinition)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.NAME, attributes, 'setterNameCriterion', rule.getterSetterDefinition)
+      RearrangerTestUtil.setIf(RearrangerTestDsl.BODY, attributes, 'setterBodyCriterion', rule.getterSetterDefinition)
+    })
+    
+    // Args number.
+    def argsNumber = [
+      (RearrangerTestDsl.FROM) : 'minParamsAttr',
+      (RearrangerTestDsl.TO)   : 'maxParamsAttr'
+    ]
+    def argsNumberHandler = { RearrangerTestDsl key, attributes, rule ->
+      if (attributes.containsKey(key.value)) {
+        rule."${argsNumber[key]}".match = true
+        rule."${argsNumber[key]}".value = attributes[key.value]
+      }
+    }
+    registerHandler(RearrangerTestDsl.ARGUMENTS_NUMBER, { data, attributes, rule ->
+      argsNumberHandler(RearrangerTestDsl.FROM, attributes, rule)
+      argsNumberHandler(RearrangerTestDsl.TO, attributes, rule)
     })
   }
   
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaSpacingRule.groovy b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaSpacingRule.groovy
index 559df6d97ae8..bcc99867d94a 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaSpacingRule.groovy
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/JavaSpacingRule.groovy
@@ -27,6 +27,9 @@ class JavaSpacingRule extends AbstractRuleBuilder {
         s.force = true
         s.nBlankLines = attributes[RearrangerTestDsl.BLANK_LINES.value]
       }
+      if (attributes[RearrangerTestDsl.REMOVE_BLANK_LINES.value]) {
+        settings.removeBlanksInsideCodeBlocks = true
+      }
     })
   }
   
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/MethodType.java b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/MethodType.java
index f31690cb7248..d02eb8148d04 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/MethodType.java
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/MethodType.java
@@ -5,5 +5,5 @@ package com.wrq.rearranger.util.java;
  * @since 5/17/12 11:05 AM
  */
 public enum MethodType {
-  CONSTRUCTOR, GETTER_OR_SETTER, OTHER
+  CONSTRUCTOR, GETTER_OR_SETTER, OVERLOADED, OTHER
 }
diff --git a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/SortType.java b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/SortOption.java
similarity index 51%
rename from plugins/rearranger/test/src/com/wrq/rearranger/util/java/SortType.java
rename to plugins/rearranger/test/src/com/wrq/rearranger/util/java/SortOption.java
index ab035a85809e..3d862599eec7 100644
--- a/plugins/rearranger/test/src/com/wrq/rearranger/util/java/SortType.java
+++ b/plugins/rearranger/test/src/com/wrq/rearranger/util/java/SortOption.java
@@ -4,6 +4,6 @@ package com.wrq.rearranger.util.java;
  * @author Denis Zhdanov
  * @since 5/17/12 3:57 PM
  */
-public enum SortType {
-  BY_NAME
+public enum SortOption {
+  NAME, TYPE, TYPE_CASE_INSENSITIVE, NAME_CASE_INSENSITIVE, MODIFIER
 }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/CommentSeparatorResult1.java b/plugins/rearranger/test/testData/com/wrq/rearranger/CommentSeparatorResult1.java
index 8f113e82c851..6f46868f0d96 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/CommentSeparatorResult1.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/CommentSeparatorResult1.java
@@ -1,6 +1,6 @@
 public class CommentSeparatorTest1 {
 
-  // Fields ==================================================================
+	// Fields ======================================================================
 
   public int i;
 }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/Enum1Result.java b/plugins/rearranger/test/testData/com/wrq/rearranger/Enum1Result.java
index 3d662839533a..9cceddc0f8ac 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/Enum1Result.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/Enum1Result.java
@@ -23,8 +23,9 @@ import java.util.List;
 public class Enum1Test implements Cloneable {
 // ------------------------------ FIELDS ------------------------------
 
-  private static final String    STEREOTYPE_PREFIX = "STEREOTYPE_";
-  private              Enum1Test parent            = null;
+  private static final String STEREOTYPE_PREFIX = "STEREOTYPE_";
+
+  private Enum1Test parent = null;
   private SuiteModel suiteModel;
   private SuiteItem  storage;
   private List childNodes = new ArrayList(10);
@@ -298,14 +299,16 @@ public class Enum1Test implements Cloneable {
     return this.getPassed() + " / " + this.getFailed() + " of " + this.getTotalInstructions();
   }
 
-  public int getTotalInstructions() {
+  public int getPassed() {
     int count = 0;
     if (getStereotype().equals(Stereotype.STEREOTYPE_INSTRUCTION)) {
-      count++;
+      if (getState().equals(ExecutionState.PASSED)) {
+        count++;
+      }
     }
-    for (Enum1Test t : childNodes) {
-      if (!getStereotype().equals(Stereotype.STEREOTYPE_INSTRUCTION)) {
-        count += t.getTotalInstructions();
+    else {
+      for (Enum1Test t : childNodes) {
+        count += t.getPassed();
       }
     }
     return count;
@@ -326,16 +329,14 @@ public class Enum1Test implements Cloneable {
     return count;
   }
 
-  public int getPassed() {
+  public int getTotalInstructions() {
     int count = 0;
     if (getStereotype().equals(Stereotype.STEREOTYPE_INSTRUCTION)) {
-      if (getState().equals(ExecutionState.PASSED)) {
-        count++;
-      }
+      count++;
     }
-    else {
-      for (Enum1Test t : childNodes) {
-        count += t.getPassed();
+    for (Enum1Test t : childNodes) {
+      if (!getStereotype().equals(Stereotype.STEREOTYPE_INSTRUCTION)) {
+        count += t.getTotalInstructions();
       }
     }
     return count;
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/GenericsResult1.java b/plugins/rearranger/test/testData/com/wrq/rearranger/GenericsResult1.java
index 16b18c44c73d..470d6b51783e 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/GenericsResult1.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/GenericsResult1.java
@@ -1,7 +1,8 @@
 public class TestGenerics {
-  //--------------------------------------------------------------------
-  //------------------------------------------ Protected/Package Methods
+   //--------------------------------------------------------------------
+   //------------------------------------------ Protected/Package Methods
 
+      
   static  T test() {
     return null;
   }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/InterfaceResult1.java b/plugins/rearranger/test/testData/com/wrq/rearranger/InterfaceResult1.java
index 0add5205bd14..2b8965c18dcd 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/InterfaceResult1.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/InterfaceResult1.java
@@ -1,5 +1,6 @@
 public interface TestInterface {
   int CONSTANT = 5;
+
   public int CONSTANT2 = 6;
 
   void testMethod();
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/OverloadedResult1.java b/plugins/rearranger/test/testData/com/wrq/rearranger/OverloadedResult1.java
index 64ec60be8083..16e45b32ef17 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/OverloadedResult1.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/OverloadedResult1.java
@@ -1,7 +1,8 @@
 public class TestOverloaded {
-  //--------------------------------------------------------------------
-  //------------------------------------------------------- Constructors
+   //--------------------------------------------------------------------
+   //------------------------------------------------------- Constructors
 
+      
   public TestOverloaded(String p_login) {
   }
 
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23BNNANXME.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23BNNANXME.java
index 4e7bf76cd622..3bf2004df185 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23BNNANXME.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23BNNANXME.java
@@ -1,6 +1,7 @@
 public class RearrangementTest23
   implements IFace2, IFace1
 {
+
   public int getY() {
     return 6;
   }
@@ -8,7 +9,6 @@ public class RearrangementTest23
   public int getX() {
     return getA() ? 5 : 3;
   }
-
   int method1() {
     return 4;
   }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNIANXME.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNIANXME.java
index 73e08795186f..ef00945287f0 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNIANXME.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNIANXME.java
@@ -1,7 +1,8 @@
 public class RearrangementTest23
   implements IFace2, IFace1
 {
-  /** * Interface IFace1 Header *** */
+/**** Interface IFace1 Header ****/
+
   public int getY() {
     return 6;
   }
@@ -10,7 +11,8 @@ public class RearrangementTest23
     return getA() ? 5 : 3;
   }
 /**** Interface IFace1 Trailer ***/
-  /** * Interface IFace2 Header *** */
+/**** Interface IFace2 Header ****/
+
   public boolean getB() {
     return false;
   }
@@ -18,8 +20,7 @@ public class RearrangementTest23
   public boolean getA() {
     return true;
   }
-
-  /** * Interface IFace2 Trailer ** */
+/**** Interface IFace2 Trailer ***/
   int method1() {
     return 4;
   }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMA.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMA.java
index 22a6c10e38e7..4f0b0b8ea0e1 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMA.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMA.java
@@ -1,7 +1,8 @@
 public class RearrangementTest23
   implements IFace2, IFace1
 {
-  /** * Interface IFace2 Header *** */
+/**** Interface IFace2 Header ****/
+
   public boolean getA() {
     return true;
   }
@@ -10,7 +11,8 @@ public class RearrangementTest23
     return false;
   }
 /**** Interface IFace2 Trailer ***/
-  /** * Interface IFace1 Header *** */
+/**** Interface IFace1 Header ****/
+
   public int getX() {
     return getA() ? 5 : 3;
   }
@@ -18,8 +20,7 @@ public class RearrangementTest23
   public int getY() {
     return 6;
   }
-
-  /** * Interface IFace1 Trailer ** */
+/**** Interface IFace1 Trailer ***/
   int method1() {
     return 4;
   }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXME.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXME.java
index f903e3e5cc05..7e52e4923324 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXME.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXME.java
@@ -1,7 +1,8 @@
 public class RearrangementTest23
   implements IFace2, IFace1
 {
-  /** * Interface IFace2 Header *** */
+/**** Interface IFace2 Header ****/
+
   public boolean getB() {
     return false;
   }
@@ -10,7 +11,8 @@ public class RearrangementTest23
     return true;
   }
 /**** Interface IFace2 Trailer ***/
-  /** * Interface IFace1 Header *** */
+/**** Interface IFace1 Header ****/
+
   public int getY() {
     return 6;
   }
@@ -18,8 +20,7 @@ public class RearrangementTest23
   public int getX() {
     return getA() ? 5 : 3;
   }
-
-  /** * Interface IFace1 Trailer ** */
+/**** Interface IFace1 Trailer ***/
   int method1() {
     return 4;
   }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMI.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMI.java
index 8088b74fa28a..1ab483ac4f6e 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMI.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult23NNNANXMI.java
@@ -1,7 +1,8 @@
 public class RearrangementTest23
   implements IFace2, IFace1
 {
-  /** * Interface IFace2 Header *** */
+/**** Interface IFace2 Header ****/
+
   public boolean getA() {
     return true;
   }
@@ -10,7 +11,8 @@ public class RearrangementTest23
     return false;
   }
 /**** Interface IFace2 Trailer ***/
-  /** * Interface IFace1 Header *** */
+/**** Interface IFace1 Header ****/
+
   public int getY() {
     return 6;
   }
@@ -18,8 +20,7 @@ public class RearrangementTest23
   public int getX() {
     return getA() ? 5 : 3;
   }
-
-  /** * Interface IFace1 Trailer ** */
+/**** Interface IFace1 Trailer ***/
   int method1() {
     return 4;
   }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult26.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult26.java
index fd22dd84a491..6145ad5a6868 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult26.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult26.java
@@ -7,7 +7,6 @@ class RearrangementTest26 {
   public void setValue(int i) {
     value = i;
   }
-
   int value;
 
   {
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult28.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult28.java
index f7382377292c..ef4bc4993913 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult28.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult28.java
@@ -1,37 +1,32 @@
 public class RearrangementTest28
   implements InterfaceName, InterfaceName2
 {
-  // start of fields
+// start of fields
   int i;
-
-  // end of fields
+// end of fields
 // start of interface InterfaceName
 // Level 1 methods
   public int getTime() {
     return getAnother();
   }
-
-  // Level 2 methods
+// Level 2 methods
   public int getAnother() {
     return 0;
   }
-
-  // end Level 2 methods
+// end Level 2 methods
 // end Level 1 methods
 // end of interface InterfaceName
 // start of interface InterfaceName2
   public int getDate() {
     return 0;
   }
-
-  // end of interface InterfaceName2
+// end of interface InterfaceName2
 // Level 1 methods
   public void m1() {
     m2();
     m3();
   }
-
-  // Level 2 methods
+// Level 2 methods
   public void m2() {
   }
 
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult41.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult41.java
index 899c73d58aea..ac91dac03562 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult41.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult41.java
@@ -1,5 +1,6 @@
 public class RearrangementTest41 {
-  public final void setPrice(final double price) {
+  public final void setPrice(final double price)
+  {
     this.price = price;
   }
 }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult43.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult43.java
index 3c9995a3c124..049fbd8b5b6b 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult43.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult43.java
@@ -1,4 +1,5 @@
 public class RearrangementTest43 {
+
   void method2(int a, int b) {
   }
 
@@ -7,7 +8,6 @@ public class RearrangementTest43 {
 
   void method1(int a) {
   }
-
   void method0() {
   }
 }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult44.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult44.java
index 8a24d11d1a0d..ef7dac09dd16 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult44.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult44.java
@@ -1,6 +1,6 @@
 /** test generated comment with fill. */
 public class RearrangementTest44 {
-  // -+-+-+-+- METHODS -+-+-+-+-
+// -+-+-+-+- METHODS -+-+-+-+-
   private void method(int i) {
   }
 }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46D.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46D.java
index 3cb5853fa8b2..facc29fd1544 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46D.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46D.java
@@ -6,10 +6,10 @@ public class RearrangementTest46 {
   protected       boolean isInvalid;
   protected final int     sqlType;
   protected List validator = new Vector();
-  protected       Object value;
-  protected final String dbColumnName;
-  protected final String table;
-  protected       String invalidText;
+  protected       Object  value;
+  protected final String  dbColumnName;
+  protected final String  table;
+  protected       String  invalidText;
 
   RearrangementTest46() {
     dbColumnName = "column";
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46E.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46E.java
index 4a1b25780ae1..6f0aebbb0ea6 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46E.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult46E.java
@@ -8,8 +8,8 @@ public class RearrangementTest46 {
   protected       boolean isInvalid;
   protected       boolean isMandatory;
   protected List validator = new Vector();
-  protected Object value;
-  protected String invalidText;
+  protected       Object  value;
+  protected       String  invalidText;
 
   RearrangementTest46() {
     dbColumnName = "column";
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult47.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult47.java
index b7e52ca2b1b8..f14640cb89df 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult47.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementResult47.java
@@ -3,7 +3,7 @@ public class RearrangementTest47 {
   public final static int CONSTANT2 = 2;
 
   enum suits {CLUBS, DIAMONDS, HEARTS, SPADES}
-
   int var2 = 2;
+
   int var3 = 3;
 }
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest32.java b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest32.java
index 58d1b54e6d63..b89ab41d9237 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest32.java
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest32.java
@@ -1,5 +1,7 @@
 public class Temp {
-  // ------------------------------ FIELDS ------------------------------
+
+// ------------------------------ FIELDS ------------------------------
+
   int field1;
 
 // -------------------------- OTHER METHODS --------------------------
diff --git a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest38cfg.xml b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest38cfg.xml
index d900d4239981..96f82645dfe9 100644
--- a/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest38cfg.xml
+++ b/plugins/rearranger/test/testData/com/wrq/rearranger/RearrangementTest38cfg.xml
@@ -179,9 +179,7 @@
               noExtractedMethods="false"/>
         
       
-      \n\
-        \ //////////////////////////////////////////////\n\ \ //\ Instance\ Methods\n\ \ //////////////////////////////////////////////
-      
+      \n  //////////////////////////////////////////////\n  // Instance Methods\n  //////////////////////////////////////////////
       
         
         
diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
index 08ec882113d4..b66cb41a1fe0 100644
--- a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
+++ b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic
@@ -132,6 +132,7 @@ hardlinks
 helvetica
 holdability
 hostname
+hprof
 href
 hsqldb
 html
@@ -156,6 +157,7 @@ iphoneos
 isnull
 javabean
 javabeans
+javac
 javadoc
 javaee
 javascript
@@ -378,12 +380,14 @@ stateful
 stdarg
 stdlib
 stmt
+strictfp
 stylesheet
 stylesheets
 sublicense
 subpackage
 subpartition
 subpartitions
+subst
 substring
 subtree
 subtrees
diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.form b/plugins/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.form
index 987deb37434d..08fb9aed8c9e 100644
--- a/plugins/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.form
+++ b/plugins/spellchecker/src/com/intellij/spellchecker/settings/SpellCheckerSettingsPane.form
@@ -80,7 +80,7 @@
                     
                     
                     
-                      
+                      
                     
                     
                     
@@ -112,7 +112,7 @@
                     
                     
                     
-                      
+                      
                     
                     
                     
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
index 05cad23251a0..943f436a17cd 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
@@ -27,7 +27,7 @@
         
         
         
-          
+          
         
         
           
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
index 8198915d6eff..81ad5ef1d57a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java
@@ -111,6 +111,7 @@ public class SvnConfiguration implements PersistentStateComponent {
   public boolean IGNORE_SPACES_IN_ANNOTATE = true;
   public boolean SHOW_MERGE_SOURCES_IN_ANNOTATE = true;
   public boolean FORCE_UPDATE = false;
+  public boolean IGNORE_EXTERNALS = false;
   public Boolean TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE;
 
   public UseAcceleration myUseAcceleration = UseAcceleration.nothing;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
index 0b3296955b6b..ae68233c985a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
@@ -44,6 +44,7 @@ public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
   private static final String ourAuthenticationRealm = "Authentication realm:";
   private final Project myProject;
   private final VirtualFile myCommonAncestor;
+  private boolean myIgnoreExternals;
 
   public SvnCommandLineUpdateClient(final Project project, VirtualFile commonAncestor) {
     super(SvnVcs.getInstance(project).createUpdateClient());
@@ -102,6 +103,9 @@ public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
         if (makeParents) {
           command.addParameters("--parents");
         }
+        if (myIgnoreExternals) {
+          command.addParameters("--ignore-externals");
+        }
         command.addParameters("--accept", "postpone");
         command.addParameters("--config-dir", configDir.getPath());
 
@@ -268,4 +272,9 @@ public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
     // todo MAIN
     //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry);
   }
+
+  @Override
+  public void setIgnoreExternals(boolean ignoreExternals) {
+    myIgnoreExternals = ignoreExternals;
+  }
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanel.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanel.form
index 04f86d5da634..2809a2fa68b2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanel.form
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanel.form
@@ -15,7 +15,7 @@
         
         
         
-          
+          
         
         
         
@@ -176,7 +176,7 @@
         
         
         
-          
+          
         
         
         
@@ -250,7 +250,7 @@
         
         
         
-          
+          
         
         
         
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java
index c3a6dbf9e67d..d69a47b2ec70 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnSvnkitUpdateClient.java
@@ -200,6 +200,11 @@ public class SvnSvnkitUpdateClient implements SvnUpdateClientI {
     myClient.setEventHandler(dispatcher);
   }
 
+  @Override
+  public void setIgnoreExternals(boolean ignoreExternals) {
+    myClient.setIgnoreExternals(ignoreExternals);
+  }
+
   public ISVNEventHandler getEventHandler() {
     return myDispatcher;
   }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java
index 3568ce8a33e8..f587581f2c31 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/SvnUpdateClientI.java
@@ -72,4 +72,5 @@ public interface SvnUpdateClientI {
 
   void setExportExpandsKeywords(boolean expand);
   void setEventHandler(ISVNEventHandler dispatcher);
+  void setIgnoreExternals(boolean ignoreExternals);
 }
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
index 41062ac038d2..b2137fe3eaa5 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
@@ -85,7 +85,6 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
       final SVNURL sourceUrl = getSourceUrl(myVcs, root);
       final boolean isSwitch = rootInfo != null && rootInfo.getUrl() != null && ! rootInfo.getUrl().equals(sourceUrl);
       final SVNRevision updateTo = rootInfo != null && rootInfo.isUpdateToRevision() ? rootInfo.getRevision() : SVNRevision.HEAD;
-
       if (isSwitch) {
         final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, true, sourceUrl);
         rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, rootInfo.getRevision(), configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
@@ -108,6 +107,9 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
       } else {
         updateClient = new SvnSvnkitUpdateClient(myVcs.createUpdateClient());
       }
+      if (! isSwitch) {
+        updateClient.setIgnoreExternals(configuration.IGNORE_EXTERNALS);
+      }
       updateClient.setEventHandler(myHandler);
       updateClient.setUpdateLocksOnDemand(configuration.UPDATE_LOCK_ON_DEMAND);
       return updateClient;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form
index c5d82eaf815b..9dba2ba4a112 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.form
@@ -14,7 +14,7 @@
           
         
         
-          
+          
             
             
             
@@ -22,7 +22,7 @@
             
               
                 
-                  
+                  
                 
               
               
@@ -57,6 +57,14 @@
                   
                 
               
+              
+                
+                  
+                
+                
+                  
+                
+              
             
           
           
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.java
index 9080272ba078..ab66664f0f82 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdatePanel.java
@@ -34,6 +34,7 @@ public class SvnUpdatePanel extends AbstractSvnUpdatePanel {
   private DepthCombo myDepthCombo;
   private JLabel myDepthLabel;
   private JPanel myAdditionalPanel;
+  private JCheckBox myIgnoreExternalsCheckBox;
 
   public SvnUpdatePanel(SvnVcs vcs, Collection roots) {
     super(vcs);
@@ -58,12 +59,19 @@ public class SvnUpdatePanel extends AbstractSvnUpdatePanel {
       }
     });
     myForceBox.setSelected(svnConfiguration.FORCE_UPDATE);
+    myIgnoreExternalsCheckBox.setSelected(svnConfiguration.IGNORE_EXTERNALS);
     myForceBox.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent e) {
         svnConfiguration.FORCE_UPDATE = myForceBox.isSelected();
       }
     });
+    myIgnoreExternalsCheckBox.addActionListener(new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        svnConfiguration.IGNORE_EXTERNALS = myIgnoreExternalsCheckBox.isSelected();
+      }
+    });
   }
 
   protected JPanel getRootsPanel() {
diff --git a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanelOld.form b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanelOld.form
index 3b12c98f9b5e..d7685d5a0ea9 100644
--- a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanelOld.form
+++ b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/config/ConfigureProxiesOptionsPanelOld.form
@@ -17,7 +17,7 @@
         
         
         
-          
+          
         
         
         
@@ -179,7 +179,7 @@
         
         
         
-          
+          
         
         
         
@@ -264,7 +264,7 @@
         
         
         
-          
+          
         
         
         
diff --git a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml
index 54e20de62ffb..d73517d191ee 100644
--- a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml
+++ b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml
@@ -14,21 +14,7 @@
     
   
 
-  
-    
-      
-
-      
-
-      
-              
-              
-
-      
-    
-  
-
+  
+     
+  
 
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java
index a030df6bc597..926e87fb7dc5 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/DesignerToolWindowManager.java
@@ -19,7 +19,6 @@ import com.intellij.designer.componentTree.ComponentTree;
 import com.intellij.designer.componentTree.ComponentTreeBuilder;
 import com.intellij.designer.componentTree.TreeEditableArea;
 import com.intellij.designer.designSurface.DesignerEditorPanel;
-import com.intellij.designer.propertyTable.PropertyTable;
 import com.intellij.designer.propertyTable.PropertyTablePanel;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -156,10 +155,6 @@ public final class DesignerToolWindowManager implements ProjectComponent {
     return editors.length > 0 ? getDesigner(editors[0]) : null;
   }
 
-  public PropertyTable getPropertyTable() {
-    return myPropertyTablePanel.getPropertyTable();
-  }
-
   private void bindToDesigner(final DesignerEditorPanel designer) {
     myWindowQueue.cancelAllUpdates();
     myWindowQueue.queue(new Update("update") {
@@ -177,14 +172,12 @@ public final class DesignerToolWindowManager implements ProjectComponent {
         clearTreeBuilder();
         myComponentTree.newModel();
         if (designer == null) {
-          myComponentTree.setDecorator(null);
-          myComponentTree.setActionPanel(null);
+          myComponentTree.setDesignerPanel(null);
           myPropertyTablePanel.getPropertyTable().setArea(null, null);
           myToolWindow.setAvailable(false, null);
         }
         else {
-          myComponentTree.setDecorator(designer.getTreeDecorator());
-          myComponentTree.setActionPanel(designer.getActionPanel());
+          myComponentTree.setDesignerPanel(designer);
           myTreeBuilder = new ComponentTreeBuilder(myComponentTree, designer);
           myPropertyTablePanel.getPropertyTable().setArea(designer, myTreeBuilder.getTreeArea());
           myToolWindow.setAvailable(true, null);
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java
index bde7dfb0d5c2..7a6bf5ae69da 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/CommonEditActionsProvider.java
@@ -65,7 +65,9 @@ public class CommonEditActionsProvider implements DeleteProvider, CopyProvider,
 
   @Override
   public boolean canDeleteElement(@NotNull DataContext dataContext) {
-    // TODO: InplaceEditing
+    if (myDesigner.getInplaceEditingLayer().isEditing()) {
+      return false;
+    }
     List selection = getArea().getSelection();
     if (selection.isEmpty()) {
       return false;
@@ -143,8 +145,7 @@ public class CommonEditActionsProvider implements DeleteProvider, CopyProvider,
 
   @Override
   public boolean isCopyEnabled(@NotNull DataContext dataContext) {
-    // TODO: InplaceEditing
-    return !getArea().getSelection().isEmpty();
+    return !myDesigner.getInplaceEditingLayer().isEditing() && !getArea().getSelection().isEmpty();
   }
 
   @Override
@@ -185,8 +186,7 @@ public class CommonEditActionsProvider implements DeleteProvider, CopyProvider,
 
   @Override
   public boolean isPasteEnabled(@NotNull DataContext dataContext) {
-    // TODO: InplaceEditing
-    return getSerializedComponentData() != null;
+    return !myDesigner.getInplaceEditingLayer().isEditing() && getSerializedComponentData() != null;
   }
 
   @Nullable
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java
index 200f2ec2c714..6397254c02ed 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java
@@ -48,6 +48,8 @@ public class DesignerActionPanel implements DataProvider {
     myCommonEditActionsProvider = new CommonEditActionsProvider(designer);
     myShortcuts = shortcuts;
 
+    createInplaceEditingAction(myShortcuts).setDesignerPanel(designer);
+
     myActionGroup.add(myStaticGroup);
     myActionGroup.add(myDynamicGroup);
 
@@ -74,11 +76,11 @@ public class DesignerActionPanel implements DataProvider {
     SelectAllAction selectAllAction = new SelectAllAction(designer.getSurfaceArea());
     registerAction(selectAllAction, "$SelectAll");
 
-    myPopupGroup.add(actionManager.getAction("$Cut"));
-    myPopupGroup.add(actionManager.getAction("$Copy"));
-    myPopupGroup.add(actionManager.getAction("$Paste"));
+    myPopupGroup.add(actionManager.getAction(IdeActions.ACTION_CUT));
+    myPopupGroup.add(actionManager.getAction(IdeActions.ACTION_COPY));
+    myPopupGroup.add(actionManager.getAction(IdeActions.ACTION_PASTE));
     myPopupGroup.addSeparator();
-    myPopupGroup.add(actionManager.getAction("$Delete"));
+    myPopupGroup.add(actionManager.getAction(IdeActions.ACTION_DELETE));
     myPopupGroup.addSeparator();
     myPopupGroup.add(selectParent);
     myPopupGroup.add(selectAllAction);
@@ -91,6 +93,12 @@ public class DesignerActionPanel implements DataProvider {
     });
   }
 
+  public static StartInplaceEditing createInplaceEditingAction(JComponent shortcuts) {
+    StartInplaceEditing action = new StartInplaceEditing();
+    action.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), shortcuts);
+    return action;
+  }
+
   private void registerAction(AnAction action, @NonNls String actionId) {
     action.registerCustomShortcutSet(
       ActionManager.getInstance().getAction(actionId).getShortcutSet(),
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/StartInplaceEditing.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/StartInplaceEditing.java
new file mode 100644
index 000000000000..a450a651c58e
--- /dev/null
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/StartInplaceEditing.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.designer.actions;
+
+import com.intellij.designer.designSurface.DesignerEditorPanel;
+import com.intellij.designer.model.RadComponent;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Alexander Lobas
+ */
+public class StartInplaceEditing extends AnAction {
+  private DesignerEditorPanel myDesigner;
+
+  public void setDesignerPanel(@Nullable DesignerEditorPanel designer) {
+    myDesigner = designer;
+  }
+
+  @Override
+  public void update(AnActionEvent event) {
+    boolean enabled = false;
+
+    if (myDesigner != null) {
+      List selection = myDesigner.getSurfaceArea().getSelection();
+      if (selection.size() == 1) {
+        try {
+          enabled = !selection.get(0).getInplaceProperties().isEmpty();
+        }
+        catch (Exception e) {
+        }
+      }
+    }
+
+    event.getPresentation().setEnabled(enabled);
+  }
+
+  @Override
+  public void actionPerformed(AnActionEvent e) {
+    myDesigner.getInplaceEditingLayer().startEditing(null);
+  }
+}
\ No newline at end of file
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/componentTree/ComponentTree.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/componentTree/ComponentTree.java
index 80b8c7b3eb6b..e39eb730ca18 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/componentTree/ComponentTree.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/componentTree/ComponentTree.java
@@ -16,6 +16,8 @@
 package com.intellij.designer.componentTree;
 
 import com.intellij.designer.actions.DesignerActionPanel;
+import com.intellij.designer.actions.StartInplaceEditing;
+import com.intellij.designer.designSurface.DesignerEditorPanel;
 import com.intellij.designer.designSurface.FeedbackTreeLayer;
 import com.intellij.designer.model.RadComponent;
 import com.intellij.openapi.actionSystem.DataProvider;
@@ -35,6 +37,7 @@ import java.awt.*;
  * @author Alexander Lobas
  */
 public final class ComponentTree extends Tree implements DataProvider {
+  private final StartInplaceEditing myInplaceEditingAction;
   private TreeComponentDecorator myDecorator;
   private DesignerActionPanel myActionPanel;
   private RadComponent myMarkComponent;
@@ -55,20 +58,24 @@ public final class ComponentTree extends Tree implements DataProvider {
     // Install convenient keyboard navigation
     TreeUtil.installActions(this);
 
-    // TODO: F2 should start inplace editing
+    myInplaceEditingAction = DesignerActionPanel.createInplaceEditingAction(this);
   }
 
   public void newModel() {
     setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
   }
 
-  public void setDecorator(@Nullable TreeComponentDecorator decorator) {
-    myDecorator = decorator;
+  public void setDesignerPanel(@Nullable DesignerEditorPanel designer) {
+    if (designer == null) {
+      myDecorator = null;
+      myActionPanel = null;
+    }
+    else {
+      myDecorator = designer.getTreeDecorator();
+      myActionPanel = designer.getActionPanel();
+    }
     myMarkComponent = null;
-  }
-
-  public void setActionPanel(@Nullable DesignerActionPanel actionPanel) {
-    myActionPanel = actionPanel;
+    myInplaceEditingAction.setDesignerPanel(designer);
   }
 
   public void mark(RadComponent component, int feedback) {
@@ -79,12 +86,7 @@ public final class ComponentTree extends Tree implements DataProvider {
 
   @Override
   public Object getData(@NonNls String dataId) {
-    // TODO: support keys
-
-    if (myActionPanel != null) {
-      return myActionPanel.getData(dataId);
-    }
-    return null;
+    return myActionPanel == null ? null : myActionPanel.getData(dataId);
   }
 
   @Nullable
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/CaptionPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/CaptionPanel.java
index a9b3e8dda142..19af11b3eb39 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/CaptionPanel.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/CaptionPanel.java
@@ -129,7 +129,7 @@ public class CaptionPanel extends JLayeredPane implements DataProvider, DeletePr
       public ActionGroup getPopupActions() {
         if (myActionGroup == null) {
           myActionGroup = new DefaultActionGroup();
-          myActionGroup.add(ActionManager.getInstance().getAction("$Delete"));
+          myActionGroup.add(ActionManager.getInstance().getAction(IdeActions.ACTION_DELETE));
         }
         return myActionGroup;
       }
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java
index f46df3e4126b..2ee177594ddf 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java
@@ -24,6 +24,7 @@ import com.intellij.designer.designSurface.tools.*;
 import com.intellij.designer.model.FindComponentVisitor;
 import com.intellij.designer.model.RadComponent;
 import com.intellij.designer.palette.Item;
+import com.intellij.designer.propertyTable.InplaceContext;
 import com.intellij.designer.propertyTable.Property;
 import com.intellij.diagnostic.LogMessageEx;
 import com.intellij.diagnostic.errordialog.Attachment;
@@ -97,6 +98,7 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
   protected GlassLayer myGlassLayer;
   private DecorationLayer myDecorationLayer;
   private FeedbackLayer myFeedbackLayer;
+  private InplaceEditingLayer myInplaceEditingLayer;
 
   private ListSelectionListener myPaletteListener;
   protected ToolProvider myToolProvider;
@@ -244,6 +246,11 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
         }, command, null);
       }
 
+      @Override
+      public void startInplaceEditing(@Nullable InplaceContext inplaceContext) {
+        myInplaceEditingLayer.startEditing(inplaceContext);
+      }
+
       @Override
       public void showError(@NonNls String message, Throwable e) {
         DesignerEditorPanel.this.showError(message, e);
@@ -259,6 +266,9 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
     myFeedbackLayer = new FeedbackLayer();
     myLayeredPane.add(myFeedbackLayer, LAYER_FEEDBACK);
 
+    myInplaceEditingLayer = new InplaceEditingLayer(this);
+    myLayeredPane.add(myInplaceEditingLayer, LAYER_INPLACE_EDITING);
+
     JPanel content = new JPanel(new GridBagLayout());
 
     GridBagConstraints gbc = new GridBagConstraints();
@@ -513,6 +523,10 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
     return myActionPanel;
   }
 
+  public InplaceEditingLayer getInplaceEditingLayer() {
+    return myInplaceEditingLayer;
+  }
+
   public JComponent getPreferredFocusedComponent() {
     return myDesignerCard.isVisible() ? myGlassLayer : myErrorPanel;
   }
@@ -681,7 +695,6 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider
 
   @Override
   public Object getData(@NonNls String dataId) {
-    // TODO: support keys
     return myActionPanel.getData(dataId);
   }
 
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/InplaceEditingLayer.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/InplaceEditingLayer.java
new file mode 100644
index 000000000000..560619fce313
--- /dev/null
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/InplaceEditingLayer.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.designer.designSurface;
+
+import com.intellij.designer.designSurface.feedbacks.LineMarginBorder;
+import com.intellij.designer.model.RadComponent;
+import com.intellij.designer.propertyTable.InplaceContext;
+import com.intellij.designer.propertyTable.Property;
+import com.intellij.designer.propertyTable.PropertyEditor;
+import com.intellij.designer.propertyTable.PropertyEditorListener;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.wm.FocusWatcher;
+import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
+import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt;
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Alexander Lobas
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public class InplaceEditingLayer extends JComponent {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.designer.designSurface.InplaceEditingLayer");
+
+  private final FocusWatcher myFocusWatcher = new FocusWatcher() {
+    protected void focusLostImpl(FocusEvent e) {
+      Component opposite = e.getOppositeComponent();
+      if (e.isTemporary() || opposite != null && SwingUtilities.isDescendingFrom(opposite, getTopComponent())) {
+        // Do nothing if focus moves inside top component hierarchy
+        return;
+      }
+      // [vova] we need LaterInvocator here to prevent write-access assertions
+      ApplicationManager.getApplication().invokeLater(new Runnable() {
+        public void run() {
+          finishEditing(true);
+        }
+      }, ModalityState.NON_MODAL);
+    }
+  };
+  private final ComponentSelectionListener mySelectionListener = new ComponentSelectionListener() {
+    @Override
+    public void selectionChanged(EditableArea area) {
+      finishEditing(true);
+    }
+  };
+  private PropertyEditorListener myEditorListener = new PropertyEditorListener() {
+    @Override
+    public void valueCommitted(PropertyEditor source, boolean continueEditing, boolean closeEditorOnError) {
+      finishEditing(true);
+    }
+
+    @Override
+    public void editingCanceled(PropertyEditor source) {
+      finishEditing(false);
+    }
+
+    @Override
+    public void preferredSizeChanged(PropertyEditor source) {
+      adjustInplaceComponentSize();
+    }
+  };
+  private List myEditors;
+
+  private final DesignerEditorPanel myDesigner;
+  private JComponent myInplaceComponent;
+  private int myPreferredWidth;
+
+  public InplaceEditingLayer(DesignerEditorPanel designer) {
+    myDesigner = designer;
+  }
+
+  public void startEditing(@Nullable InplaceContext inplaceContext) {
+    try {
+      List selection = myDesigner.getSurfaceArea().getSelection();
+      if (selection.size() != 1) {
+        return;
+      }
+
+      RadComponent radComponent = selection.get(0);
+      List inplaceProperties = radComponent.getInplaceProperties();
+      if (inplaceProperties.isEmpty()) {
+        return;
+      }
+
+      myInplaceComponent = new JPanel(new GridLayoutManager(inplaceProperties.size(), 2));
+      myInplaceComponent.setBorder(new LineMarginBorder(5, 5, 5, 5));
+      new AnAction() {
+        @Override
+        public void actionPerformed(AnActionEvent e) {
+          finishEditing(false);
+        }
+      }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), myInplaceComponent);
+
+      int row = 0;
+
+      myEditors = new ArrayList();
+
+      JComponent componentToFocus = null;
+      Font font = null;
+
+      if (inplaceContext == null) {
+        inplaceContext = new InplaceContext();
+      }
+
+      for (Property property : inplaceProperties) {
+        JLabel label = new JLabel(property.getName() + ":");
+        if (font == null) {
+          font = label.getFont().deriveFont(Font.BOLD);
+        }
+        label.setFont(font);
+
+        myInplaceComponent.add(label,
+                               new GridConstraints(row, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, 0, 0, null, null,
+                                                   null));
+
+        PropertyEditor editor = property.getEditor();
+        myEditors.add(editor);
+
+        JComponent component = editor.getComponent(radComponent.getRoot(), radComponent, property.getValue(radComponent), inplaceContext);
+
+        myInplaceComponent.add(component,
+                               new GridConstraints(row++, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, 0, 0,
+                                                   null, null, null));
+
+        if (componentToFocus == null) {
+          componentToFocus = editor.getPreferredFocusedComponent();
+        }
+      }
+
+      for (PropertyEditor editor : myEditors) {
+        editor.addPropertyEditorListener(myEditorListener);
+      }
+
+      Rectangle bounds = radComponent.getBounds(this);
+      Dimension size = myInplaceComponent.getPreferredSize();
+      myPreferredWidth = size.width;
+      myInplaceComponent.setBounds(bounds.x, bounds.y, size.width, size.height);
+      add(myInplaceComponent);
+
+      if (componentToFocus == null) {
+        componentToFocus = IdeFocusTraversalPolicy.getPreferredFocusedComponent(myInplaceComponent);
+      }
+      if (componentToFocus != null) {
+        componentToFocus.requestFocusInWindow();
+      }
+      else {
+        myInplaceComponent.requestFocusInWindow();
+      }
+
+      myDesigner.getSurfaceArea().addSelectionListener(mySelectionListener);
+      myFocusWatcher.install(myInplaceComponent);
+
+      enableEvents(AWTEvent.MOUSE_EVENT_MASK);
+      repaint();
+    }
+    catch (Throwable e) {
+      LOG.error(e);
+    }
+  }
+
+  private void finishEditing(boolean commit) {
+    myDesigner.getSurfaceArea().removeSelectionListener(mySelectionListener);
+
+    if (myInplaceComponent != null) {
+      if (commit) {
+        // TODO: Auto-generated method stub
+      }
+
+      for (PropertyEditor editor : myEditors) {
+        editor.removePropertyEditorListener(myEditorListener);
+      }
+
+      removeInplaceComponent();
+      myFocusWatcher.deinstall(myInplaceComponent);
+      myInplaceComponent = null;
+    }
+
+    myEditors = null;
+
+    myDesigner.getPreferredFocusedComponent().requestFocusInWindow();
+
+    disableEvents(AWTEvent.MOUSE_EVENT_MASK);
+    repaint();
+  }
+
+  private void adjustInplaceComponentSize() {
+    myInplaceComponent.revalidate();
+    Dimension size = myInplaceComponent.getPreferredSize();
+    int width = Math.max(size.width, myPreferredWidth);
+    width = Math.min(width, getWidth() - myInplaceComponent.getX());
+    myInplaceComponent.setSize(width, myInplaceComponent.getHeight());
+    myInplaceComponent.revalidate();
+    System.out.println("size: " + width);
+  }
+
+  private void removeInplaceComponent() {
+    // [vova] before removing component from Swing tree we have to
+    // request component into glass layer. Otherwise focus from component being removed
+    // can go to some RadComponent.
+
+    LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(myDesigner.getPreferredFocusedComponent());
+    try {
+      remove(myInplaceComponent);
+    }
+    finally {
+      LayoutFocusTraversalPolicyExt.setOverridenDefaultComponent(null);
+    }
+  }
+
+  /**
+   * When there is an inplace editor we "listen" all mouse event
+   * and finish editing by any MOUSE_PRESSED or MOUSE_RELEASED event.
+   * We are acting like yet another glass pane over the standard glass layer.
+   */
+  protected void processMouseEvent(MouseEvent e) {
+    if (myInplaceComponent != null && (MouseEvent.MOUSE_PRESSED == e.getID() || MouseEvent.MOUSE_RELEASED == e.getID())) {
+      finishEditing(true);
+    }
+    // [vova] this is very important! Without this code Swing doen't close popup menu on our
+    // layered pane. Swing adds MouseListeners to all component to close popup. If we do not
+    // invoke super then we lock all mouse listeners.
+    super.processMouseEvent(e);
+  }
+
+  public boolean isEditing() {
+    return myInplaceComponent != null;
+  }
+}
\ No newline at end of file
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java
index 466a829ac9a1..7efcfb6c1f7c 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/SelectionTool.java
@@ -17,10 +17,12 @@ package com.intellij.designer.designSurface.tools;
 
 import com.intellij.designer.designSurface.EditableArea;
 import com.intellij.designer.model.RadComponent;
+import com.intellij.designer.propertyTable.InplaceContext;
 import com.intellij.openapi.actionSystem.ActionManager;
 import com.intellij.openapi.actionSystem.ActionPopupMenu;
 import org.jetbrains.annotations.Nullable;
 
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import java.util.List;
@@ -85,6 +87,13 @@ public class SelectionTool extends InputTool {
     handleMove(); // hack: update cursor
   }
 
+  @Override
+  protected void handleDoubleClick(int button) {
+    if (button == MouseEvent.BUTTON1 && myToolProvider != null) {
+      myToolProvider.startInplaceEditing(null);
+    }
+  }
+
   @Override
   protected void handleMove() {
     if (myState == STATE_INIT) {
@@ -190,6 +199,11 @@ public class SelectionTool extends InputTool {
     if (myTracker != null) {
       myTracker.keyTyped(event, area);
     }
+    else if (myToolProvider != null &&
+             Character.isLetterOrDigit(event.getKeyChar()) &&
+             (event.getModifiers() & (InputEvent.ALT_MASK | InputEvent.CTRL_MASK)) == 0) {
+      myToolProvider.startInplaceEditing(new InplaceContext(event.getKeyChar()));
+    }
   }
 
   @Override
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java
index 4507942f5baf..a1827e4f8a74 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/tools/ToolProvider.java
@@ -17,6 +17,7 @@ package com.intellij.designer.designSurface.tools;
 
 import com.intellij.designer.designSurface.EditOperation;
 import com.intellij.designer.designSurface.EditableArea;
+import com.intellij.designer.propertyTable.InplaceContext;
 import com.intellij.util.ThrowableRunnable;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.Nullable;
@@ -133,4 +134,6 @@ public abstract class ToolProvider {
   public abstract boolean execute(ThrowableRunnable operation, String command, boolean updateProperties);
 
   public abstract void execute(List operations, String command);
+
+  public abstract void startInplaceEditing(@Nullable InplaceContext inplaceContext);
 }
\ No newline at end of file
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java
index 5f8316abf946..4337bcf8161e 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java
@@ -114,6 +114,11 @@ public abstract class MetaManager {
 
     Element properties = element.getChild("properties");
     if (properties != null) {
+      Attribute inplace = properties.getAttribute("inplace");
+      if (inplace != null) {
+        meta.setInplaceProperties(StringUtil.split(inplace.getValue(), " "));
+      }
+
       Attribute top = properties.getAttribute("top");
       if (top != null) {
         meta.setTopProperties(StringUtil.split(top.getValue(), " "));
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java
index b86e227fc498..ab019ead955c 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java
@@ -39,6 +39,7 @@ public class MetaModel {
   private Icon myIcon;
   private String myCreation;
   private boolean myDelete = true;
+  private List myInplaceProperties = Collections.emptyList();
   private List myTopProperties = Collections.emptyList();
   private List myNormalProperties = Collections.emptyList();
   private List myImportantProperties = Collections.emptyList();
@@ -116,6 +117,14 @@ public class MetaModel {
     myPaletteItem.setMetaModel(this);
   }
 
+  public List getInplaceProperties() {
+    return myInplaceProperties;
+  }
+
+  public void setInplaceProperties(List inplaceProperties) {
+    myInplaceProperties = inplaceProperties;
+  }
+
   public List getTopProperties() {
     return myTopProperties;
   }
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java
index 749bbb16d2b3..c43400d71452 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java
@@ -22,6 +22,7 @@ import com.intellij.designer.designSurface.StaticDecorator;
 import com.intellij.designer.designSurface.tools.DragTracker;
 import com.intellij.designer.designSurface.tools.InputTool;
 import com.intellij.designer.propertyTable.Property;
+import com.intellij.designer.propertyTable.PropertyTable;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
 import org.jdom.Element;
 import org.jetbrains.annotations.NotNull;
@@ -186,6 +187,22 @@ public abstract class RadComponent {
     return Collections.emptyList();
   }
 
+  public List getInplaceProperties() throws Exception {
+    List properties = new ArrayList();
+
+    if (myMetaModel != null) {
+      List allProperties = getProperties();
+      for (String name : myMetaModel.getInplaceProperties()) {
+        Property property = PropertyTable.findProperty(allProperties, name);
+        if (property != null) {
+          properties.add(property);
+        }
+      }
+    }
+
+    return properties;
+  }
+
   @SuppressWarnings("unchecked")
   public final  T getClientProperty(@NotNull String key) {
     return (T)myClientProperties.get(key);
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/InplaceContext.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/InplaceContext.java
new file mode 100644
index 000000000000..63cff0814927
--- /dev/null
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/InplaceContext.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.designer.propertyTable;
+
+/**
+ * @author Alexander Lobas
+ */
+public class InplaceContext {
+  private char myStartChar;
+
+  public InplaceContext() {
+    this((char)0);
+  }
+
+  public InplaceContext(char startChar) {
+    myStartChar = startChar;
+  }
+
+  public boolean isStartChar() {
+    return myStartChar != 0;
+  }
+
+  public String getText(String text) {
+    if (text == null) {
+      text = "";
+    }
+
+    text += myStartChar;
+    myStartChar = 0;
+    return text;
+  }
+}
\ No newline at end of file
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyEditor.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyEditor.java
index c0892ab4cff2..3ef33c0d9909 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyEditor.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyEditor.java
@@ -29,10 +29,13 @@ public abstract class PropertyEditor {
   private final EventListenerList myListenerList = new EventListenerList();
 
   @NotNull
-  public abstract JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value);
+  public abstract JComponent getComponent(@NotNull RadComponent rootComponent,
+                                          @Nullable RadComponent component,
+                                          Object value,
+                                          @Nullable InplaceContext inplaceContext);
 
   @Nullable
-  public JComponent getPreferredFocusedComponent(@NotNull JComponent component) {
+  public JComponent getPreferredFocusedComponent() {
     return null;
   }
 
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java
index f22f320262b2..eafb8dc3dc24 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTable.java
@@ -533,7 +533,7 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi
     editCellAt(index, convertColumnIndexToView(1));
     LOG.assertTrue(editorComp != null);
 
-    JComponent preferredComponent = editor.getPreferredFocusedComponent((JComponent)editorComp);
+    JComponent preferredComponent = editor.getPreferredFocusedComponent();
     if (preferredComponent == null) {
       preferredComponent = IdeFocusTraversalPolicy.getPreferredFocusedComponent((JComponent)editorComp);
     }
@@ -855,7 +855,7 @@ public final class PropertyTable extends JBTable implements ComponentSelectionLi
     @Override
     public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
       try {
-        JComponent component = myEditor.getComponent(myDesigner.getRootComponent(), getCurrentComponent(), getValue((Property)value));
+        JComponent component = myEditor.getComponent(myDesigner.getRootComponent(), getCurrentComponent(), getValue((Property)value), null);
 
         if (component instanceof JComboBox) {
           component.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java
index 54c7891b27ec..de01a6a7fbf7 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/PropertyTablePanel.java
@@ -17,6 +17,8 @@ package com.intellij.designer.propertyTable;
 
 import com.intellij.designer.DesignerBundle;
 import com.intellij.designer.propertyTable.actions.IPropertyTableAction;
+import com.intellij.designer.propertyTable.actions.RestoreDefault;
+import com.intellij.designer.propertyTable.actions.ShowExpert;
 import com.intellij.designer.propertyTable.actions.ShowJavadoc;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.actionSystem.impl.ActionButton;
@@ -45,11 +47,19 @@ public final class PropertyTablePanel extends JPanel implements ListSelectionLis
         new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 5, 2, 0), 0, 0));
 
     ActionManager actionManager = ActionManager.getInstance();
+    DefaultActionGroup actionGroup = new DefaultActionGroup();
 
-    AnAction quickJavadocAction = ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC);
-    new ShowJavadoc().registerCustomShortcutSet(quickJavadocAction.getShortcutSet(), myPropertyTable);
+    ShowJavadoc showJavadoc = new ShowJavadoc(myPropertyTable);
+    showJavadoc.registerCustomShortcutSet(actionManager.getAction(IdeActions.ACTION_QUICK_JAVADOC).getShortcutSet(), myPropertyTable);
+    actionGroup.add(showJavadoc);
 
-    ActionGroup actionGroup = (ActionGroup)actionManager.getAction("UIDesigner.PropertyTable");
+    actionGroup.addSeparator();
+
+    RestoreDefault restoreDefault = new RestoreDefault(myPropertyTable);
+    restoreDefault.registerCustomShortcutSet(actionManager.getAction(IdeActions.ACTION_DELETE).getShortcutSet(), myPropertyTable);
+    actionGroup.add(restoreDefault);
+
+    actionGroup.add(new ShowExpert(myPropertyTable));
 
     PopupHandler.installPopupHandler(myPropertyTable, actionGroup,
                                      ActionPlaces.GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP,
@@ -82,7 +92,7 @@ public final class PropertyTablePanel extends JPanel implements ListSelectionLis
   public void valueChanged(ListSelectionEvent e) {
     for (AnAction action : myActions) {
       if (action instanceof IPropertyTableAction) {
-        ((IPropertyTableAction)action).update(myPropertyTable);
+        ((IPropertyTableAction)action).update();
       }
     }
   }
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/IPropertyTableAction.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/IPropertyTableAction.java
index c4585198cfc9..78fd4094fa22 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/IPropertyTableAction.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/IPropertyTableAction.java
@@ -15,11 +15,9 @@
  */
 package com.intellij.designer.propertyTable.actions;
 
-import com.intellij.designer.propertyTable.PropertyTable;
-
 /**
  * @author Alexander Lobas
  */
 public interface IPropertyTableAction {
-  void update(PropertyTable table);
+  void update();
 }
\ No newline at end of file
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/RestoreDefault.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/RestoreDefault.java
index 1261283f1599..3f36998c7a1e 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/RestoreDefault.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/RestoreDefault.java
@@ -16,7 +16,6 @@
 package com.intellij.designer.propertyTable.actions;
 
 import com.intellij.designer.DesignerBundle;
-import com.intellij.designer.DesignerToolWindowManager;
 import com.intellij.designer.propertyTable.Property;
 import com.intellij.designer.propertyTable.PropertyTable;
 import com.intellij.openapi.actionSystem.AnAction;
@@ -28,7 +27,11 @@ import com.intellij.openapi.util.IconLoader;
  * @author Alexander Lobas
  */
 public class RestoreDefault extends AnAction implements IPropertyTableAction {
-  public RestoreDefault() {
+  private final PropertyTable myTable;
+
+  public RestoreDefault(PropertyTable table) {
+    myTable = table;
+
     Presentation presentation = getTemplatePresentation();
     String text = DesignerBundle.message("designer.properties.restore_default");
     presentation.setText(text);
@@ -38,13 +41,12 @@ public class RestoreDefault extends AnAction implements IPropertyTableAction {
 
   @Override
   public void update(AnActionEvent e) {
-    PropertyTable table = DesignerToolWindowManager.getInstance(e.getProject()).getPropertyTable();
-    setEnabled(table, e.getPresentation());
+    setEnabled(myTable, e.getPresentation());
   }
 
   @Override
-  public void update(PropertyTable table) {
-    setEnabled(table, getTemplatePresentation());
+  public void update() {
+    setEnabled(myTable, getTemplatePresentation());
   }
 
   private static void setEnabled(PropertyTable table, Presentation presentation) {
@@ -57,10 +59,8 @@ public class RestoreDefault extends AnAction implements IPropertyTableAction {
     }
   }
 
-
   @Override
   public void actionPerformed(AnActionEvent e) {
-    PropertyTable table = DesignerToolWindowManager.getInstance(e.getProject()).getPropertyTable();
-    table.restoreDefaultValue();
+    myTable.restoreDefaultValue();
   }
 }
\ No newline at end of file
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowExpert.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowExpert.java
index 7b972ff85967..3348c8f88736 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowExpert.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowExpert.java
@@ -16,7 +16,6 @@
 package com.intellij.designer.propertyTable.actions;
 
 import com.intellij.designer.DesignerBundle;
-import com.intellij.designer.DesignerToolWindowManager;
 import com.intellij.designer.propertyTable.PropertyTable;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.Presentation;
@@ -27,7 +26,11 @@ import com.intellij.openapi.util.IconLoader;
  * @author Alexander Lobas
  */
 public class ShowExpert extends ToggleAction {
-  public ShowExpert() {
+  private final PropertyTable myTable;
+
+  public ShowExpert(PropertyTable table) {
+    myTable = table;
+
     Presentation presentation = getTemplatePresentation();
     String text = DesignerBundle.message("designer.properties.show.expert");
     presentation.setText(text);
@@ -37,13 +40,11 @@ public class ShowExpert extends ToggleAction {
 
   @Override
   public boolean isSelected(AnActionEvent e) {
-    PropertyTable table = DesignerToolWindowManager.getInstance(e.getProject()).getPropertyTable();
-    return table.isShowExpert();
+    return myTable.isShowExpert();
   }
 
   @Override
   public void setSelected(AnActionEvent e, boolean state) {
-    PropertyTable table = DesignerToolWindowManager.getInstance(e.getProject()).getPropertyTable();
-    table.showExpert(state);
+    myTable.showExpert(state);
   }
 }
\ No newline at end of file
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java
index c11a585ba6dc..06778d652f4d 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java
@@ -18,7 +18,6 @@ package com.intellij.designer.propertyTable.actions;
 import com.intellij.codeInsight.documentation.DocumentationComponent;
 import com.intellij.codeInsight.documentation.DocumentationManager;
 import com.intellij.designer.DesignerBundle;
-import com.intellij.designer.DesignerToolWindowManager;
 import com.intellij.designer.propertyTable.Property;
 import com.intellij.designer.propertyTable.PropertyTable;
 import com.intellij.openapi.actionSystem.AnAction;
@@ -28,11 +27,13 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.popup.JBPopup;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.util.ActionCallback;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
 import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.popup.NotLookupOrSearchCondition;
 
 import java.awt.*;
 
@@ -40,7 +41,11 @@ import java.awt.*;
  * @author Alexander Lobas
  */
 public class ShowJavadoc extends AnAction implements IPropertyTableAction {
-  public ShowJavadoc() {
+  private final PropertyTable myTable;
+
+  public ShowJavadoc(PropertyTable table) {
+    myTable = table;
+
     Presentation presentation = getTemplatePresentation();
     String text = DesignerBundle.message("designer.properties.show.javadoc");
     presentation.setText(text);
@@ -50,13 +55,12 @@ public class ShowJavadoc extends AnAction implements IPropertyTableAction {
 
   @Override
   public void update(AnActionEvent e) {
-    PropertyTable table = DesignerToolWindowManager.getInstance(e.getProject()).getPropertyTable();
-    setEnabled(table, e.getPresentation());
+    setEnabled(myTable, e.getPresentation());
   }
 
   @Override
-  public void update(PropertyTable table) {
-    setEnabled(table, getTemplatePresentation());
+  public void update() {
+    setEnabled(myTable, getTemplatePresentation());
   }
 
   private static void setEnabled(PropertyTable table, Presentation presentation) {
@@ -70,8 +74,7 @@ public class ShowJavadoc extends AnAction implements IPropertyTableAction {
     DocumentationManager documentationManager = DocumentationManager.getInstance(project);
     final DocumentationComponent component = new DocumentationComponent(documentationManager);
 
-    final PropertyTable table = DesignerToolWindowManager.getInstance(project).getPropertyTable();
-    final Property property = table.getSelectionProperty();
+    final Property property = myTable.getSelectionProperty();
     PsiElement javadocElement = property.getJavadocElement();
 
     ActionCallback callback;
@@ -85,17 +88,26 @@ public class ShowJavadoc extends AnAction implements IPropertyTableAction {
 
     callback.doWhenProcessed(new Runnable() {
       public void run() {
-        final JBPopup hint =
+        JBPopup hint =
           JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
+            .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
+            .setProject(project)
             .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
             .setResizable(true)
             .setMovable(true)
             .setRequestFocus(true)
             .setTitle(DesignerBundle.message("designer.properties.javadoc.title", property.getName()))
+            .setCancelCallback(new Computable() {
+              @Override
+              public Boolean compute() {
+                Disposer.dispose(component);
+                return Boolean.TRUE;
+              }
+            })
             .createPopup();
         component.setHint(hint);
         Disposer.register(hint, component);
-        hint.show(new RelativePoint(table.getParent(), new Point(0, 0)));
+        hint.show(new RelativePoint(myTable.getParent(), new Point(0, 0)));
       }
     });
 
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java
index bc57cc10b9da..b069d777add7 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java
@@ -16,6 +16,7 @@
 package com.intellij.designer.propertyTable.editors;
 
 import com.intellij.designer.model.RadComponent;
+import com.intellij.designer.propertyTable.InplaceContext;
 import com.intellij.designer.propertyTable.PropertyEditor;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
@@ -52,8 +53,16 @@ public class BooleanEditor extends PropertyEditor {
     return Boolean.valueOf(myCheckBox.isSelected());
   }
 
+  @Override
+  public JComponent getPreferredFocusedComponent() {
+    return myCheckBox;
+  }
+
   @NotNull
-  public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) {
+  public JComponent getComponent(@NotNull RadComponent rootComponent,
+                                 @Nullable RadComponent component,
+                                 Object value,
+                                 @Nullable InplaceContext inplaceContext) {
     try {
       myInsideChange = true;
       myCheckBox.setBackground(UIUtil.getTableBackground());
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java
index dc661ab879fd..f19eb16efed7 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java
@@ -52,6 +52,11 @@ public abstract class ComboEditor extends PropertyEditor {
     }
   }
 
+  @Override
+  public JComponent getPreferredFocusedComponent() {
+    return myCombo;
+  }
+
   private static class ComboListeners implements PopupMenuListener, ActionListener {
     private final PropertyEditor myEditor;
     private boolean myCancelled;
diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/TextEditor.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/TextEditor.java
index e226de011224..592a859cd72f 100644
--- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/TextEditor.java
+++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/TextEditor.java
@@ -16,11 +16,15 @@
 package com.intellij.designer.propertyTable.editors;
 
 import com.intellij.designer.model.RadComponent;
+import com.intellij.designer.propertyTable.InplaceContext;
 import com.intellij.designer.propertyTable.PropertyEditor;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
+import javax.swing.event.DocumentEvent;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 
@@ -37,13 +41,36 @@ public class TextEditor extends PropertyEditor {
         fireValueCommitted(true, false);
       }
     });
+    myTextField.getDocument().addDocumentListener(
+      new DocumentAdapter() {
+        protected void textChanged(final DocumentEvent e) {
+          preferredSizeChanged();
+        }
+      }
+    );
   }
 
   @NotNull
   @Override
-  public JComponent getComponent(@NotNull RadComponent rootComponent, @Nullable RadComponent component, Object value) {
+  public JComponent getComponent(@NotNull RadComponent rootComponent,
+                                 @Nullable RadComponent component,
+                                 Object value,
+                                 @Nullable InplaceContext inplaceContext) {
     setEditorValue(component, value);
-    myTextField.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
+    if (inplaceContext == null) {
+      myTextField.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
+    }
+    else {
+      myTextField.setBorder(UIUtil.getTextFieldBorder());
+      if (inplaceContext.isStartChar()) {
+        myTextField.setText(inplaceContext.getText(myTextField.getText()));
+      }
+    }
+    return myTextField;
+  }
+
+  @Override
+  public JComponent getPreferredFocusedComponent() {
     return myTextField;
   }
 
diff --git a/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties b/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties
index f105d74fd4cf..aeb0e5ad1812 100644
--- a/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties
+++ b/plugins/ui-designer/ui-designer-new/src/messages/DesignerBundle.properties
@@ -8,7 +8,7 @@ command.set.property.value=Set Property Value
 designer.properties.title=Properties
 designer.properties.show.expert=Show expert properties
 designer.properties.show.javadoc=Show Documentation
-designer.properties.javadoc.title=Documentation for {0} property
+designer.properties.javadoc.title=Documentation for {0} property
 designer.properties.restore_default=Restore default value
 designer.properties.column1=Property
 designer.properties.column2=Value
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index 233461687c9d..acb49fac6a1a 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -761,6 +761,7 @@
     
     
     
+    
     
 
     
diff --git a/xml/dom-impl/src/com/intellij/util/dom/generator/DomGenPanel.form b/xml/dom-impl/src/com/intellij/util/dom/generator/DomGenPanel.form
index fdf67645cb77..c914572ca2e4 100644
--- a/xml/dom-impl/src/com/intellij/util/dom/generator/DomGenPanel.form
+++ b/xml/dom-impl/src/com/intellij/util/dom/generator/DomGenPanel.form
@@ -7,7 +7,7 @@
     
     
     
-      
+      
     
     
     
diff --git a/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form b/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form
index 1c22db5fb1aa..cd42e379619c 100644
--- a/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form
+++ b/xml/impl/src/com/intellij/application/options/XmlAutoImportOptionsProvider.form
@@ -16,7 +16,7 @@
         
         
         
-          
+          
         
         
           
diff --git a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form
index c37baff30100..0030a84058ef 100644
--- a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form
+++ b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form
@@ -15,7 +15,7 @@
         
         
         
-          
+          
         
         
         
diff --git a/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java b/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java
index 130ea0ef209a..2ff3bc720240 100644
--- a/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java
+++ b/xml/relaxng/test/org/intellij/plugins/relaxNG/HighlightingTestBase.java
@@ -37,6 +37,7 @@ import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiReference;
 import com.intellij.testFramework.ExpectedHighlightingData;
+import com.intellij.testFramework.PlatformTestCase;
 import com.intellij.testFramework.PlatformTestUtil;
 import com.intellij.testFramework.UsefulTestCase;
 import com.intellij.testFramework.builders.EmptyModuleFixtureBuilder;
@@ -51,42 +52,21 @@ import org.intellij.plugins.testUtil.IdeaCodeInsightTestCase;
 import org.intellij.plugins.testUtil.ResourceUtil;
 import org.jetbrains.annotations.NotNull;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.Collection;
 
-import static com.intellij.openapi.util.io.FileUtil.delete;
-
 /**
  * Created by IntelliJ IDEA.
  * User: sweinreuter
  * Date: 25.07.2007
  */
 public abstract class HighlightingTestBase extends UsefulTestCase implements IdeaCodeInsightTestCase {
-  private static final File ourTempPath;
-
-  private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
-
-  static {
-    // IDEA leaves bazillions of "ideaXXXX.ipr" files and "unitTestXXXX.tmp" directories in the temp directory
-    ourTempPath = new File(new File(System.getProperty(JAVA_IO_TMPDIR, "/tmp")), "test" + System.identityHashCode(Object.class));
-    ourTempPath.mkdirs();
-
-    try {
-      System.setProperty(JAVA_IO_TMPDIR, ourTempPath.getCanonicalPath());
-      Runtime.getRuntime().addShutdownHook(new Thread("Cleanup Temp") {
-        @Override
-        public void run() {
-          delete(ourTempPath);
-        }
-      });
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
   protected CodeInsightTestFixture myTestFixture;
 
+  @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
+  protected HighlightingTestBase() {
+    PlatformTestCase.initPlatformLangPrefix();
+  }
+
   protected void setUp() throws Exception {
     super.setUp();
     final IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory();