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 extends Breakpoint> 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 extends Breakpoint> 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 extends Breakpoint> 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 extends ModuleLevelBuilder> 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 @@