Merge remote-tracking branch 'origin/master'

This commit is contained in:
Konstantin Bulenkov
2012-09-22 03:38:05 +04:00
145 changed files with 2679 additions and 1160 deletions
@@ -338,6 +338,7 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements
}
}
@Override
public ExcludedEntriesConfiguration getExcludedEntriesConfiguration() {
return myExcludedEntriesConfiguration;
}
@@ -54,13 +54,11 @@ public abstract class ProblemsView {
myProject = project;
}
public abstract void clearMessages(CompileScope scope);
public abstract void clearMessages();
public abstract void clearOldMessages(CompileScope scope, UUID currentSessionId);
public abstract void addMessage(int type, @NotNull String[] text, @Nullable String groupName, @NotNull Navigatable navigatable, @Nullable String exportTextPrefix, @Nullable String rendererTextPrefix, @NotNull UUID sessionId);
public void addMessage(CompilerMessage message, @NotNull UUID sessionId) {
public final void addMessage(CompilerMessage message, @NotNull UUID sessionId) {
final VirtualFile file = message.getVirtualFile();
Navigatable navigatable = message.getNavigatable();
if (navigatable == null) {
@@ -445,13 +445,13 @@ public class CompileDriver {
return buildManager.scheduleBuild(myProject, compileContext.isRebuild(), compileContext.isMake(), scopes, paths, builderParams, new DefaultMessageHandler(myProject) {
@Override
public void buildStarted(UUID sessionId) {
final ProblemsView view = ProblemsViewImpl.SERVICE.getInstance(myProject);
view.clearMessages(compileContext.getCompileScope());
view.clearProgress();
}
@Override
public void sessionTerminated(UUID sessionId) {
final ProblemsView view = ProblemsViewImpl.SERVICE.getInstance(myProject);
view.clearProgress();
view.clearOldMessages(compileContext.getCompileScope(), sessionId);
}
@Override
@@ -16,21 +16,28 @@
package com.intellij.compiler.impl;
import com.intellij.compiler.ProblemsView;
import com.intellij.ide.errorTreeView.ErrorTreeElement;
import com.intellij.ide.errorTreeView.ErrorViewStructure;
import com.intellij.ide.errorTreeView.GroupingElement;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.pom.Navigatable;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.util.concurrency.SequentialTaskExecutor;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
import java.util.concurrent.Executor;
/**
* @author Eugene Zhuravlev
@@ -40,6 +47,12 @@ public class ProblemsViewImpl extends ProblemsView{
private static final String PROBLEMS_TOOLWINDOW_ID = "Problems";
private final ProblemsViewPanel myPanel;
private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(new Executor() {
@Override
public void execute(Runnable command) {
ApplicationManager.getApplication().executeOnPooledThread(command);
}
});
public ProblemsViewImpl(final Project project, final ToolWindowManager wm) {
super(project);
@@ -71,21 +84,39 @@ public class ProblemsViewImpl extends ProblemsView{
}
@Override
public void clearMessages(CompileScope scope) {
// todo: temporary solution:
clearMessages();
/*
final ErrorViewStructure structure = myPanel.getErrorViewStructure();
for (ErrorTreeElement element : structure.getChildElements(structure.getRootElement())) {
// todo: add ability to remove selected messages in structure
}
*/
public void clearOldMessages(@Nullable final CompileScope scope, @NotNull final UUID currentSessionId) {
myViewUpdater.execute(new Runnable() {
@Override
public void run() {
cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId);
myPanel.reload();
}
});
}
@Override
public void clearMessages() {
myPanel.clearMessages();
private void cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) {
final ErrorViewStructure structure = myPanel.getErrorViewStructure();
for (ErrorTreeElement element : structure.getChildElements(fromElement)) {
if (element instanceof GroupingElement) {
if (scope != null) {
final VirtualFile file = ((GroupingElement)element).getFile();
if (file != null && !scope.belongs(file.getUrl())) {
continue;
}
}
if (!currentSessionId.equals(element.getData())) {
structure.removeElement(element);
}
else {
cleanupChildrenRecursively(element, scope, currentSessionId);
}
}
else {
if (!currentSessionId.equals(element.getData())) {
structure.removeElement(element);
}
}
}
}
@Override
@@ -94,7 +125,18 @@ public class ProblemsViewImpl extends ProblemsView{
@Nullable final String groupName,
@NotNull final Navigatable navigatable,
@Nullable final String exportTextPrefix, @Nullable final String rendererTextPrefix, @Nullable final UUID sessionId) {
myPanel.addMessage(type, text, groupName, navigatable, exportTextPrefix, rendererTextPrefix, sessionId);
myViewUpdater.execute(new Runnable() {
@Override
public void run() {
final ErrorViewStructure structure = myPanel.getErrorViewStructure();
final GroupingElement group = structure.lookupGroupingElement(groupName);
if (group != null && !sessionId.equals(group.getData())) {
structure.removeElement(group);
}
myPanel.addMessage(type, text, groupName, navigatable, exportTextPrefix, rendererTextPrefix, sessionId);
}
});
}
@Override
@@ -15,34 +15,21 @@
*/
package com.intellij.compiler.options;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
import com.intellij.compiler.CompilerSettingsFactory;
import com.intellij.compiler.impl.rmiCompiler.RmicConfiguration;
import com.intellij.compiler.server.BuildManager;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.compiler.options.ExcludedEntriesConfigurable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.FileStatusManager;
import org.jetbrains.annotations.Nls;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class CompilerConfigurable implements SearchableConfigurable.Parent, Configurable.NoScroll {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.options.CompilerConfigurable");
private final Project myProject;
private final CompilerUIConfigurable myCompilerUIConfigurable;
@@ -101,100 +88,16 @@ public class CompilerConfigurable implements SearchableConfigurable.Parent, Conf
public Configurable[] getConfigurables() {
if (myKids == null) {
List<Configurable> kids = new ArrayList<Configurable>();
CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, false, false, false, true);
final ExcludedEntriesConfigurable excludes =
new ExcludedEntriesConfigurable(myProject, descriptor, compilerConfiguration.getExcludedEntriesConfiguration()) {
public void apply() {
super.apply();
FileStatusManager.getInstance(myProject).fileStatusesChanged(); // refresh exclude from compile status
//ProjectView.getInstance(myProject).refresh();
}
};
kids.add(createExcludesWrapper(excludes, myProject));
ArrayList<Configurable> additional = new ArrayList<Configurable>();
final CompilerSettingsFactory[] factories = Extensions.getExtensions(CompilerSettingsFactory.EP_NAME, myProject);
if (factories.length > 0) {
for (CompilerSettingsFactory factory : factories) {
final Configurable configurable;
try {
configurable = factory.create(myProject);
}
catch (Exception e) {
LOG.error(e);
continue;
}
additional.add(configurable);
myKids = ContainerUtil.mapNotNull(factories, new NullableFunction<CompilerSettingsFactory, Configurable>() {
@Nullable
@Override
public Configurable fun(CompilerSettingsFactory factory) {
return factory.create(myProject);
}
Collections.sort(additional, new Comparator<Configurable>() {
public int compare(final Configurable o1, final Configurable o2) {
return Comparing.compare(o1.getDisplayName(), o2.getDisplayName());
}
});
}
additional.add(0, new RmicConfigurable(RmicConfiguration.getSettings(myProject)));
additional.add(0, new AnnotationProcessorsConfigurable(myProject));
additional.add(0, new JavaCompilersTab(myProject, compilerConfiguration.getRegisteredJavaCompilers(),
compilerConfiguration.getDefaultCompiler()));
kids.addAll(additional);
myKids = kids.toArray(new Configurable[kids.size()]);
}, new Configurable[0]);
}
return myKids;
}
private static Configurable createExcludesWrapper(final ExcludedEntriesConfigurable excludes, final Project project) {
return new SearchableConfigurable() {
@Nls
public String getDisplayName() {
return "Excludes";
}
public String getHelpTopic() {
return "reference.projectsettings.compiler.excludes";
}
public JComponent createComponent() {
return excludes.createComponent();
}
public void apply() {
excludes.apply();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
BuildManager.getInstance().clearState(project);
}
});
}
public boolean isModified() {
return excludes.isModified();
}
public void reset() {
excludes.reset();
}
public void disposeUIResources() {
excludes.disposeUIResources();
}
@NotNull
public String getId() {
return getHelpTopic();
}
public Runnable enableSearch(String option) {
return null;
}
};
}
}
@@ -54,6 +54,11 @@ public class JavaCompilersTab implements SearchableConfigurable, Configurable.No
private final Collection<Configurable> myConfigurables;
private final TargetOptionsComponent myTargetLevelComponent;
public JavaCompilersTab(final Project project) {
this(project, ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getRegisteredJavaCompilers(),
((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getDefaultCompiler());
}
public JavaCompilersTab(final Project project, Collection<BackendCompiler> compilers, BackendCompiler defaultCompiler) {
myProject = project;
myDefaultCompiler = defaultCompiler;
@@ -15,11 +15,13 @@
*/
package com.intellij.compiler.options;
import com.intellij.compiler.impl.rmiCompiler.RmicConfiguration;
import com.intellij.compiler.impl.rmiCompiler.RmicSettings;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.ui.RawCommandLineEditor;
import org.jetbrains.annotations.NotNull;
@@ -41,8 +43,8 @@ public class RmicConfigurable implements SearchableConfigurable, Configurable.No
private final RmicSettings myRmicSettings;
private JLabel myFieldLabel;
public RmicConfigurable(final RmicSettings javacSettings) {
myRmicSettings = javacSettings;
public RmicConfigurable(final Project project) {
myRmicSettings = RmicConfiguration.getSettings(project);
myCbEnabled.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
setOptionsEnabled(e.getStateChange() == ItemEvent.SELECTED);
@@ -54,9 +54,6 @@ class AutoMakeMessageHandler extends DefaultMessageHandler {
@Override
public void buildStarted(UUID sessionId) {
final ProblemsView view = ProblemsView.SERVICE.getInstance(myProject);
view.clearMessages();
view.clearProgress();
}
@Override
@@ -147,7 +144,9 @@ class AutoMakeMessageHandler extends DefaultMessageHandler {
myProject.putUserData(LAST_AUTO_MAKE_NOFITICATION, null);
}
}
ProblemsView.SERVICE.getInstance(myProject).clearProgress();
final ProblemsView view = ProblemsView.SERVICE.getInstance(myProject);
view.clearProgress();
view.clearOldMessages(null, sessionId);
}
private void informWolf(Project project, CmdlineRemoteProto.Message.BuilderMessage.CompileMessage message) {
@@ -66,7 +66,6 @@ import com.intellij.util.concurrency.SequentialTaskExecutor;
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;
@@ -963,8 +962,8 @@ public class BuildManager implements ApplicationComponent{
private static class ProjectData {
final SequentialTaskExecutor taskQueue;
private final Set<String> myChanged = new THashSet<String>(PathHashingStrategy.INSTANCE);
private final Set<String> myDeleted = new THashSet<String>(PathHashingStrategy.INSTANCE);
private final Set<String> myChanged = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
private final Set<String> myDeleted = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
private long myNextEventOrdinal = 0L;
private boolean myNeedRescan = true;
@@ -1009,20 +1008,6 @@ public class BuildManager implements ApplicationComponent{
myChanged.clear();
myDeleted.clear();
}
static class PathHashingStrategy implements TObjectHashingStrategy<String> {
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);
}
}
}
}
@@ -16,6 +16,7 @@
package com.intellij.compiler;
import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -58,4 +59,6 @@ public abstract class CompilerConfiguration {
public abstract boolean isAddNotNullAssertions();
public abstract void setAddNotNullAssertions(boolean enabled);
public abstract ExcludedEntriesConfiguration getExcludedEntriesConfiguration();
}
@@ -20,9 +20,11 @@ import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
/**
* Please use {@link com.intellij.openapi.options.ConfigurableEP#parentId} to put your configurable under Compiler Settings
* @author Eugene Zhuravlev
* Date: Sep 17, 2008
*/
@Deprecated
public interface CompilerSettingsFactory {
ExtensionPointName<CompilerSettingsFactory> EP_NAME = ExtensionPointName.create("com.intellij.compilerSettingsFactory");
@@ -16,6 +16,7 @@
package com.intellij.openapi.compiler.options;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.fileChooser.FileChooser;
@@ -24,6 +25,7 @@ import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.table.JBTable;
@@ -47,6 +49,11 @@ public class ExcludedEntriesConfigurable implements UnnamedConfigurable {
private final ExcludedEntriesConfiguration myConfiguration;
private ExcludedEntriesPanel myExcludedEntriesPanel;
public ExcludedEntriesConfigurable(Project project) {
this(project, new FileChooserDescriptor(true, true, false, false, false, true),
CompilerConfiguration.getInstance(project).getExcludedEntriesConfiguration());
}
public ExcludedEntriesConfigurable(Project project, FileChooserDescriptor descriptor, final ExcludedEntriesConfiguration configuration) {
myDescriptor = descriptor;
myConfiguration = configuration;
@@ -79,6 +86,7 @@ public class ExcludedEntriesConfigurable implements UnnamedConfigurable {
for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
myConfiguration.addExcludeEntryDescription(description.copy(myProject));
}
FileStatusManager.getInstance(myProject).fileStatusesChanged(); // refresh exclude from compile status
}
public boolean isModified() {
@@ -44,7 +44,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.HtmlListCellRenderer;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SortedComboBoxModel;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.PathUtil;
@@ -190,9 +190,9 @@ public class LibraryOptionsPanel implements Disposable {
updateState();
}
});
myExistingLibraryComboBox.setRenderer(new HtmlListCellRenderer() {
myExistingLibraryComboBox.setRenderer(new ColoredListCellRenderer() {
@Override
protected void doCustomize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (value == null) {
append("[No library selected]");
}
@@ -60,7 +60,7 @@ public class JdkChooserPanel extends JPanel {
myListModel = new DefaultListModel();
myList = new JBList(myListModel);
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myList.setCellRenderer(new ProjectJdkListRenderer(myList.getCellRenderer()));
myList.setCellRenderer(new ProjectJdkListRenderer());
myList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
@@ -17,7 +17,7 @@ package com.intellij.ide.util.projectWizard;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ui.OrderEntryAppearanceService;
import com.intellij.ui.HtmlListCellRenderer;
import com.intellij.ui.ColoredListCellRendererWrapper;
import com.intellij.ui.SimpleTextAttributes;
import javax.swing.*;
@@ -26,11 +26,7 @@ import javax.swing.*;
* @author Eugene Zhuravlev
* @since May 18, 2005
*/
public class ProjectJdkListRenderer extends HtmlListCellRenderer {
public ProjectJdkListRenderer(final ListCellRenderer listCellRenderer) {
super();
}
public class ProjectJdkListRenderer extends ColoredListCellRendererWrapper {
@Override
public void doCustomize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (value == null || value instanceof Sdk) {
@@ -63,7 +63,7 @@ public class JdkComboBox extends ComboBoxWithWidePopup {
super(new JdkComboBoxModel(jdkModel, filter));
myFilter = filter;
myCreationFilter = creationFilter;
setRenderer(new ProjectJdkListRenderer(getRenderer()) {
setRenderer(new ProjectJdkListRenderer() {
@Override
public void doCustomize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
if (JdkComboBox.this.isEnabled()) {
@@ -121,7 +121,7 @@ public class HighlightMethodUtil {
for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
PsiMethod superMethod = superMethodSignature.getMethod();
PsiType declaredReturnType = superMethod.getReturnType();
PsiType superReturnType = superMethodSignature.getSubstitutor().substitute(declaredReturnType);
PsiType superReturnType = declaredReturnType;
if (superMethodSignature.isRaw()) superReturnType = TypeConversionUtil.erasure(declaredReturnType);
if (returnType == null || superReturnType == null || method == superMethod) continue;
PsiClass superClass = superMethod.getContainingClass();
@@ -151,10 +151,10 @@ public class HighlightMethodUtil {
superMethodSignature);
substitutedSuperReturnType = unifyingSubstitutor == null
? superReturnType
: unifyingSubstitutor.substitute(superMethodSignature.getSubstitutor().substitute(superReturnType));
: unifyingSubstitutor.substitute(superReturnType);
}
else {
substitutedSuperReturnType = TypeConversionUtil.erasure(superReturnType);
substitutedSuperReturnType = TypeConversionUtil.erasure(superMethodSignature.getSubstitutor().substitute(superReturnType));
}
if (returnType.equals(substitutedSuperReturnType)) return null;
@@ -0,0 +1,267 @@
/*
* 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.documentation;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.QuickFix;
import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection;
import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection;
import com.intellij.javadoc.JavadocNavigationDelegate;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* @author Denis Zhdanov
* @since 9/20/12 8:44 PM
*/
public class JavaDocCommentFixer implements DocCommentFixer {
@NotNull private static final String PARAM_TAG = "@param";
/**
* Lists tags eligible for moving caret to after javadoc fixing. The main idea is that we want to locate caret at the
* incomplete tag description after fixing the doc comment.
* <p/>
* Example:
* <pre>
* class Test {
* &#47;**
* * Method description
* *
* * @param i 'i' argument
* * @param j [we want to move the caret here because j's description is missing]
* *&#47;
* void test(int i, int j) {
* }
* }
* </pre>
*/
@NotNull private static final Set<String> CARET_ANCHOR_TAGS = ContainerUtilRt.newHashSet(PARAM_TAG, "@throws", "@return");
@NotNull private static final List<String> TAGS_ORDER = new ArrayList<String>();
static {
String tags = System.getProperty("java.doc.comment.fix.tags.order");
if (tags == null) {
tags = "@param:@return:@throws";
}
for (String s : tags.split(":")) {
String tagName = s.trim();
if (!tagName.isEmpty()) {
TAGS_ORDER.add("@" + tagName);
}
}
}
private static final Comparator<PsiElement> COMPARATOR = new Comparator<PsiElement>() {
@Override
public int compare(PsiElement e1, PsiElement e2) {
return e2.getTextRange().getEndOffset() - e1.getTextRange().getEndOffset();
}
};
@Override
public void fixComment(@NotNull Project project, @NotNull Editor editor, @NotNull PsiComment comment) {
if (!(comment instanceof PsiDocComment)) {
return;
}
PsiDocCommentOwner owner = ((PsiDocComment)comment).getOwner();
if (owner == null) {
return;
}
JavaDocReferenceInspection referenceInspection = new JavaDocReferenceInspection();
JavaDocLocalInspection localInspection = getDocLocalInspection();
InspectionManager inspectionManager = InspectionManager.getInstance(project);
ProblemDescriptor[] referenceProblems = null;
ProblemDescriptor[] otherProblems = null;
if (owner instanceof PsiClass) {
referenceProblems = referenceInspection.checkClass(((PsiClass)owner), inspectionManager, false);
otherProblems = localInspection.checkClass(((PsiClass)owner), inspectionManager, false);
}
else if (owner instanceof PsiField) {
referenceProblems = referenceInspection.checkField(((PsiField)owner), inspectionManager, false);
otherProblems = localInspection.checkField(((PsiField)owner), inspectionManager, false);
}
else if (owner instanceof PsiMethod) {
referenceProblems = referenceInspection.checkMethod((PsiMethod)owner, inspectionManager, false);
otherProblems = localInspection.checkMethod((PsiMethod)owner, inspectionManager, false);
}
if (referenceProblems != null) {
fixReferenceProblems(referenceProblems, project);
}
if (otherProblems != null) {
fixCommonProblems(otherProblems, comment, editor.getDocument(), project);
}
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
locateCaret((PsiDocComment)comment, editor);
}
@NotNull
private static JavaDocLocalInspection getDocLocalInspection() {
JavaDocLocalInspection localInspection = new JavaDocLocalInspection();
//region visibility
localInspection.TOP_LEVEL_CLASS_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = PsiModifier.PRIVATE;
localInspection.INNER_CLASS_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = PsiModifier.PRIVATE;
localInspection.FIELD_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = PsiModifier.PRIVATE;
localInspection.METHOD_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = PsiModifier.PRIVATE;
//endregion
localInspection.IGNORE_EMPTY_DESCRIPTIONS = true;
//region class type arguments
if (!localInspection.TOP_LEVEL_CLASS_OPTIONS.REQUIRED_TAGS.contains(PARAM_TAG)) {
localInspection.TOP_LEVEL_CLASS_OPTIONS.REQUIRED_TAGS += PARAM_TAG;
}
if (!localInspection.INNER_CLASS_OPTIONS.REQUIRED_TAGS.contains(PARAM_TAG)) {
localInspection.INNER_CLASS_OPTIONS.REQUIRED_TAGS += PARAM_TAG;
}
//endregion
return localInspection;
}
@SuppressWarnings("unchecked")
private static void fixReferenceProblems(@NotNull ProblemDescriptor[] problems, @NotNull Project project) {
for (ProblemDescriptor problem : problems) {
QuickFix[] fixes = problem.getFixes();
if (fixes != null) {
fixes[0].applyFix(project, problem);
}
}
}
// TODO den add doc
@SuppressWarnings("unchecked")
private static void fixCommonProblems(@NotNull ProblemDescriptor[] problems,
@NotNull PsiComment comment,
@NotNull final Document document,
@NotNull Project project)
{
List<PsiElement> toRemove = new ArrayList<PsiElement>();
for (ProblemDescriptor problem : problems) {
PsiElement element = problem.getPsiElement();
if (element == null) {
continue;
}
if (comment.getTextRange().contains(element.getTextRange())) {
// Unnecessary element like '@return' at the void method's javadoc.
for (PsiElement e = element; e != null; e = e.getParent()) {
if (e instanceof PsiDocTag) {
toRemove.add(e);
break;
}
}
}
else {
// Problems like 'missing @param'.
QuickFix[] fixes = problem.getFixes();
if (fixes != null && fixes.length > 0) {
fixes[0].applyFix(project, problem);
}
}
}
if (toRemove.isEmpty()) {
return;
}
if (toRemove.size() > 1) {
Collections.sort(toRemove, COMPARATOR);
}
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
CharSequence text = document.getCharsSequence();
for (PsiElement element : toRemove) {
int startOffset = element.getTextRange().getStartOffset();
int startLine = document.getLineNumber(startOffset);
int i = CharArrayUtil.shiftBackward(text, startOffset - 1, " \t");
if (i >= 0) {
char c = text.charAt(i);
if (c == '*') {
i = CharArrayUtil.shiftBackward(text, i - 1, " \t");
}
}
if (i >= 0 && text.charAt(i) == '\n') {
startOffset = Math.max(i, document.getLineStartOffset(startLine) - 1);
}
int endOffset = element.getTextRange().getEndOffset();
// Javadoc PSI is awkward, it includes next line text before the next tag. That's why we need to strip it.
i = CharArrayUtil.shiftBackward(text, endOffset - 1, " \t*");
if (i > 0 && text.charAt(i) == '\n') {
endOffset = i;
}
document.deleteString(startOffset, endOffset);
}
}
private static void locateCaret(@NotNull PsiDocComment comment, @NotNull Editor editor) {
Document document = editor.getDocument();
int lineToNavigate = -1;
for (PsiDocTag tag : comment.getTags()) {
PsiElement nameElement = tag.getNameElement();
if (nameElement == null || !CARET_ANCHOR_TAGS.contains(nameElement.getText())) {
continue;
}
boolean good = false;
PsiElement[] dataElements = tag.getDataElements();
if (dataElements != null) {
PsiDocTagValue valueElement = tag.getValueElement();
for (PsiElement element : dataElements) {
if (element == valueElement) {
continue;
}
if (!StringUtil.isEmptyOrSpaces(element.getText())) {
good = true;
break;
}
}
}
if (!good) {
int offset = tag.getTextRange().getEndOffset();
CharSequence text = document.getCharsSequence();
int i = CharArrayUtil.shiftBackward(text, offset - 1, " \t*");
if (i > 0 && text.charAt(i) == '\n') {
offset = i - 1;
}
lineToNavigate = document.getLineNumber(offset);
break;
}
}
if (lineToNavigate >= 0) {
editor.getCaretModel().moveToOffset(document.getLineEndOffset(lineToNavigate));
JavadocNavigationDelegate.navigateToLineEnd(editor, comment.getContainingFile());
}
}
}
@@ -30,6 +30,7 @@ import com.intellij.codeInsight.NullableNotNullDialog;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpressionFix;
import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
@@ -182,6 +183,36 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
reportNullableAssignments(runner, holder);
reportUnboxedNullables(runner, holder);
reportNullableReturns(runner, holder);
reportNullableArgumentsPassedToNonAnnotated(runner, holder);
}
private static void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder) {
Set<PsiExpression> exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam();
for (PsiExpression expr : exprs) {
final String text = isNullLiteralExpression(expr)
? "Passing <code>null</code> argument to non annotated parameter"
: "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
LocalQuickFix[] fixes = createNPEFixes(expr, expr);
final PsiElement parent = expr.getParent();
if (parent instanceof PsiExpressionList) {
final int idx = ArrayUtil.find(((PsiExpressionList)parent).getExpressions(), expr);
if (idx > -1) {
final PsiElement gParent = parent.getParent();
if (gParent instanceof PsiCallExpression) {
final PsiMethod psiMethod = ((PsiCallExpression)gParent).resolveMethod();
if (psiMethod != null && psiMethod.getManager().isInProject(psiMethod)) {
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
if (idx < parameters.length) {
final AddNullableAnnotationFix addNullableAnnotationFix = new AddNullableAnnotationFix(parameters[idx]);
fixes = fixes == null ? new LocalQuickFix[]{addNullableAnnotationFix} : ArrayUtil.append(fixes, addNullableAnnotationFix);
holder.registerProblem(expr, text, fixes);
}
}
}
}
}
}
}
private static void reportCallMayProduceNpe(ProblemsHolder holder, MethodCallInstruction mcInstruction) {
@@ -577,5 +608,10 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
protected void onPassingNullParameter(DataFlowRunner runner, PsiExpression arg) {
((StandardDataFlowRunner)runner).onPassingNullParameter(arg); // Parameters on stack are reverted.
}
@Override
protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {
((StandardDataFlowRunner)runner).onPassingNullParameterToNonAnnotated(arg);
}
}
}
@@ -46,6 +46,7 @@ public class StandardDataFlowRunner extends AnnotationsAwareDataFlowRunner {
private final Set<Instruction> myNPEInstructions = new HashSet<Instruction>();
private final Set<Instruction> myCCEInstructions = new HashSet<Instruction>();
private final Set<PsiExpression> myNullableArguments = new HashSet<PsiExpression>();
private final Set<PsiExpression> myNullableArgumentsPassedToNonAnnotatedParam = new HashSet<PsiExpression>();
private final Set<PsiExpression> myNullableAssignments = new HashSet<PsiExpression>();
private final Set<PsiReturnStatement> myNullableReturns = new HashSet<PsiReturnStatement>();
@@ -74,6 +75,7 @@ public class StandardDataFlowRunner extends AnnotationsAwareDataFlowRunner {
myNPEInstructions.clear();
myCCEInstructions.clear();
myNullableArguments.clear();
myNullableArgumentsPassedToNonAnnotatedParam.clear();
myNullableAssignments.clear();
myNullableReturns.clear();
myUnboxedNullables.clear();
@@ -109,6 +111,10 @@ public class StandardDataFlowRunner extends AnnotationsAwareDataFlowRunner {
return myNullableArguments;
}
public Set<PsiExpression> getNullableArgumentsPassedToNonAnnotatedParam() {
return myNullableArgumentsPassedToNonAnnotatedParam;
}
@NotNull public Set<PsiExpression> getNullableAssignments() {
return myNullableAssignments;
}
@@ -128,6 +134,12 @@ public class StandardDataFlowRunner extends AnnotationsAwareDataFlowRunner {
myNullableArguments.add(expr);
}
public void onPassingNullParameterToNonAnnotated(PsiExpression expr) {
if (mySuggestNullableAnnotations) {
myNullableArgumentsPassedToNonAnnotatedParam.add(expr);
}
}
public void onAssigningToNotNullableVariable(final PsiExpression expr) {
myNullableAssignments.add(expr);
}
@@ -147,6 +159,7 @@ public class StandardDataFlowRunner extends AnnotationsAwareDataFlowRunner {
|| !myCCEInstructions.isEmpty()
|| !getRedundantInstanceofs(this, visitor).isEmpty()
|| !myNullableArguments.isEmpty()
|| !myNullableArgumentsPassedToNonAnnotatedParam.isEmpty()
|| !myNullableAssignments.isEmpty()
|| !myNullableReturns.isEmpty()
|| !myUnboxedNullables.isEmpty();
@@ -56,6 +56,25 @@ public class StandardInstructionVisitor extends InstructionVisitor {
}
}
};
private final FactoryMap<MethodCallInstruction, boolean[]> myParametersNonAnnotated = new FactoryMap<MethodCallInstruction, boolean[]>() {
@Override
protected boolean[] create(MethodCallInstruction key) {
final PsiCallExpression callExpression = key.getCallExpression();
final PsiMethod callee = callExpression == null ? null : callExpression.resolveMethod();
if (callee != null) {
final PsiParameter[] params = callee.getParameterList().getParameters();
boolean[] result = new boolean[params.length];
final NullableNotNullManager notNullManager = NullableNotNullManager.getInstance(callee.getProject());
for (int i = 0; i < params.length; i++) {
result[i] = !notNullManager.isNotNull(params[i], false) && !notNullManager.isNullable(params[i], false);
}
return result;
}
else {
return ArrayUtil.EMPTY_BOOLEAN_ARRAY;
}
}
};
private final FactoryMap<MethodCallInstruction, Boolean> myCalleeNullability = new FactoryMap<MethodCallInstruction, Boolean>() {
@Override
protected Boolean create(MethodCallInstruction key) {
@@ -161,14 +180,22 @@ public class StandardInstructionVisitor extends InstructionVisitor {
public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
final PsiExpression[] args = instruction.getArgs();
final boolean[] parametersNotNull = myParametersNotNull.get(instruction);
final boolean[] nonAnnotated = myParametersNonAnnotated.get(instruction);
final DfaNotNullValue.Factory factory = runner.getFactory().getNotNullFactory();
for (int i = 0; i < args.length; i++) {
final DfaValue arg = memState.pop();
final int revIdx = args.length - i - 1;
if (args.length <= parametersNotNull.length && revIdx < parametersNotNull.length && parametersNotNull[revIdx] && !memState.applyNotNull(arg)) {
onPassingNullParameter(runner, args[revIdx]);
if (arg instanceof DfaVariableValue) {
memState.setVarValue((DfaVariableValue)arg, factory.create(((DfaVariableValue)arg).getVariableType()));
if (args.length <= parametersNotNull.length && revIdx < parametersNotNull.length) {
if (parametersNotNull[revIdx]) {
if (!memState.applyNotNull(arg)) {
onPassingNullParameter(runner, args[revIdx]);
if (arg instanceof DfaVariableValue) {
memState.setVarValue((DfaVariableValue)arg, factory.create(((DfaVariableValue)arg).getVariableType()));
}
}
}
else if (nonAnnotated[revIdx] && !memState.checkNotNullable(arg)) {
onPassingNullParameterToNonAnnotated(runner, args[revIdx]);
}
}
}
@@ -248,6 +275,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
protected void onUnboxingNullable(MethodCallInstruction instruction, DataFlowRunner runner) {}
protected void onPassingNullParameter(DataFlowRunner runner, PsiExpression arg) {}
protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {}
@Override
public DfaInstructionState[] visitBinop(BinopInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
@@ -92,15 +92,16 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
}
}
@NonNls public Options TOP_LEVEL_CLASS_OPTIONS = new Options("none", "");
@NonNls public Options INNER_CLASS_OPTIONS = new Options("none", "");
@NonNls public Options METHOD_OPTIONS = new Options("none", "@return@param@throws or @exception");
@NonNls public Options FIELD_OPTIONS = new Options("none", "");
public boolean IGNORE_DEPRECATED = false;
public boolean IGNORE_JAVADOC_PERIOD = true;
public boolean IGNORE_DUPLICATED_THROWS = false;
public boolean IGNORE_POINT_TO_ITSELF = false;
public String myAdditionalJavadocTags = "";
@NonNls public Options TOP_LEVEL_CLASS_OPTIONS = new Options("none", "");
@NonNls public Options INNER_CLASS_OPTIONS = new Options("none", "");
@NonNls public Options METHOD_OPTIONS = new Options("none", "@return@param@throws or @exception");
@NonNls public Options FIELD_OPTIONS = new Options("none", "");
public boolean IGNORE_DEPRECATED = false;
public boolean IGNORE_JAVADOC_PERIOD = true;
public boolean IGNORE_DUPLICATED_THROWS = false;
public boolean IGNORE_POINT_TO_ITSELF = false;
public boolean IGNORE_EMPTY_DESCRIPTIONS = false;
public String myAdditionalJavadocTags = "";
private static final Logger LOG = Logger.getInstance("com.intellij.codeInspection.javaDoc.JavaDocLocalInspection");
@@ -145,8 +146,8 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
private class MyChangeListener implements ChangeListener {
private final JCheckBox myCheckBox;
private final Options myOptions;
private final String myTagName;
private final Options myOptions;
private final String myTagName;
public MyChangeListener(JCheckBox checkBox, Options options, String tagName) {
myCheckBox = checkBox;
@@ -156,7 +157,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
public void stateChanged(ChangeEvent e) {
if (myCheckBox.isSelected()) {
if (!isTagRequired(myOptions,myTagName)) {
if (!isTagRequired(myOptions, myTagName)) {
myOptions.REQUIRED_TAGS += myTagName;
}
}
@@ -594,27 +595,29 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
}
}
for (PsiDocTag tag : tags) {
if ("param".equals(tag.getName())) {
final PsiElement[] dataElements = tag.getDataElements();
final PsiDocTagValue valueElement = tag.getValueElement();
boolean hasProblemsWithTag = dataElements.length < 2;
if (!hasProblemsWithTag) {
final StringBuilder buf = new StringBuilder();
for (PsiElement element : dataElements) {
if (element != valueElement){
buf.append(element.getText());
if (!IGNORE_EMPTY_DESCRIPTIONS) {
for (PsiDocTag tag : tags) {
if ("param".equals(tag.getName())) {
final PsiElement[] dataElements = tag.getDataElements();
final PsiDocTagValue valueElement = tag.getValueElement();
boolean hasProblemsWithTag = dataElements.length < 2;
if (!hasProblemsWithTag) {
final StringBuilder buf = new StringBuilder();
for (PsiElement element : dataElements) {
if (element != valueElement){
buf.append(element.getText());
}
}
hasProblemsWithTag = buf.toString().trim().length() == 0;
}
hasProblemsWithTag = buf.toString().trim().length() == 0;
}
if (hasProblemsWithTag) {
if (valueElement != null) {
problems.add(createDescriptor(valueElement,
InspectionsBundle.message("inspection.javadoc.method.problem.missing.tag.description", "<code>@param " + valueElement.getText() + "</code>"),
manager, isOnTheFly));
if (hasProblemsWithTag) {
if (valueElement != null) {
problems.add(createDescriptor(valueElement,
InspectionsBundle.message("inspection.javadoc.method.problem.missing.tag.description", "<code>@param " + valueElement.getText() + "</code>"),
manager, isOnTheFly));
}
}
}
}
}
@@ -661,7 +664,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
}
}
else
if ("return".equals(tag.getName())) {
if ("return".equals(tag.getName()) && !IGNORE_EMPTY_DESCRIPTIONS) {
if (extractTagDescription(tag).length() == 0) {
String message = InspectionsBundle.message("inspection.javadoc.method.problem.missing.tag.description", "<code>@return</code>");
ProblemDescriptor descriptor = manager.createProblemDescriptor(tag.getNameElement(), message, (LocalQuickFix)null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
@@ -694,10 +697,10 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
return false;
}
private static void processThrowsTags(final PsiDocTag[] tags,
final Map<PsiClassType, PsiClass> declaredExceptions,
final InspectionManager mananger,
@NotNull final ArrayList<ProblemDescriptor> problems, boolean isOnTheFly) {
private void processThrowsTags(final PsiDocTag[] tags,
final Map<PsiClassType, PsiClass> declaredExceptions,
final InspectionManager mananger,
@NotNull final ArrayList<ProblemDescriptor> problems, boolean isOnTheFly) {
for (PsiDocTag tag : tags) {
if ("throws".equals(tag.getName()) || "exception".equals(tag.getName())) {
final PsiDocTagValue value = tag.getValueElement();
@@ -714,7 +717,7 @@ public class JavaDocLocalInspection extends BaseLocalInspectionTool {
PsiClassType classType = it.next();
final PsiClass psiClass = declaredExceptions.get(classType);
if (InheritanceUtil.isInheritorOrSelf(exceptionClass, psiClass, true)) {
if (extractThrowsTagDescription(tag).length() == 0) {
if (!IGNORE_EMPTY_DESCRIPTIONS && extractThrowsTagDescription(tag).length() == 0) {
problems.add(createDescriptor(tag.getNameElement(), InspectionsBundle.message("inspection.javadoc.method.problem.missing.tag.description", "<code>" + tag.getName() + "</code>"), mananger,
isOnTheFly));
}
@@ -31,7 +31,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.search.GlobalSearchScope;
@@ -73,42 +72,6 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
checkNullableStuffForMethod(method, holder);
}
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
if (!PsiUtil.isLanguageLevel5OrHigher(expression) || !REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD) return;
final PsiMethod psiMethod = expression.resolveMethod();
if (psiMethod != null && (psiMethod.getManager().isInProject(psiMethod) || CodeStyleSettingsManager.getInstance().getCurrentSettings().USE_EXTERNAL_ANNOTATIONS)) {
final NullableNotNullManager nullableNotNullManager = NullableNotNullManager.getInstance(holder.getProject());
final PsiClass annotationsClass =
JavaPsiFacade.getInstance(holder.getProject()).findClass(nullableNotNullManager.getDefaultNullable(), psiMethod.getResolveScope());
if (annotationsClass == null) return;
final PsiParameterList parameterList = psiMethod.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
final PsiExpression[] expressions = expression.getArgumentList().getExpressions();
for (int i = 0, expressionsLength = expressions.length; i < Math.min(expressionsLength, parameters.length); i++) {
PsiExpression psiExpression = expressions[i];
boolean nullablePassedAsParameter = false;
if (psiExpression instanceof PsiMethodCallExpression) {
final PsiMethod method = expression.resolveMethod();
nullablePassedAsParameter = nullableNotNullManager.isNullable(method, false);
} else if (psiExpression instanceof PsiReferenceExpression) {
final PsiElement resolve = ((PsiReferenceExpression)psiExpression).resolve();
if (resolve instanceof PsiModifierListOwner) {
nullablePassedAsParameter = nullableNotNullManager.isNullable((PsiModifierListOwner)resolve, false);
}
}
final PsiType exprType = psiExpression.getType();
if (exprType == PsiType.NULL || nullablePassedAsParameter) {
final PsiParameter parameter = parameters[i];
if (!NullableNotNullManager.isNullable(parameter) && !NullableNotNullManager.isNotNull(parameter)) {
holder.registerProblem(psiExpression, "Nullable value is passed to parameter which is not yet @Nullable",
new MyAddNullableAnnotationFix(parameter));
}
}
}
}
}
@Override public void visitField(PsiField field) {
if (!PsiUtil.isLanguageLevel5OrHigher(field)) return;
final PsiType type = field.getType();
@@ -450,7 +413,6 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
private JCheckBox myNAMethodOverridesNN;
private JPanel myPanel;
private JCheckBox myReportNotAnnotatedGetter;
private JCheckBox myReportNullsPassedToNonAnnotatedParameter;
private JButton myConfigureAnnotationsButton;
private OptionsPanel() {
@@ -465,7 +427,6 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
myNAMethodOverridesNN.addActionListener(actionListener);
myNNParameterOverridesN.addActionListener(actionListener);
myReportNotAnnotatedGetter.addActionListener(actionListener);
myReportNullsPassedToNonAnnotatedParameter.addActionListener(actionListener);
myConfigureAnnotationsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -482,7 +443,6 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
myNNParameterOverridesN.setSelected(REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE);
myNAMethodOverridesNN.setSelected(REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL);
myReportNotAnnotatedGetter.setSelected(REPORT_NOT_ANNOTATED_GETTER);
myReportNullsPassedToNonAnnotatedParameter.setSelected(REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD);
}
private void apply() {
@@ -490,7 +450,6 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE = myNNParameterOverridesN.isSelected();
REPORT_NOT_ANNOTATED_GETTER = myReportNotAnnotatedGetter.isSelected();
REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL;
REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = myReportNullsPassedToNonAnnotatedParameter.isSelected();
}
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.codeInspection.nullable.NullableStuffInspection.OptionsPanel">
<grid id="cc1c9" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="cc1c9" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="69" y="57" width="634" height="235"/>
@@ -10,7 +10,7 @@
<children>
<vspacer id="c3eef">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="2f304" class="javax.swing.JCheckBox" binding="myReportNotAnnotatedGetter">
@@ -21,14 +21,6 @@
<text resource-bundle="messages/InspectionsBundle" key="inspection.nullable.problems.not.annotated.getters.for.annotated.fields"/>
</properties>
</component>
<component id="690c8" class="javax.swing.JCheckBox" binding="myReportNullsPassedToNonAnnotatedParameter" default-binding="true">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/InspectionsBundle" key="inspection.nullable.problems.non.annotated.passed.null"/>
</properties>
</component>
<component id="f4e37" class="javax.swing.JCheckBox" binding="myNNParameterOverridesN">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
@@ -47,7 +39,7 @@
</component>
<component id="ef852" class="javax.swing.JButton" binding="myConfigureAnnotationsButton" default-binding="true">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/InspectionsBundle" key="configure.annotations.option"/>
@@ -94,10 +94,10 @@ public class JavadocNavigationDelegate extends EditorNavigationDelegateAdapter {
return Result.CONTINUE;
}
return navigateToLineEnd(editor, project, psiFile);
return navigateToLineEnd(editor, psiFile);
}
public static Result navigateToLineEnd(@NotNull Editor editor, @NotNull Project project, @NotNull PsiFile psiFile) {
public static Result navigateToLineEnd(@NotNull Editor editor, @NotNull PsiFile psiFile) {
final Document document = editor.getDocument();
final CaretModel caretModel = editor.getCaretModel();
final int offset = caretModel.getOffset();
@@ -91,10 +91,11 @@ class AnonymousToInnerDialog extends DialogWrapper{
if (psiType instanceof PsiClassType) {
type = TypeConversionUtil.erasure(psiType);
}
if (type == null || type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) return "";
if (type instanceof PsiArrayType) {
type = type.getDeepComponentType();
}
return type.getPresentableText();
return StringUtil.getShortName(type.getPresentableText());
}
}, "") + name, "My" + name};
} else {
@@ -17,6 +17,7 @@ package com.intellij.refactoring.typeMigration;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
/**
* @author db
@@ -35,6 +36,7 @@ public class Util {
return parent;
}
@Nullable
public static PsiElement normalizeElement(final PsiElement element) {
if (element instanceof PsiMethod) {
final PsiMethod superMethod = ((PsiMethod)element).findDeepestSuperMethod();
@@ -42,6 +44,18 @@ public class Util {
return superMethod == null ? element : superMethod;
}
else if (element instanceof PsiParameter && element.getParent() instanceof PsiParameterList) {
final PsiElement declarationScope = ((PsiParameter)element).getDeclarationScope();
if (declarationScope instanceof PsiLambdaExpression) {
final PsiType interfaceType = ((PsiLambdaExpression)declarationScope).getFunctionalInterfaceType();
if (interfaceType != null) {
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType);
if (interfaceMethod != null) {
final int index = ((PsiParameterList)element.getParent()).getParameterIndex((PsiParameter)element);
return interfaceMethod.getParameterList().getParameters()[index];
}
}
return null;
}
final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
if (method != null) {
@@ -64,7 +78,7 @@ public class Util {
final PsiElement element = normalizeElement(e);
if (!element.getManager().isInProject(element)) {
if (element == null || !element.getManager().isInProject(element)) {
return false;
}
@@ -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.
@@ -13,10 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author max
*/
package com.intellij.psi;
import com.intellij.openapi.components.ServiceManager;
@@ -27,6 +23,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author max
*/
public abstract class JavaPsiFacade {
private static final NotNullLazyKey<JavaPsiFacade, Project> INSTANCE_KEY = ServiceManager.createLazyKey(JavaPsiFacade.class);
@@ -38,18 +37,6 @@ public abstract class JavaPsiFacade {
return getInstance(project).getElementFactory();
}
/**
* Searches the project and all its libraries for a class with the specified full-qualified
* name and returns one if it is found.
*
* @param qualifiedName the full-qualified name of the class to find.
* @return the PSI class, or null if no class with such name is found.
* @deprecated use {@link #findClass(String, com.intellij.psi.search.GlobalSearchScope)}
*/
@Nullable
public abstract PsiClass findClass(@NotNull @NonNls String qualifiedName);
/**
* Searches the specified scope within the project for a class with the specified full-qualified
* name and returns one if it is found.
@@ -61,7 +48,6 @@ public abstract class JavaPsiFacade {
@Nullable
public abstract PsiClass findClass(@NonNls @NotNull String qualifiedName, @NotNull GlobalSearchScope scope);
/**
* Searches the specified scope within the project for classes with the specified full-qualified
* name and returns all found classes.
@@ -94,8 +80,8 @@ public abstract class JavaPsiFacade {
/**
* Returns the factory for the project, which can be used to create instances of certain java constructs from their textual
* presentation. Elements created shall not be used to later interfer (like insert into) a PSI parsed from the user codebase
* since no formatting to the user codestyle will be performed in this case. Please use {@link #getElementFactory()} instead, which
* representation. Elements created shall not be used to later intermix (like insert into) a PSI parsed from the user codebase
* since no formatting to the user code style will be performed in this case. Please use {@link #getElementFactory()} instead, which
* provides exactly same methods but ensures created instances will get properly formatted.
* @return the parser facade.
*/
@@ -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,14 +22,24 @@ package com.intellij.psi.impl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
public abstract class JavaPsiFacadeEx extends JavaPsiFacade {
public static JavaPsiFacadeEx getInstanceEx(Project project) {
@TestOnly
public static JavaPsiFacadeEx getInstanceEx(@NotNull Project project) {
return (JavaPsiFacadeEx)getInstance(project);
}
@TestOnly
@Nullable
public PsiClass findClass(@NotNull String qualifiedName) {
return findClass(qualifiedName, GlobalSearchScope.allScope(getProject()));
}
@TestOnly
public abstract void setAssertOnFileLoadingFilter(@NotNull VirtualFileFilter filter);
}
@@ -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.
@@ -90,14 +90,6 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
JavaElementType.ANNOTATION.getIndex(); // Initialize stubs.
}
/**
* @deprecated
*/
@Override
public PsiClass findClass(@NotNull String qualifiedName) {
return findClass(qualifiedName, GlobalSearchScope.allScope(myProject));
}
@Override
public PsiClass findClass(@NotNull final String qualifiedName, @NotNull GlobalSearchScope scope) {
ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
@@ -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.
@@ -303,7 +303,9 @@ public class PsiSuperMethodImplUtil {
PsiSubstitutor superSubstitutor,
PsiSubstitutor derivedSubstitutor, boolean inRawContext) {
if (inRawContext) {
superSubstitutor = JavaPsiFacadeEx.getElementFactory(superClass.getProject()).createRawSubstitutor(derivedSubstitutor, superSubstitutor.getSubstitutionMap().keySet().toArray(PsiTypeParameter.EMPTY_ARRAY));
Set<PsiTypeParameter> typeParams = superSubstitutor.getSubstitutionMap().keySet();
PsiElementFactory factory = JavaPsiFacade.getElementFactory(superClass.getProject());
superSubstitutor = factory.createRawSubstitutor(derivedSubstitutor, typeParams.toArray(new PsiTypeParameter[typeParams.size()]));
}
Map<PsiTypeParameter, PsiType> map = null;
for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(superClass)) {
@@ -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.
@@ -203,7 +203,7 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this);
ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
final JavaPsiFacadeImpl facade = getFacade();
final JavaPsiFacade facade = getFacade();
final Condition<String> prefixMatcher = processor.getHint(JavaCompletionHints.NAME_FILTER);
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
@@ -295,8 +295,9 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
}
}
final JavaPsiFacadeImpl facade = getFacade();
for (PsiClass aClass : facade.findClasses(getQualifiedName() + ".package-info", allScope())) {
final JavaPsiFacade facade = getFacade();
final GlobalSearchScope scope = allScope();
for (PsiClass aClass : facade.findClasses(getQualifiedName() + ".package-info", scope)) {
ContainerUtil.addIfNotNull(aClass.getModifierList(), list);
}
@@ -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.
@@ -58,10 +58,9 @@ public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousC
@Override
@NotNull
public PsiJavaCodeReferenceElement getBaseClassReference() {
final PsiJavaCodeReferenceElement result =
(PsiJavaCodeReferenceElement)getNode().findChildByRoleAsPsiElement(ChildRole.BASE_CLASS_REFERENCE);
assert result != null;
return result;
final PsiElement baseRef = getFirstChild();
assert baseRef instanceof PsiJavaCodeReferenceElement : getText();
return (PsiJavaCodeReferenceElement)baseRef;
}
@Override
@@ -90,7 +89,7 @@ public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousC
type = factory.createType(ref);
}
catch (IncorrectOperationException e) {
type = PsiClassType.getJavaLangObject(getManager(), getResolveScope());
type = PsiType.getJavaLangObject(getManager(), getResolveScope());
}
myCachedBaseType = new PatchedSoftReference<PsiClassType>(type);
@@ -272,8 +272,11 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
PsiElement lastParent,
@NotNull PsiElement place) {
assert isValid();
if (processor instanceof ClassResolverProcessor && isPhysical() &&
// TODO den remove
boolean allowCaching = true;
if (allowCaching && processor instanceof ClassResolverProcessor && isPhysical() &&
(getUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING) == Boolean.TRUE || myResolveCache.hasUpToDateValue())) {
final ClassResolverProcessor hint = (ClassResolverProcessor)processor;
String name = hint.getName(state);
@@ -0,0 +1,20 @@
abstract class F<A, B> {
public abstract B f(A a);
public final F<A, P1<B>> lazy() {
return new F<A, P1<B>>() {
public P1<B> f(final A a) {
return null;
}
};
}
private class TestClient<A, B> extends F<A, P1<B>> {
public P1<B> f(final A a) {
return null;
}
}
}
class P1<T> {
}
@@ -0,0 +1,12 @@
Cleaning output files:
out/production/DeleteClassAfterCompileErrors/packageA/Server.class
End of files
Compiling files:
src/packageA/Server.java
End of files
Cleaning output files:
out/production/DeleteClassAfterCompileErrors/packageA/Client.class
End of files
Compiling files:
src/packageA/Client.java
End of files
@@ -0,0 +1,9 @@
package packageA;
public class Client {
public void method(Server server) {
server.method();
}
}
@@ -0,0 +1,7 @@
package packageA;
public class Server {
public void method() {
System.out.println("Server.method");
}
}
@@ -0,0 +1,7 @@
package packageA;
public class Server {
public void method() {
System.out.println("Server.method"); <some-error!>
}
}
@@ -9,7 +9,7 @@ public class BrokenAlignment {
System.out.println(data.getText().hashCode());
}
data = new Data(null, null);
data = new Data(null, <warning descr="Passing 'null' argument to non annotated parameter">null</warning>);
System.out.println(<warning descr="Method invocation 'data.getText().hashCode()' may produce 'java.lang.NullPointerException'">data.getText().hashCode()</warning>);
if (data.inner() != null) {
@@ -19,7 +19,7 @@ public class BrokenAlignment {
System.out.println(data.inner().hashCode());
}
data = new Data(null, null);
data = new Data(null, <warning descr="Passing 'null' argument to non annotated parameter">null</warning>);
System.out.println(<warning descr="Method invocation 'data.inner().hashCode()' may produce 'java.lang.NullPointerException'">data.inner().hashCode()</warning>);
}
}
@@ -6,7 +6,7 @@ public class BrokenAlignment {
System.out.println(data.text.hashCode());
}
data = new Data(null, null);
data = new Data(null, <warning descr="Passing 'null' argument to non annotated parameter">null</warning>);
System.out.println(<warning descr="Method invocation 'data.text.hashCode()' may produce 'java.lang.NullPointerException'">data.text.hashCode()</warning>);
if (data.inner != null) {
@@ -16,7 +16,7 @@ public class BrokenAlignment {
System.out.println(data.inner.hashCode());
}
data = new Data(null, null);
data = new Data(null, <warning descr="Passing 'null' argument to non annotated parameter">null</warning>);
System.out.println(<warning descr="Method invocation 'data.inner.hashCode()' may produce 'java.lang.NullPointerException'">data.inner.hashCode()</warning>);
}
}
@@ -148,6 +148,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA89771() throws Exception { doTest(false); }
public void testIDEA89801() throws Exception { doTest(false); }
public void testInconvertibleTypes() throws Exception { doTest(false); }
public void testIncompatibleReturnType() throws Exception { doTest(false); }
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
@@ -80,9 +80,418 @@ class Test {
}'''
)
}
void testRemoveOneParameterFromMany() {
doTest(
initial: '''\
class Test {
/**
* @param i
* @param j
* @param k
*/
void test(int i, int j) {<caret>
}
}''',
expected: '''\
class Test {
/**
* @param i <caret>
* @param j
*/
void test(int i, int j) {
}
}'''
)
}
void testRemoveTheOnlyParameter() {
doTest(
initial: '''\
class Test {
/**
* My description
* @param i
*/
void test() {<caret>
}
}''',
expected: '''\
class Test {
/**
* My description
*/
void test() {<caret>
}
}'''
)
}
void testRemoveReturn() {
doTest(
initial: '''\
class Test {
/**
* My description
* @return data
*/
void test() {<caret>
}
}''',
expected: '''\
class Test {
/**
* My description
*/
void test() {<caret>
}
}'''
)
}
void testRemoveOneThrowsFromMany() {
doTest(
initial: '''\
class MyException1 extends Exception {}
class MyException2 extends Exception {}
class Test {
/**
* @param i my arg
* @throws MyException1 text1
* @throws MyException2 text2
*/
void test(int i) throws MyException2 {<caret>
}
}''',
expected: '''\
class MyException1 extends Exception {}
class MyException2 extends Exception {}
class Test {
/**
* @param i my arg
* @throws MyException2 text2
*/
void test(int i) throws MyException2 {
}
}'''
)
}
void testRemoveTheOnlyThrows() {
doTest(
initial: '''\
class MyException extends Exception {}
class Test {
/**
* @param i my arg
* @throws MyException text
*/
void test(int i) {<caret>
}
}''',
expected: '''\
class MyException extends Exception {}
class Test {
/**
* @param i my arg
*/
void test(int i) {
}
}'''
)
}
void testRemoveOneTypeParameterFromMany() {
doTest(
initial: '''\
/**
* @param <T> tDescription
* @param <V> vDescription
*/
class Test<V> {<caret>
}''',
expected: '''\
/**
* @param <V> vDescription
*/
class Test<V> {<caret>
}'''
)
}
void testRemoveMultipleTypeParameter() {
doTest(
initial: '''\
/**
* @param <T> tDescription
* @param <V> vDescription
*/
class Test {<caret>
}''',
expected: '''\
/**
*/
class Test {<caret>
}'''
)
}
void testAddFirstParameter() {
doTest(
initial: '''\
class Test {
/**
*/
void test(int i) {<caret>
}
}''',
expected: '''\
class Test {
/**
* @param i <caret>
*/
void test(int i) {
}
}'''
)
}
void testAddMultipleParameter() {
doTest(
initial: '''\
class Test {
/**
* @param i
*/
void test(int i, int j, int k) {<caret>
}
}''',
expected: '''\
class Test {
/**
* @param i <caret>
* @param j
* @param k
*/
void test(int i, int j, int k) {
}
}'''
)
}
void testAddReturn() {
doTest(
initial: '''\
class Test {
/**
*/
int test() {<caret>
}
}''',
expected: '''\
class Test {
/**
* @return<caret>
*/
int test() {
}
}'''
)
}
void testAddFirstThrows() {
doTest(
initial: '''\
class MyException extends Exception {}
class Test {
/**
* @param i my arg
*/
void test(int i) throws MyException {<caret>
}
}''',
expected: '''\
class MyException extends Exception {}
class Test {
/**
* @param i my arg
* @throws MyException<caret>
*/
void test(int i) throws MyException {
}
}''')
}
void testAddNonFirstThrows() {
doTest(
initial: '''\
class MyException1 extends Exception {}
class MyException2 extends Exception {}
class MyException3 extends Exception {}
class Test {
/**
* @param i my arg
* @throws MyException1
*/
void test(int i) throws MyException1, MyException2, MyException3 {<caret>
}
}''',
expected: '''\
class MyException1 extends Exception {}
class MyException2 extends Exception {}
class MyException3 extends Exception {}
class Test {
/**
* @param i my arg
* @throws MyException1<caret>
* @throws MyException2
* @throws MyException3
*/
void test(int i) throws MyException1, MyException2, MyException3 {
}
}''')
}
void testAddFirstThrowsWhenEmptyReturnIsAvailable() {
doTest(
initial: '''\
class MyException extends Exception {}
class Test {
/**
* @return
*/
int test() throws MyException {<caret>
return 1;
}
}''',
expected: '''\
class MyException extends Exception {}
class Test {
/**
* @return<caret>
* @throws MyException
*/
int test() throws MyException {
return 1;
}
}''')
}
void testAddFirstTypeParameter() {
doTest(
initial: '''\
/**
* My description
* @author me
*/
class Test<T> {<caret>
}''',
expected: '''\
/**
* My description
* @author me
* @param <T> <caret>
*/
class Test<T> {
}''')
}
void testAddNonFirstTypeParameter() {
doTest(
initial: '''\
/**
* My description
* @author me
* @param <T> type description<caret>
*/
class Test<T, V> {
}''',
expected: '''\
/**
* My description
* @author me
* @param <T> type description
* @param <V> <caret>
*/
class Test<T, V> {
}''')
}
void _testCorrectParametersOrder() {
doTest(
initial: '''\
class Test {
/**
* @param j
* @param k k description
* @param i
*/
public void test(int i, int j, int k) {<caret>
}
}''',
expected: '''\
class Test {
/**
* @param i <caret>
* @param j
* @param k k description
*/
public void test(int i, int j, int k) {
}
}'''
)
}
void testCorrectTypeParametersOrder() {
// TODO den implement
}
void testAllesZusammen() {
// TODO den implement
}
void testNavigateToMissingParamDescription() {
doTest(
initial: '''\
class Test {
/**
* @param i
*/
void test(int i) {<caret>
}
}''',
expected: '''\
class Test {
/**
* @param i <caret>
*/
void test(int i) {
}
}'''
)
}
void testNavigateToMissingReturnDescription() {
// TODO den implement
}
void testNavigateToMissingThrowsDescription() {
// TODO den implement
}
private def doTest(Map args) {
configureFromFileText("${getTestName(false)}.java", args.initial)
myEditor.settings.virtualSpace = false
executeAction(FixDocCommentAction.ACTION_ID)
checkResultByText(args.expected)
}
@@ -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;
import com.intellij.JavaTestUtil;
@@ -48,8 +63,7 @@ public class LibraryOrderTest extends PsiTestCase {
public void testNavigation() throws Exception {
setupPaths();
final JavaPsiFacade psiManager = getJavaFacade();
final PsiClass classA = psiManager.findClass("test.A");
final PsiClass classA = getJavaFacade().findClass("test.A");
final PsiElement navigationElement = classA.getNavigationElement();
assertNotNull(navigationElement);
assertTrue(navigationElement != classA);
@@ -57,7 +71,7 @@ public class LibraryOrderTest extends PsiTestCase {
}
private void checkClassFromLib(String qualifiedName, String index) {
final PsiClass classA = (PsiClass)JavaPsiFacade.getInstance(myProject).findClass(qualifiedName).getNavigationElement();
final PsiClass classA = (PsiClass)getJavaFacade().findClass(qualifiedName).getNavigationElement();
assertNotNull(classA);
final PsiMethod[] methodsA = classA.getMethods();
assertEquals(1, methodsA.length);
@@ -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;
import com.intellij.openapi.application.ApplicationManager;
@@ -5,6 +20,7 @@ import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.impl.JavaPsiFacadeEx;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
import com.intellij.testFramework.PsiTestUtil;
@@ -34,7 +50,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testSimpleStuff() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -67,7 +83,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testRawTypes() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -93,7 +109,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testSubstWithInheritor() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -123,7 +139,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testSimpleRawTypeInMethodArg() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -156,8 +172,7 @@ public class TypesTest extends GenericsTestCase {
public void testRawTypeInMethodArg() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final PsiClass classA = psiManager.findClass("A");
final PsiClass classA = getJavaFacade().findClass("A");
assertNotNull(classA);
final PsiMethod method = classA.getMethods()[0];
@@ -172,7 +187,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testBoundedParams() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -191,7 +206,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testRawTypeExtension() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -210,7 +225,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testTypesInGenericClass() {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -226,8 +241,8 @@ public class TypesTest extends GenericsTestCase {
assertEquals(typeT, type);
}
public void testAssignableSubinheritor() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
public void testAssignableSubInheritor() throws Exception {
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classCollection = psiManager.findClass("test.Collection");
final PsiClass classList = psiManager.findClass("test.List");
@@ -242,7 +257,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testComplexInheritance() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -259,7 +274,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testListListInheritance() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -280,7 +295,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testSpaceInTypeParameterList() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -294,7 +309,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testMethodTypeParameter() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -325,7 +340,7 @@ public class TypesTest extends GenericsTestCase {
}
public void testRawArrayTypes() throws Exception {
final JavaPsiFacade psiManager = getJavaFacade();
final JavaPsiFacadeEx psiManager = getJavaFacade();
final PsiElementFactory factory = psiManager.getElementFactory();
final PsiClass classA = psiManager.findClass("A");
assertNotNull(classA);
@@ -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.impl.source.tree.java;
import com.intellij.openapi.application.ApplicationManager;
@@ -19,6 +34,7 @@ public class ExtendsBoundListTest extends LightCodeInsightTestCase {
check();
}
public void testRemoveBoundFromEnd() throws Exception {
final PsiTypeParameter typeParameter = getTypeParameter();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -30,6 +46,7 @@ public class ExtendsBoundListTest extends LightCodeInsightTestCase {
check();
}
public void testRemoveBoundFromMiddle() throws Exception {
final PsiTypeParameter typeParameter = getTypeParameter();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -45,20 +62,19 @@ public class ExtendsBoundListTest extends LightCodeInsightTestCase {
public void testAddBoundInTheMiddle() throws Exception {
final PsiTypeParameter typeParameter = getTypeParameter();
final PsiReferenceList extendsList = typeParameter.getExtendsList();
final JavaPsiFacade manager = getJavaFacade();
final PsiClass clonableClass = manager.findClass("java.lang.Cloneable");
assertNotNull(clonableClass);
final PsiJavaCodeReferenceElement reference = manager.getElementFactory().createClassReferenceElement(clonableClass);
final PsiClass cloneableClass = getJavaFacade().findClass("java.lang.Cloneable");
assertNotNull(cloneableClass);
final PsiJavaCodeReferenceElement reference = getJavaFacade().getElementFactory().createClassReferenceElement(cloneableClass);
extendsList.addAfter(reference, extendsList.getReferenceElements()[0]);
check();
}
public void testAddBoundInFront() throws Exception {
final PsiTypeParameter typeParameter = getTypeParameter();
final PsiReferenceList extendsList = typeParameter.getExtendsList();
final JavaPsiFacade manager = getJavaFacade();
final PsiClass clonableClass = manager.findClass("java.lang.Cloneable");
assertNotNull(clonableClass);
final PsiJavaCodeReferenceElement reference = manager.getElementFactory().createClassReferenceElement(clonableClass);
final PsiClass cloneableClass = getJavaFacade().findClass("java.lang.Cloneable");
assertNotNull(cloneableClass);
final PsiJavaCodeReferenceElement reference = getJavaFacade().getElementFactory().createClassReferenceElement(cloneableClass);
extendsList.addBefore(reference, extendsList.getReferenceElements()[0]);
check();
}
@@ -66,28 +82,23 @@ public class ExtendsBoundListTest extends LightCodeInsightTestCase {
public void testAddBoundInEnd() throws Exception {
final PsiTypeParameter typeParameter = getTypeParameter();
final PsiReferenceList extendsList = typeParameter.getExtendsList();
final JavaPsiFacade manager = getJavaFacade();
final PsiClass clonableClass = manager.findClass("java.lang.Cloneable");
assertNotNull(clonableClass);
final PsiJavaCodeReferenceElement reference = manager.getElementFactory().createClassReferenceElement(clonableClass);
final PsiClass cloneableClass = getJavaFacade().findClass("java.lang.Cloneable");
assertNotNull(cloneableClass);
final PsiJavaCodeReferenceElement reference = getJavaFacade().getElementFactory().createClassReferenceElement(cloneableClass);
extendsList.addBefore(reference, null);
check();
}
public void testAddBound() throws Exception {
final PsiTypeParameter typeParameter = getTypeParameter();
final PsiReferenceList extendsList = typeParameter.getExtendsList();
final JavaPsiFacade manager = getJavaFacade();
final PsiClass clonableClass = manager.findClass(CommonClassNames.JAVA_LANG_RUNNABLE);
assertNotNull(clonableClass);
final PsiJavaCodeReferenceElement reference = manager.getElementFactory().createClassReferenceElement(clonableClass);
final PsiClass cloneableClass = getJavaFacade().findClass(CommonClassNames.JAVA_LANG_RUNNABLE);
assertNotNull(cloneableClass);
final PsiJavaCodeReferenceElement reference = getJavaFacade().getElementFactory().createClassReferenceElement(cloneableClass);
extendsList.add(reference);
check();
}
private void check() throws Exception {
outputFile(getTestName(true) + "_after.java");
}
@@ -95,8 +106,7 @@ public class ExtendsBoundListTest extends LightCodeInsightTestCase {
private PsiTypeParameter getTypeParameter() throws Exception {
inputFile(getTestName(true) + ".java");
final PsiClass aClass = ((PsiJavaFile)getFile()).getClasses()[0];
final PsiTypeParameter typeParameter = aClass.getTypeParameters()[0];
return typeParameter;
return aClass.getTypeParameters()[0];
}
private void outputFile(String filename) throws Exception {
@@ -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.resolve;
import com.intellij.openapi.projectRoots.Sdk;
@@ -267,7 +282,7 @@ public class ResolveMethodTest extends ResolveTestCase {
PsiReference ref = configureByFile("method/" + getTestName(false) + ".java");
// just assume this is called by some highlighting inspection/intention/pass before the resolve
JavaPsiFacade.getInstance(getProject()).findClass("NN").getAllMethods();
getJavaFacade().findClass("NN").getAllMethods();
PsiElement target = ref.resolve();
assertInstanceOf(target, PsiMethod.class);
@@ -31,7 +31,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.JavaPsiFacadeImpl;
import com.intellij.psi.impl.JavaPsiFacadeEx;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.cache.impl.id.IdIndex;
import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
@@ -181,7 +181,7 @@ public class UpdateCacheTest extends PsiTestCase{
assertNotNull(myProject);
myPsiManager = (PsiManagerImpl) PsiManager.getInstance(myProject);
myJavaFacade = (JavaPsiFacadeImpl) JavaPsiFacade.getInstance(myProject);
myJavaFacade = JavaPsiFacadeEx.getInstanceEx(myProject);
objectClass = myJavaFacade.findClass(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(getProject()));
assertNotNull(objectClass);
@@ -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.refactoring;
import com.intellij.codeInsight.CodeInsightTestCase;
@@ -9,8 +24,8 @@ import com.intellij.testFramework.PsiTestUtil;
import org.jetbrains.annotations.Nullable;
/**
* User: anna
* Date: Aug 31, 2010
* @author anna
* @since Aug 31, 2010
*/
public class DndMoveTest extends CodeInsightTestCase {
@Override
@@ -23,7 +38,7 @@ public class DndMoveTest extends CodeInsightTestCase {
@Nullable
@Override
public PsiElement compute() {
return JavaPsiFacade.getInstance(getProject()).findClass("d.MyClass");
return getJavaFacade().findClass("d.MyClass");
}
}, true);
}
@@ -33,12 +48,11 @@ public class DndMoveTest extends CodeInsightTestCase {
@Nullable
@Override
public PsiElement compute() {
return JavaPsiFacade.getInstance(getProject()).findClass("d.Second");
return getJavaFacade().findClass("d.Second");
}
}, false);
}
private void doTest(final String targetDirName, final Computable<PsiElement> source, final boolean expected) throws Exception {
String testName = getTestName(true);
String root = getTestDataPath() + getTestRoot() + testName;
@@ -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.
*/
/*
* User: anna
* Date: 20-Aug-2008
@@ -138,7 +154,7 @@ public class IntroduceParameterObjectTest extends MultiFileTestCase{
@Override
public ParameterTablePanel.VariableData[] fun(PsiMethod psiMethod) {
final PsiParameter parameter = psiMethod.getParameterList().getParameters()[0];
final PsiClass collectionClass = JavaPsiFacade.getInstance(getProject()).findClass(CommonClassNames.JAVA_UTIL_COLLECTION);
final PsiClass collectionClass = getJavaFacade().findClass(CommonClassNames.JAVA_UTIL_COLLECTION);
final ParameterTablePanel.VariableData variableData =
new ParameterTablePanel.VariableData(parameter, JavaPsiFacade.getElementFactory(getProject()).createType(collectionClass));
variableData.name = parameter.getName();
@@ -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.
@@ -27,8 +27,8 @@ import org.jetbrains.annotations.NonNls;
import java.io.IOException;
/**
* User: anna
* Date: 11/4/11
* @author anna
* @since 11/4/11
*/
public class InlineLibraryMethodTest extends RefactoringTestCase {
@Override
@@ -45,7 +45,7 @@ public class InlineLibraryMethodTest extends RefactoringTestCase {
@NonNls String fileName = "/refactoring/inlineMethod/" + getTestName(false) + ".java";
configureByFile(fileName);
PsiClass fileClass = JavaPsiFacade.getInstance(getProject()).findClass("mycompany.File");
PsiClass fileClass = getJavaFacade().findClass("mycompany.File");
assertNotNull(fileClass);
final PsiFile file = fileClass.getContainingFile();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -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.
@@ -15,19 +15,17 @@
*/
package com.intellij.testFramework.fixtures;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.impl.JavaPsiFacadeEx;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
/**
* @author yole
*/
public interface JavaCodeInsightTestFixture extends CodeInsightTestFixture {
JavaPsiFacade getJavaFacade();
JavaPsiFacadeEx getJavaFacade();
PsiClass addClass(@NotNull @NonNls final String classText);
@@ -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.
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.JavaPsiFacadeEx;
import com.intellij.psi.impl.PsiModificationTrackerImpl;
import com.intellij.psi.search.ProjectScope;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
@@ -36,9 +37,9 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i
}
@Override
public JavaPsiFacade getJavaFacade() {
public JavaPsiFacadeEx getJavaFacade() {
assertInitialized();
return JavaPsiFacade.getInstance(getProject());
return JavaPsiFacadeEx.getInstanceEx(getProject());
}
@Override
+1 -1
View File
@@ -15,7 +15,7 @@
<orderEntry type="module" module-name="lang-api" exported="" />
<orderEntry type="module" module-name="lang-impl" exported="" />
<orderEntry type="module" module-name="compiler-impl" />
<orderEntry type="module" module-name="java-impl" />
<orderEntry type="module" module-name="java-impl" exported="" />
<orderEntry type="module" module-name="execution-impl" exported="" scope="RUNTIME" />
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="module" module-name="testFramework" exported="" />
@@ -821,7 +821,7 @@ public class IncProjectBuilder {
if (!outputs.isEmpty()) {
context.processMessage(new FileDeletedEvent(outputs));
}
srcToOut.remove(srcPath);
srcToOut.update(srcPath, Collections.<String>emptyList());
}
return true;
}
@@ -2,10 +2,10 @@ package org.jetbrains.jps.incremental.artifacts;
import com.intellij.util.SmartList;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.IOUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.jps.incremental.storage.AbstractStateStorage;
import org.jetbrains.jps.incremental.storage.PathStringDescriptor;
import java.io.*;
import java.util.List;
@@ -42,7 +42,7 @@ public class ArtifactOutputToSourceMapping extends AbstractStateStorage<String,
};
public ArtifactOutputToSourceMapping(@NonNls File storePath) throws IOException {
super(storePath, new EnumeratorStringDescriptor(), EXTERNALIZER);
super(storePath, new PathStringDescriptor(), EXTERNALIZER);
}
public static class SourcePathAndRootIndex {
@@ -3,6 +3,7 @@ package org.jetbrains.jps.incremental.artifacts;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.CompileContext;
@@ -17,7 +18,10 @@ import org.jetbrains.jps.incremental.storage.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
/**
* @author nik
@@ -61,22 +65,22 @@ public class ArtifactSourceFilesState extends CompositeStorageOwner {
configuration.save();
}
else if (fsState.markInitialScanPerformed(myTarget)) {
final Set<String> currentPaths = new HashSet<String>();
final Set<File> currentPaths = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
fsState.clearDeletedPaths(myTarget);
markDirtyFiles(builder, dataManager, currentPaths, false);
final SourceToOutputMapping mapping = dataManager.getSourceToOutputMap(myTarget);
final Iterator<String> iterator = mapping.getKeysIterator();
while (iterator.hasNext()) {
String path = iterator.next();
File file = new File(path);
if (!currentPaths.contains(path)) {
File file = new File(FileUtil.toSystemDependentName(path));
if (!currentPaths.contains(file)) {
fsState.registerDeleted(myTarget, file, myProjectDescriptor.timestamps.getStorage());
}
}
}
}
private void markDirtyFiles(ArtifactInstructionsBuilder builder, BuildDataManager dataManager, @Nullable Set<String> currentPaths,
private void markDirtyFiles(ArtifactInstructionsBuilder builder, BuildDataManager dataManager, @Nullable Set<File> currentPaths,
final boolean forceMarkDirty) throws IOException {
for (Pair<ArtifactRootDescriptor, DestinationInfo> pair : builder.getInstructions()) {
ArtifactRootDescriptor descriptor = pair.getFirst();
@@ -89,7 +93,7 @@ public class ArtifactSourceFilesState extends CompositeStorageOwner {
}
private void processRecursively(File file, ArtifactRootDescriptor descriptor, BuildDataManager dataManager, SourceFileFilter filter,
@Nullable Set<String> currentPaths, final boolean forceMarkDirty) throws IOException {
@Nullable Set<File> currentPaths, final boolean forceMarkDirty) throws IOException {
final String filePath = FileUtil.toSystemIndependentName(FileUtil.toCanonicalPath(file.getPath()));
if (!filter.accept(filePath, dataManager)) return;
@@ -103,7 +107,7 @@ public class ArtifactSourceFilesState extends CompositeStorageOwner {
}
else {
if (currentPaths != null) {
currentPaths.add(filePath);
currentPaths.add(file);
}
if (forceMarkDirty || myProjectDescriptor.timestamps.getStorage().getStamp(file, myTarget) != FileSystemUtil.lastModified(file)) {
myProjectDescriptor.fsState.markDirty(null, file, descriptor, myProjectDescriptor.timestamps.getStorage());
@@ -100,7 +100,7 @@ public class IncArtifactBuilder extends ProjectLevelBuilder {
}
}
Set<String> changedOutputPaths = new THashSet<String>();
Set<String> changedOutputPaths = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
for (Map.Entry<BuildRootDescriptor, Set<File>> entry : filesToRecompile.entrySet()) {
int rootIndex = ((ArtifactRootDescriptor)entry.getKey()).getRootIndex();
for (File file : entry.getValue()) {
@@ -110,6 +110,7 @@ public class IncArtifactBuilder extends ProjectLevelBuilder {
if (outputPaths != null) {
changedOutputPaths.addAll(outputPaths);
for (String outputPath : outputPaths) {
filesToDelete.putValue(outputPath, sourcePath);
final List<ArtifactOutputToSourceMapping.SourcePathAndRootIndex> sources = outSrcMapping.getState(outputPath);
if (sources != null) {
for (ArtifactOutputToSourceMapping.SourcePathAndRootIndex source : sources) {
@@ -177,7 +178,7 @@ public class IncArtifactBuilder extends ProjectLevelBuilder {
}
Set<String> paths = filesToProcess.get(rootIndex);
if (paths == null) {
paths = new THashSet<String>();
paths = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
filesToProcess.put(rootIndex, paths);
}
paths.add(path);
@@ -190,8 +191,8 @@ public class IncArtifactBuilder extends ProjectLevelBuilder {
context.processMessage(new ProgressMessage("Deleting outdated files..."));
int notDeletedFilesCount = 0;
final THashSet<String> notDeletedPaths = new THashSet<String>();
final THashSet<String> deletedPaths = new THashSet<String>();
final THashSet<String> notDeletedPaths = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
final THashSet<String> deletedPaths = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
for (String filePath : filesToDelete.keySet()) {
if (notDeletedPaths.contains(filePath)) {
@@ -16,13 +16,16 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/** @noinspection SynchronizationOnLocalVariableOrMethodParameter*/
final class FilesDelta {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.fs.FilesDelta");
private final Set<String> myDeletedPaths = Collections.synchronizedSet(new HashSet<String>());
private final Set<String> myDeletedPaths = Collections.synchronizedSet(new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY));
private final Map<BuildRootDescriptor, Set<File>> myFilesToRecompile = Collections.synchronizedMap(new HashMap<BuildRootDescriptor, Set<File>>());
public void save(DataOutput out) throws IOException {
@@ -155,7 +158,9 @@ final class FilesDelta {
public Set<String> getAndClearDeletedPaths() {
synchronized (myDeletedPaths) {
try {
return new HashSet<String>(myDeletedPaths);
final THashSet<String> _paths = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
_paths.addAll(myDeletedPaths);
return _paths;
}
finally {
myDeletedPaths.clear();
@@ -0,0 +1,19 @@
package org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.EnumeratorStringDescriptor;
/**
* @author nik
*/
public class PathStringDescriptor extends EnumeratorStringDescriptor {
@Override
public int getHashCode(String value) {
return FileUtil.pathHashCode(value);
}
@Override
public boolean isEqual(String val1, String val2) {
return FileUtil.pathsEqual(val1, val2);
}
}
@@ -2,7 +2,6 @@ package org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.IOUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -22,17 +21,7 @@ import java.util.List;
public final class SourceToOutputMapping extends AbstractStateStorage<String, Collection<String>> {
public SourceToOutputMapping(File storePath) throws IOException {
super(storePath, new EnumeratorStringDescriptor() {
@Override
public int getHashCode(String value) {
return FileUtil.pathHashCode(value);
}
@Override
public boolean isEqual(String val1, String val2) {
return FileUtil.pathsEqual(val1, val2);
}
}, new StringCollectionExternalizer());
super(storePath, new PathStringDescriptor(), new StringCollectionExternalizer());
}
@Override
@@ -36,6 +36,12 @@ public class CommonTest extends IncrementalTestCase {
doTest();
}
public void testDeleteClassAfterCompileErrors() throws Exception {
setupInitialProject();
doTestBuild(2);
}
public void testDeleteClassPackageDoesntMatchRoot() throws Exception {
doTest();
}
@@ -97,12 +97,15 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
}
}
private void modify() {
private void modify(int stage) {
final String removedSuffix = stage == 0? ".remove" : ".remove" + stage;
final String newSuffix = stage == 0? ".new" : ".new" + stage;
FileUtil.processFilesRecursively(baseDir, new Processor<File>() {
@Override
public boolean process(File file) {
if (file.getName().endsWith(".remove")) {
FileUtil.delete(getTargetFile(file, ".remove"));
if (file.getName().endsWith(removedSuffix)) {
FileUtil.delete(getTargetFile(file, removedSuffix));
}
return true;
}
@@ -111,8 +114,8 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
@Override
public boolean process(File file) {
try {
if (file.getName().endsWith(".new")) {
FileUtil.copyContent(file, getTargetFile(file, ".new"));
if (file.getName().endsWith(newSuffix)) {
FileUtil.copyContent(file, getTargetFile(file, newSuffix));
}
}
catch (IOException e) {
@@ -121,6 +124,13 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
return true;
}
});
if (Utils.TIMESTAMP_ACCURACY > 1) {
try {
Thread.sleep(Utils.TIMESTAMP_ACCURACY);
}
catch (InterruptedException ignored) {
}
}
}
private File getTargetFile(File sourceFile, final String suffix) {
@@ -133,6 +143,12 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
}
public BuildResult doTest() {
setupInitialProject();
return doTestBuild(1);
}
protected void setupInitialProject() {
if (new File(workDir, ".idea").exists()) {
getOrCreateJdk();
loadProject(workDir.getAbsolutePath());
@@ -140,8 +156,6 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
else {
addModule();
}
return doTestBuild();
}
protected JpsModule addModule() {
@@ -153,30 +167,31 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
return addModule(moduleName, new String[]{srcPath}, null, getOrCreateJdk());
}
protected BuildResult doTestBuild() {
final TestJavaBuilderLogger
javaBuilderLogger = new TestJavaBuilderLogger(FileUtil.toSystemIndependentName(workDir.getAbsolutePath()) + "/");
final ProjectDescriptor
projectDescriptor = createProjectDescriptor(new BuildLoggingManager(new ArtifactBuilderLoggerImpl(), javaBuilderLogger));
protected BuildResult doTestBuild(int makesCount) {
final TestJavaBuilderLogger builderLogger = new TestJavaBuilderLogger(FileUtil.toSystemIndependentName(workDir.getAbsolutePath()) + "/");
final ProjectDescriptor pd = createProjectDescriptor(new BuildLoggingManager(new ArtifactBuilderLoggerImpl(), builderLogger));
try {
doBuild(projectDescriptor, createAllModulesScope(true), false, true, false).assertSuccessful();
doBuild(pd, createAllModulesScope(true), false, true, false).assertSuccessful();
modify();
if (Utils.TIMESTAMP_ACCURACY > 1) {
try {
Thread.sleep(Utils.TIMESTAMP_ACCURACY);
}
catch (InterruptedException ignored) {
}
BuildResult result = null;
for (int idx = 0; idx < makesCount; idx++) {
modify(idx);
result = doBuild(pd, createAllModulesScope(false), true, false, false);
}
BuildResult result = doBuild(projectDescriptor, createAllModulesScope(false), true, false, false);
assertNotNull(result);
final ByteArrayOutputStream makeDump = new ByteArrayOutputStream();
if (result.isSuccessful()) {
projectDescriptor.dataManager.getMappings().toStream(new PrintStream(makeDump));
final PrintStream stream = new PrintStream(makeDump);
try {
pd.dataManager.getMappings().toStream(stream);
}
finally {
stream.close();
}
}
makeDump.close();
@@ -186,19 +201,25 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
logFile = new File(baseDir, "build.log");
}
final String expected = StringUtil.convertLineSeparators(FileUtil.loadFile(logFile));
final String actual = javaBuilderLogger.myLog.toString();
final String actual = builderLogger.myLog.toString();
assertEquals(expected, actual);
if (result.isSuccessful()) {
doBuild(projectDescriptor, createAllModulesScope(true), false, true, false).assertSuccessful();
doBuild(pd, createAllModulesScope(true), false, true, false).assertSuccessful();
final ByteArrayOutputStream rebuildDump = new ByteArrayOutputStream();
projectDescriptor.dataManager.getMappings().toStream(new PrintStream(rebuildDump));
final PrintStream stream = new PrintStream(rebuildDump);
try {
pd.dataManager.getMappings().toStream(stream);
}
finally {
stream.close();
}
rebuildDump.close();
assertEquals(rebuildDump.toString(), makeDump.toString());
}
return result;
@@ -207,7 +228,7 @@ public abstract class IncrementalTestCase extends JpsBuildTestCase {
throw new RuntimeException(e);
}
finally {
projectDescriptor.release();
pd.release();
}
}
@@ -26,7 +26,7 @@ public class MarkDirtyTest extends IncrementalTestCase {
addTestRoot(module, "testSrc");
JpsLibrary library = addLibrary("lib/a.jar");
JpsModuleRootModificationUtil.addDependency(module, library, JpsJavaDependencyScope.TEST, false);
doTestBuild().assertSuccessful();
doTestBuild(1).assertSuccessful();
}
public void testTransitiveRecompile() {
@@ -38,6 +38,6 @@ public class MarkDirtyTest extends IncrementalTestCase {
JpsModule lib = addModule("lib", "lib/src");
addTestRoot(lib, "lib/testSrc");
JpsModuleRootModificationUtil.addDependency(util, lib);
doTestBuild().assertSuccessful();
doTestBuild(1).assertSuccessful();
}
}
@@ -28,7 +28,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase {
change(aFile, "a2");
buildAll();
assertCopied("aaa.txt");
assertDeletedAndCopied("out/artifacts/a/x.jar", "aaa.txt");
assertOutput(a, fs().archive("x.jar").file("aaa.txt", "a2"));
buildAllAndAssertUpToDate();
@@ -55,7 +55,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase {
change(cFile, "c2");
buildAll();
assertCopied("c.txt");
assertDeletedAndCopied("out/artifacts/a/a.jar", "c.txt");
assertOutput(a, fs().archive("a.jar").archive("b.jar").file("c.txt", "c2"));
buildAllAndAssertUpToDate();
@@ -74,7 +74,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase {
change(xFile, "2");
buildAll();
assertCopied("x.txt");
assertDeletedAndCopied("out/artifacts/a/junit.jar", "x.txt");
assertOutput(a, fs().archive("junit.jar").file("x.txt", "2"));
buildAllAndAssertUpToDate();
@@ -99,7 +99,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase {
change(jarFile, "321");
buildAll();
assertCopied("lib/jdom.jar");
assertDeletedAndCopied("out/artifacts/a/jdom.jar", "lib/jdom.jar");
assertOutput(a, fs().file("jdom.jar", "321"));
buildAllAndAssertUpToDate();
@@ -122,7 +122,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase {
change(firstFile, "first2");
buildAll();
assertCopied("d1/xxx.txt");
assertDeletedAndCopied("out/artifacts/a/ddd/xxx.txt", "d1/xxx.txt");
assertOutput(a, fs().dir("ddd").file("xxx.txt", "first2"));
buildAllAndAssertUpToDate();
@@ -170,7 +170,7 @@ public class ArtifactBuilderOverwriteTest extends ArtifactBuilderTestCase {
final String manifestText2 = "Manifest-Version: 1.0\r\nMain-Class: B\r\n\r\n";
change(manifest, manifestText2);
buildAll();
assertCopied("d/MANIFEST.MF", "a.txt");
assertDeletedAndCopied("out/artifacts/a/a.jar", "d/MANIFEST.MF", "a.txt");
assertOutput(a, fs().archive("a.jar").dir("META-INF").file("MANIFEST.MF", manifestText2).file("a.txt"));
buildAllAndAssertUpToDate();
@@ -27,7 +27,10 @@ import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.JpsBuildTestCase;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.BuildLoggingManager;
import org.jetbrains.jps.incremental.CompileScope;
import org.jetbrains.jps.incremental.CompileScopeImpl;
import org.jetbrains.jps.incremental.Utils;
import org.jetbrains.jps.incremental.java.JavaBuilderLoggerImpl;
import org.jetbrains.jps.model.JpsDummyElement;
import org.jetbrains.jps.model.JpsElementFactory;
@@ -211,7 +214,11 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase {
}
protected void assertDeletedAndCopied(String deletedPath, String... copiedPaths) {
assertSameElements(myArtifactBuilderLogger.myDeletedFilePaths, deletedPath);
assertDeletedAndCopied(new String[]{deletedPath}, copiedPaths);
}
protected void assertDeletedAndCopied(String[] deletedPaths, String... copiedPaths) {
assertSameElements(myArtifactBuilderLogger.myDeletedFilePaths, deletedPaths);
assertSameElements(myArtifactBuilderLogger.myCopiedFilePaths, copiedPaths);
}
@@ -248,7 +255,10 @@ public abstract class ArtifactBuilderTestCase extends JpsBuildTestCase {
try {
File file = new File(FileUtil.toSystemDependentName(path));
assertTrue("File " + file.getAbsolutePath() + " doesn't exist", file.exists());
FileUtil.rename(file, new File(file.getParentFile(), newName));
final File tempFile = new File(file.getParentFile(), "__" + newName);
FileUtil.rename(file, tempFile);
FileUtil.copyContent(tempFile, new File(file.getParentFile(), newName));
FileUtil.delete(tempFile);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -37,7 +37,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase {
change(file1, "xxx");
buildAll();
assertCopied("dir/a.txt");
assertDeletedAndCopied("out/artifacts/a/a.txt", "dir/a.txt");
assertOutput(a, fs().file("a.txt", "xxx").file("b.txt", "bbb"));
buildAllAndAssertUpToDate();
}
@@ -66,7 +66,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase {
change(file1, "xxx");
buildAll();
assertCopied("dir/a.txt", "dir/b.txt");
assertDeletedAndCopied("out/artifacts/a/a.jar", "dir/a.txt", "dir/b.txt");
assertOutput(a, fs().archive("a.jar").file("a.txt", "xxx").file("b.txt", "bbb"));
buildAllAndAssertUpToDate();
}
@@ -96,9 +96,9 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase {
buildAllAndAssertUpToDate();
change(file);
buildArtifacts(a1); assertCopied("file.txt");
buildArtifacts(a1); assertDeletedAndCopied("out/artifacts/a1/dir/file.txt", "file.txt");
buildArtifacts(a1); assertUpToDate();
buildArtifacts(a2); assertCopied("file.txt");
buildArtifacts(a2); assertDeletedAndCopied("out/artifacts/a2/dir2/file.txt", "file.txt");
buildArtifacts(a2); assertUpToDate();
buildArtifacts(a1); assertUpToDate();
buildAllAndAssertUpToDate();
@@ -115,7 +115,7 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase {
buildAll();
change(file1);
buildAll();
assertCopied("a/a.txt");
assertDeletedAndCopied("out/artifacts/a/x.jar", "a/a.txt");
}
public void testRenameFile() throws Exception {
@@ -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.
@@ -35,12 +35,7 @@ import java.util.List;
public class IElementType {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.tree.IElementType");
public static final short FIRST_TOKEN_INDEX = 1;
private static short ourCounter = FIRST_TOKEN_INDEX;
private static final short MAX_INDEXED_TYPES = 15000;
private static final List<IElementType> ourRegistry = new ArrayList<IElementType>(700);
private final short myIndex;
public static final IElementType[] EMPTY_ARRAY = new IElementType[0];
/**
* Default enumeration predicate which matches all token types.
@@ -54,34 +49,16 @@ public class IElementType {
}
};
static int getAllocatedTypesCount() {
return ourCounter;
}
public static final short FIRST_TOKEN_INDEX = 1;
public static final short MAX_INDEXED_TYPES = 15000;
public static final IElementType[] EMPTY_ARRAY = new IElementType[0];
private final String myDebugName;
private static short ourCounter = FIRST_TOKEN_INDEX;
private static final List<IElementType> ourRegistry = new ArrayList<IElementType>(700);
private final short myIndex;
@NotNull private final String myDebugName;
@NotNull private final Language myLanguage;
/**
* Enumerates all registered token types which match the specified predicate.
*
* @param p the predicate which should be matched by the element types.
* @return the array of matching element types.
*/
public static IElementType[] enumerate(Predicate p) {
List<IElementType> matches = new ArrayList<IElementType>();
IElementType[] copy;
synchronized (ourRegistry) {
copy = ourRegistry.toArray(new IElementType[ourRegistry.size()]);
}
for (IElementType value : copy) {
if (p.matches(value)) {
matches.add(value);
}
}
return matches.toArray(new IElementType[matches.size()]);
}
/**
* Creates and registers a new element type for the specified language.
*
@@ -92,7 +69,7 @@ public class IElementType {
this(debugName, language, true);
}
protected IElementType(String debugName, Language language, final boolean register) {
protected IElementType(@NotNull @NonNls String debugName, @Nullable Language language, boolean register) {
myDebugName = debugName;
myLanguage = language == null ? Language.ANY : language;
if (register) {
@@ -132,15 +109,41 @@ public class IElementType {
return myDebugName;
}
/**
* Controls whitespace balancing behavior of PsiBuilder.
* <p>By default, empty composite elements (containing no children) are bounded to the right (previous) neighbour, forming following tree:
* <pre>
* [previous_element]
* [whitespace]
* [empty_element]
* &lt;empty&gt;
* [next_element]
* </pre>
* <p>Left-bound elements are bounded to the left (next) neighbour instead:
* <pre>
* [previous_element]
* [empty_element]
* &lt;empty&gt;
* [whitespace]
* [next_element]
* </pre>
* <p>See com.intellij.lang.impl.PsiBuilderImpl.prepareLightTree() for details.
* @return true if empty elements of this type should be bound to the left.
*/
public boolean isLeftBound() {
return false;
}
/**
* Returns the element type registered at the specified index.
*
* @param idx the index for which the element type should be returned.
* @return the element type at the specified index.
* @throws IndexOutOfBoundsException if the index is out of registered elements' range.
*/
public static IElementType find(short idx) {
synchronized (ourRegistry) {
if (idx == 0) return ourRegistry.get(0); // We've changed FIRST_TOKEN_INDEX from 0 to 1. This is just for old plugins to avoid crashes.
if (idx == 0) return ourRegistry.get(0); // We've changed FIRST_TOKEN_INDEX from 0 to 1. This is just for old plugins to avoid crashes.
return ourRegistry.get(idx - FIRST_TOKEN_INDEX);
}
}
@@ -154,28 +157,29 @@ public class IElementType {
boolean matches(IElementType type);
}
static short getAllocatedTypesCount() {
return ourCounter;
}
/**
* Controls whitespace balancing behavior of PsiBuilder.
* <p>By default, empty composite elements (containing no children) are bounded to the right neighbour, forming following tree:
* <pre>
* [previous_element]
* [whitespace]
* [empty_element]
* &lt;empty&gt;
* [next_element]
* </pre>
* <p>Left-bound elements are bounded to the left neighbour instead:
* <pre>
* [previous_element]
* [empty_element]
* &lt;empty&gt;
* [whitespace]
* [next_element]
* </pre>
* <p>See {@linkplain com.intellij.lang.impl.PsiBuilderImpl#prepareLightTree()} for details.
* @return true if empty elements of this type should be bound to the left.
* Enumerates all registered token types which match the specified predicate.
*
* @param p the predicate which should be matched by the element types.
* @return the array of matching element types.
*/
public boolean isLeftBound() {
return false;
@NotNull
public static IElementType[] enumerate(@NotNull Predicate p) {
IElementType[] copy;
synchronized (ourRegistry) {
copy = ourRegistry.toArray(new IElementType[ourRegistry.size()]);
}
List<IElementType> matches = new ArrayList<IElementType>();
for (IElementType value : copy) {
if (p.matches(value)) {
matches.add(value);
}
}
return matches.toArray(new IElementType[matches.size()]);
}
}
@@ -16,6 +16,9 @@
package com.intellij.psi.tree;
import com.intellij.openapi.diagnostic.LogUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
@@ -23,51 +26,105 @@ import java.util.Arrays;
* A set of element types.
*/
public class TokenSet {
public static final TokenSet EMPTY = new TokenSet();
public static final TokenSet EMPTY = new TokenSet(Short.MAX_VALUE, (short)0) {
@Override public boolean contains(IElementType t) { return false; }
};
private final boolean[] mySet = new boolean[IElementType.getAllocatedTypesCount()] ;
private final short myShift, myMax, myTop;
private final long[] myWords;
private volatile IElementType[] myTypes;
private TokenSet(short shift, short max) {
myShift = shift;
myMax = max;
myTop = IElementType.getAllocatedTypesCount();
final int size = (max >> 6) + 1 - shift;
myWords = size > 0 ? new long[size] : ArrayUtil.EMPTY_LONG_ARRAY;
}
private boolean get(int index) {
final int wordIndex = (index >> 6) - myShift;
return wordIndex >= 0 && wordIndex < myWords.length && (myWords[wordIndex] & (1l << index)) != 0;
}
/**
* Checks if the specified element type is contained in the set.
*
* @param t the element type to search for.
* @return true if the element type is found in the set, false otherwise.
*/
public boolean contains(@Nullable IElementType t) {
if (t == null) return false;
final short i = t.getIndex();
return 0 <= i && i <= myMax && get(i);
}
/**
* Returns the array of element types contained in the set.
*
* @return the contents of the set.
*/
@NotNull
public IElementType[] getTypes() {
IElementType[] types = myTypes;
if (types == null) {
int elementCount = 0;
for (boolean bit : mySet) {
if (bit) elementCount++;
}
types = new IElementType[elementCount];
int count = 0;
for (short i = IElementType.FIRST_TOKEN_INDEX; i < mySet.length; i++) {
if (mySet[i]) {
types[count++] = IElementType.find(i);
if (types == null) {
if (myWords.length > 0) {
int elementCount = 0;
for (long word : myWords) {
elementCount += Long.bitCount(word);
}
types = new IElementType[elementCount];
int count = 0;
for (short i = (short)(myShift << 6); i <= myMax; i++) {
if (get(i)) {
types[count++] = IElementType.find(i);
}
}
}
else {
types = IElementType.EMPTY_ARRAY;
}
myTypes = types;
}
return types;
}
@Override
public String toString() {
return Arrays.toString(getTypes());
}
/**
* Returns a new token set containing the specified element types.
*
* @param types the element types contained in the set.
* @return the new token set.
*/
@NotNull
public static TokenSet create(IElementType... types) {
TokenSet set = new TokenSet();
if (types.length == 0) return EMPTY;
short min = Short.MAX_VALUE, max = 0;
for (IElementType type : types) {
if (type != null) {
final short index = type.getIndex();
assert index >= 0 : "Unregistered elements are not allowed here: " + LogUtil.objectAndClass(type);
set.mySet[index] = true;
if (min > index) min = index;
if (max < index) max = index;
}
}
final short shift = (short)(min >> 6);
final TokenSet set = new TokenSet(shift, max);
for (IElementType type : types) {
if (type != null) {
final short index = type.getIndex();
final int wordIndex = (index >> 6) - shift;
set.myWords[wordIndex] |= (1l << index);
}
}
return set;
@@ -79,12 +136,21 @@ public class TokenSet {
* @param sets the token sets to unite.
* @return the new token set.
*/
public static TokenSet orSet(TokenSet... sets) {
TokenSet newSet = new TokenSet();
@NotNull
public static TokenSet orSet(@NotNull TokenSet... sets) {
if (sets.length == 0) return EMPTY;
short shift = sets[0].myShift, max = sets[0].myMax;
for (int i = 1; i < sets.length; i++) {
if (shift > sets[i].myShift) shift = sets[i].myShift;
if (max < sets[i].myMax) max = sets[i].myMax;
}
final TokenSet newSet = new TokenSet(shift, max);
for (TokenSet set : sets) {
for (int i = 0; i < newSet.mySet.length; i++) {
if (i >= set.mySet.length) break;
newSet.mySet[i] |= set.mySet[i];
final int shiftDiff = set.myShift - newSet.myShift;
for (int i = 0; i < set.myWords.length; i++) {
newSet.myWords[i + shiftDiff] |= set.myWords[i];
}
}
return newSet;
@@ -97,51 +163,47 @@ public class TokenSet {
* @param b the second token set to intersect.
* @return the new token set.
*/
public static TokenSet andSet(TokenSet a, TokenSet b) {
TokenSet set = new TokenSet();
final boolean[] aSet = a.mySet;
final boolean[] bSet = b.mySet;
final boolean[] newSet = set.mySet;
final int aLen = aSet.length;
final int bLen = bSet.length;
final int andSize = Math.max(newSet.length, Math.max(aLen, bLen));
for (int i = 0; i < andSize; i++) {
newSet[i] = (i < aLen && aSet[i]) && (i < bLen && bSet[i]);
@NotNull
public static TokenSet andSet(@NotNull TokenSet a, @NotNull TokenSet b) {
final TokenSet newSet = new TokenSet((short)Math.min(a.myShift, b.myShift), (short)Math.max(a.myMax, b.myMax));
for (int i = 0; i < newSet.myWords.length; i++) {
final int ai = newSet.myShift - a.myShift + i, bi = newSet.myShift - b.myShift + i;
newSet.myWords[i] = (0 <= ai && ai < a.myWords.length ? a.myWords[ai] : 0l) & (0 <= bi && bi < b.myWords.length ? b.myWords[bi] : 0l);
}
return set;
return newSet;
}
/**
* Checks if the specified element type is contained in the set.
* Returns a token set containing a result of "set subtraction" of set B from set A.
*
* @param t the element type to search for.
* @return true if the element type is found in the set, false otherwise.
* @param a the basic token set.
* @param b the token set to subtract.
* @return the new token set.
*/
public boolean contains(IElementType t) {
if (t == null) return false;
final short i = t.getIndex();
return 0 <= i && i < mySet.length && mySet[i];
}
public TokenSet minus(TokenSet t) {
TokenSet set = new TokenSet();
for (int i = 0; i < mySet.length; i++) {
set.mySet [i] = mySet [i] && (i >= t.mySet.length || !t.mySet[i]);
@NotNull
public static TokenSet andNot(@NotNull TokenSet a, @NotNull TokenSet b) {
final TokenSet newSet = new TokenSet((short)Math.min(a.myShift, b.myShift), (short)Math.max(a.myMax, b.myMax));
for (int i = 0; i < newSet.myWords.length; i++) {
final int ai = newSet.myShift - a.myShift + i, bi = newSet.myShift - b.myShift + i;
newSet.myWords[i] = (0 <= ai && ai < a.myWords.length ? a.myWords[ai] : 0l) & ~(0 <= bi && bi < b.myWords.length ? b.myWords[bi] : 0l);
}
return set;
return newSet;
}
public static TokenSet not(TokenSet t) {
TokenSet set = new TokenSet();
for (int i = 0; i < t.mySet.length; i++) {
set.mySet [i] = (i >= t.mySet.length || !t.mySet[i]);
/** @deprecated please use {@linkplain #andNot(TokenSet, TokenSet)} (to remove in IDEA 13) */
@SuppressWarnings("UnusedDeclaration")
public TokenSet minus(@NotNull TokenSet t) {
return andNot(this, t);
}
/** @deprecated please use {@linkplain IElementType#enumerate(com.intellij.psi.tree.IElementType.Predicate)} (to remove in IDEA 13) */
@SuppressWarnings("UnusedDeclaration")
public static TokenSet not(@NotNull TokenSet set) {
final TokenSet newSet = new TokenSet((short)0, set.myTop);
for (int i = 0; i < newSet.myWords.length; i++) {
final long word = i >= set.myShift ? set.myWords[(i - set.myShift)] : 0l;
newSet.myWords[i] = ~word;
}
return set;
}
@Override
public String toString() {
return Arrays.asList(getTypes()).toString();
return newSet;
}
}
@@ -17,8 +17,8 @@
package com.intellij.application.options.editor;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.CompositeConfigurable;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -35,7 +35,7 @@ public class AutoImportOptionsConfigurable extends CompositeConfigurable<AutoImp
@Override
protected List<AutoImportOptionsProvider> createConfigurables() {
return AbstractConfigurableEP.createConfigurables(AutoImportOptionsProviderEP.EP_NAME);
return ConfigurableWrapper.createConfigurables(AutoImportOptionsProviderEP.EP_NAME);
}
@Override
@@ -16,7 +16,7 @@
package com.intellij.application.options.editor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
/**
* Register implementation of {@link AutoImportOptionsProvider} in the plugin.xml to provide additional options in Editor | Auto Import section:
@@ -29,6 +29,6 @@ import com.intellij.openapi.options.AbstractConfigurableEP;
*
* @author nik
*/
public class AutoImportOptionsProviderEP extends AbstractConfigurableEP<AutoImportOptionsProvider> {
public class AutoImportOptionsProviderEP extends ConfigurableEP<AutoImportOptionsProvider> {
public static final ExtensionPointName<AutoImportOptionsProviderEP> EP_NAME = ExtensionPointName.create("com.intellij.autoImportOptionsProvider");
}
@@ -23,9 +23,9 @@ import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.CompositeConfigurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.Nls;
@@ -110,7 +110,7 @@ public class CodeFoldingConfigurable extends CompositeConfigurable<CodeFoldingOp
@Override
protected List<CodeFoldingOptionsProvider> createConfigurables() {
return AbstractConfigurableEP.createConfigurables(CodeFoldingOptionsProviderEP.EP_NAME);
return ConfigurableWrapper.createConfigurables(CodeFoldingOptionsProviderEP.EP_NAME);
}
@Override
@@ -16,7 +16,7 @@
package com.intellij.application.options.editor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
/**
* Register implementation of {@link CodeFoldingOptionsProvider} in the plugin.xml to provide additional options in Editor | Code Folding section:
@@ -29,6 +29,6 @@ import com.intellij.openapi.options.AbstractConfigurableEP;
* @author nik
*/
public class CodeFoldingOptionsProviderEP extends AbstractConfigurableEP<CodeFoldingOptionsProvider> {
public class CodeFoldingOptionsProviderEP extends ConfigurableEP<CodeFoldingOptionsProvider> {
public static final ExtensionPointName<CodeFoldingOptionsProviderEP> EP_NAME = ExtensionPointName.create("com.intellij.codeFoldingOptionsProvider");
}
@@ -24,10 +24,8 @@ import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.CompositeConfigurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -194,7 +192,7 @@ public class EditorAppearanceConfigurable extends CompositeConfigurable<UnnamedC
@Override
protected List<UnnamedConfigurable> createConfigurables() {
return AbstractConfigurableEP.createConfigurables(EP_NAME);
return ConfigurableWrapper.createConfigurables(EP_NAME);
}
@Override
@@ -15,7 +15,7 @@
*/
package com.intellij.application.options.editor;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
import com.intellij.openapi.options.UnnamedConfigurable;
/**
@@ -30,5 +30,5 @@ import com.intellij.openapi.options.UnnamedConfigurable;
*
* @author nik
*/
public class EditorAppearanceConfigurableEP extends AbstractConfigurableEP<UnnamedConfigurable> {
public class EditorAppearanceConfigurableEP extends ConfigurableEP<UnnamedConfigurable> {
}
@@ -17,29 +17,16 @@
package com.intellij.application.options.editor;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
public class EditorOptions implements SearchableConfigurable.Parent {
public class EditorOptions implements SearchableConfigurable {
@NonNls public static final String ID = "preferences.editor";
private EditorOptionsPanel myEditorOptionsPanel;
private Configurable[] myChildren;
@Override
public Configurable[] getConfigurables() {
if (myChildren == null) {
final List<EditorOptionsProvider> configurables = AbstractConfigurableEP.createConfigurables(EditorOptionsProviderEP.EP_NAME);
myChildren = configurables.toArray(new EditorOptionsProvider[configurables.size()]);
}
return myChildren;
}
@Override
public String getDisplayName() {
@@ -62,16 +49,6 @@ public class EditorOptions implements SearchableConfigurable.Parent {
return null;
}
@Override
public boolean hasOwnContent() {
return true;
}
@Override
public boolean isVisible() {
return true;
}
@Override
public JComponent createComponent() {
myEditorOptionsPanel = new EditorOptionsPanel();
@@ -100,6 +77,5 @@ public class EditorOptions implements SearchableConfigurable.Parent {
@Override
public void disposeUIResources() {
myEditorOptionsPanel = null;
}
}
@@ -16,7 +16,7 @@
package com.intellij.application.options.editor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
/**
* Register implementation of {@link EditorOptionsProvider} in the plugin.xml to provide sub-section of Editor section in the Settings dialog:
@@ -29,6 +29,6 @@ import com.intellij.openapi.options.AbstractConfigurableEP;
*
* @author nik
*/
public class EditorOptionsProviderEP extends AbstractConfigurableEP<EditorOptionsProvider> {
public class EditorOptionsProviderEP extends ConfigurableEP<EditorOptionsProvider> {
public static final ExtensionPointName<EditorOptionsProviderEP> EP_NAME = ExtensionPointName.create("com.intellij.editorOptionsProvider");
}
@@ -25,10 +25,8 @@ import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.CompositeConfigurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -96,7 +94,7 @@ public class EditorSmartKeysConfigurable extends CompositeConfigurable<UnnamedCo
@Override
protected List<UnnamedConfigurable> createConfigurables() {
return AbstractConfigurableEP.createConfigurables(EP_NAME);
return ConfigurableWrapper.createConfigurables(EP_NAME);
}
@Override
@@ -15,7 +15,7 @@
*/
package com.intellij.application.options.editor;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
import com.intellij.openapi.options.UnnamedConfigurable;
/**
@@ -30,5 +30,5 @@ import com.intellij.openapi.options.UnnamedConfigurable;
*
* @author nik
*/
public class EditorSmartKeysConfigurableEP extends AbstractConfigurableEP<UnnamedConfigurable> {
public class EditorSmartKeysConfigurableEP extends ConfigurableEP<UnnamedConfigurable> {
}
@@ -17,8 +17,8 @@
package com.intellij.application.options.editor;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.profile.codeInspection.ui.ErrorOptionsProvider;
import com.intellij.profile.codeInspection.ui.ErrorOptionsProviderEP;
@@ -35,7 +35,7 @@ public class ErrorHighlightingPanel {
private final List<ErrorOptionsProvider> myExtensions;
public ErrorHighlightingPanel() {
myExtensions = AbstractConfigurableEP.createConfigurables(ErrorOptionsProviderEP.EP_NAME);
myExtensions = ConfigurableWrapper.createConfigurables(ErrorOptionsProviderEP.EP_NAME);
for (ErrorOptionsProvider optionsProvider : myExtensions) {
myErrorsPanel.add(optionsProvider.createComponent());
}
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.documentation;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiComment;
import org.jetbrains.annotations.NotNull;
/**
* @author Denis Zhdanov
* @since 9/20/12 8:37 PM
*/
public interface DocCommentFixer {
LanguageExtension<DocCommentFixer> EXTENSION = new LanguageExtension<DocCommentFixer>("com.intellij.lang.documentationFixer");
// TODO den add doc
void fixComment(@NotNull Project project, @NotNull Editor editor, @NotNull PsiComment comment);
}
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.documentation.DocCommentFixer;
import com.intellij.lang.*;
import com.intellij.lang.documentation.CodeDocumentationProvider;
import com.intellij.lang.documentation.CompositeDocumentationProvider;
@@ -104,20 +105,33 @@ public class FixDocCommentAction extends EditorAction {
return;
}
final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)c;
final Runnable task;
if (pair.second == null || pair.second.getTextRange().isEmpty()) {
task = new Runnable() {
@Override
public void run() {
generateComment(pair.first, editor, docProvider, commenter, project);
}
};
}
else {
final DocCommentFixer fixer = DocCommentFixer.EXTENSION.forLanguage(language);
if (fixer == null) {
return;
}
else {
task = new Runnable() {
@Override
public void run() {
fixer.fixComment(project, editor, pair.second);
}
};
}
}
final Runnable command = new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
if (pair.second == null || pair.second.getTextRange().isEmpty()) {
generateComment(pair.first, editor, docProvider, commenter, project);
}
else {
fixCommentIfNecessary(pair.second);
}
}
});
ApplicationManager.getApplication().runWriteAction(task);
}
};
CommandProcessor.getInstance().executeCommand(project, command, "Fix documentation", null);
@@ -246,8 +260,4 @@ public class FixDocCommentAction extends EditorAction {
}
return result;
}
private static void fixCommentIfNecessary(@NotNull PsiComment docComment) {
// TODO den implement
}
}
@@ -76,6 +76,7 @@ public class RunConfigurationsComboBoxAction extends ComboBoxAction implements D
if (DumbService.getInstance(project).isDumb()) {
presentation.setEnabled(false);
presentation.setText("");
presentation.setIcon(null);
}
else {
updateButton(ExecutionTargetManager.getActiveTarget(project),
@@ -23,90 +23,33 @@ import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.RunContentManager;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.TaskInfo;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListItemDescriptor;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.StatusBarEx;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.ui.components.JBList;
import com.intellij.util.NotNullFunction;
import com.intellij.ui.popup.list.GroupedItemsListRenderer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class StopAction extends DumbAwareAction implements AnAction.TransparentUpdate {
public void actionPerformed(final AnActionEvent e) {
final DataContext dataContext = e.getDataContext();
ProcessHandler processHandler = getHandler(dataContext);
if ((processHandler == null || processHandler.isProcessTerminated()) && ActionPlaces.MAIN_MENU.equals(e.getPlace())) {
final Collection<HandlerItem> handlerItems = getItemsList(getActiveDescriptors(dataContext));
if (!handlerItems.isEmpty()) {
final JBList list = new JBList(handlerItems);
list.installCellRenderer(new NotNullFunction<HandlerItem, JComponent>() {
final JLabel label = new JLabel();
@NotNull
public JComponent fun(HandlerItem item) {
label.setIcon(item.icon);
label.setIconTextGap(6);
label.setText(item.displayName);
return label;
}
});
final PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list);
final String title = handlerItems.size() == 1? "Confirm process stop" : "Select process to stop";
final JBPopup popup = builder.setTitle(title).setItemChoosenCallback(new Runnable() {
public void run() {
final HandlerItem item = (HandlerItem)list.getSelectedValue();
if (item != null) {
performAction(item.handler);
}
}
}).setRequestFocus(true).createPopup();
popup.showInBestPositionFor(dataContext);
}
}
if(processHandler != null) {
performAction(processHandler);
}
}
private static Collection<HandlerItem> getItemsList(List<RunContentDescriptor> descriptors) {
if (descriptors.isEmpty()) {
return Collections.emptyList();
}
final ArrayList<HandlerItem> items = new ArrayList<HandlerItem>();
for (RunContentDescriptor descriptor : descriptors) {
final ProcessHandler handler = descriptor.getProcessHandler();
if (handler != null) {
items.add(new HandlerItem(handler, descriptor.getDisplayName(), descriptor.getIcon()));
}
}
return items;
}
private static void performAction(ProcessHandler processHandler) {
if (processHandler instanceof KillableProcess && processHandler.isProcessTerminating()) {
((KillableProcess)processHandler).killProcess();
return;
}
if(processHandler.detachIsDefault()) {
processHandler.detachProcess();
}
else {
processHandler.destroyProcess();
}
}
public void update(final AnActionEvent e) {
boolean enable = false;
Icon icon = getTemplatePresentation().getIcon();
@@ -114,14 +57,7 @@ public class StopAction extends DumbAwareAction implements AnAction.TransparentU
final Presentation presentation = e.getPresentation();
if (ActionPlaces.MAIN_MENU.equals(e.getPlace())) {
final List<RunContentDescriptor> descriptors = getActiveDescriptors(e.getDataContext());
for (RunContentDescriptor descriptor : descriptors) {
final ProcessHandler handler = descriptor.getProcessHandler();
if (handler != null && !handler.isProcessTerminated()) {
enable = true;
break;
}
}
enable = !getCancellableProcesses(e.getProject()).isEmpty() || !getActiveDescriptors(e.getDataContext()).isEmpty();
}
else {
final ProcessHandler processHandler = getHandler(e.getDataContext());
@@ -142,6 +78,144 @@ public class StopAction extends DumbAwareAction implements AnAction.TransparentU
presentation.setDescription(description);
}
public void actionPerformed(final AnActionEvent e) {
final DataContext dataContext = e.getDataContext();
ProcessHandler activeProcessHandler = getHandler(dataContext);
List<Pair<TaskInfo, ProgressIndicator>> backgroundTasks = getCancellableProcesses(e.getProject());
if (ActionPlaces.MAIN_MENU.equals(e.getPlace())) {
if (activeProcessHandler != null && !activeProcessHandler.isProcessTerminating() && !activeProcessHandler.isProcessTerminated()
&& backgroundTasks.isEmpty()) {
stopProcess(activeProcessHandler);
return;
}
Pair<List<HandlerItem>, HandlerItem>
handlerItems = getItemsList(backgroundTasks, getActiveDescriptors(dataContext), activeProcessHandler);
if (handlerItems.first.isEmpty()) return;
final JBList list = new JBList(handlerItems.first);
if (handlerItems.second != null) list.setSelectedValue(handlerItems.second, true);
list.setCellRenderer(new GroupedItemsListRenderer(new ListItemDescriptor() {
@Nullable
@Override
public String getTextFor(Object value) {
return value instanceof HandlerItem ? ((HandlerItem)value).displayName : null;
}
@Nullable
@Override
public String getTooltipFor(Object value) {
return null;
}
@Nullable
@Override
public Icon getIconFor(Object value) {
return value instanceof HandlerItem ? ((HandlerItem)value).icon : null;
}
@Override
public boolean hasSeparatorAboveOf(Object value) {
return value instanceof HandlerItem && ((HandlerItem)value).hasSeparator;
}
@Nullable
@Override
public String getCaptionAboveOf(Object value) {
return null;
}
}));
final PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list);
final JBPopup popup = builder
.setMovable(true)
.setTitle(handlerItems.first.size() == 1 ? "Confirm process stop" : "Stop process")
.setFilteringEnabled(new Function<Object, String>() {
@Override
public String fun(Object o) {
return ((HandlerItem)o).displayName;
}
})
.setItemChoosenCallback(new Runnable() {
public void run() {
HandlerItem item = (HandlerItem)list.getSelectedValue();
if (item != null) item.stop();
}
}).setRequestFocus(true).createPopup();
popup.showCenteredInCurrentWindow(e.getProject());
}
else {
if (activeProcessHandler != null) {
stopProcess(activeProcessHandler);
}
}
}
private static List<Pair<TaskInfo, ProgressIndicator>> getCancellableProcesses(Project project) {
IdeFrame frame = ((WindowManagerEx)WindowManager.getInstance()).findFrameFor(project);
StatusBarEx statusBar = frame == null ? null : (StatusBarEx)frame.getStatusBar();
if (statusBar == null) return Collections.emptyList();
return ContainerUtil.findAll(statusBar.getBackgroundProcesses(),
new Condition<Pair<TaskInfo, ProgressIndicator>>() {
@Override
public boolean value(Pair<TaskInfo, ProgressIndicator> pair) {
return pair.first.isCancellable() && !pair.second.isCanceled();
}
});
}
private static Pair<List<HandlerItem>, HandlerItem> getItemsList(List<Pair<TaskInfo, ProgressIndicator>> tasks,
List<RunContentDescriptor> descriptors,
ProcessHandler activeProcessHandler) {
if (tasks.isEmpty() && descriptors.isEmpty()) return Pair.create(Collections.<HandlerItem>emptyList(), null);
ArrayList<HandlerItem> items = new ArrayList<HandlerItem>(tasks.size() + descriptors.size());
HandlerItem selected = null;
for (RunContentDescriptor descriptor : descriptors) {
final ProcessHandler handler = descriptor.getProcessHandler();
if (handler != null) {
HandlerItem item = new HandlerItem(descriptor.getDisplayName(), descriptor.getIcon(), false) {
@Override
void stop() {
stopProcess(handler);
}
};
items.add(item);
if (handler == activeProcessHandler) selected = item;
}
}
boolean hasSeparator = true;
for (final Pair<TaskInfo, ProgressIndicator> eachPair : tasks) {
items.add(new HandlerItem(eachPair.first.getTitle(), AllIcons.Process.Step_passive, hasSeparator) {
@Override
void stop() {
eachPair.second.cancel();
}
});
hasSeparator = false;
}
return Pair.<List<HandlerItem>, HandlerItem>create(items, selected);
}
private static void stopProcess(ProcessHandler processHandler) {
if (processHandler instanceof KillableProcess && processHandler.isProcessTerminating()) {
((KillableProcess)processHandler).killProcess();
return;
}
if (processHandler.detachIsDefault()) {
processHandler.detachProcess();
}
else {
processHandler.destroyProcess();
}
}
@Nullable
private static ProcessHandler getHandler(final DataContext dataContext) {
final RunContentDescriptor contentDescriptor = RunContentManager.RUN_CONTENT_DESCRIPTOR.getData(dataContext);
@@ -153,8 +227,9 @@ public class StopAction extends DumbAwareAction implements AnAction.TransparentU
else {
// main menu toolbar
final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
final RunContentDescriptor selectedContent = project == null? null : ExecutionManager.getInstance(project).getContentManager().getSelectedContent();
processHandler = selectedContent == null? null : selectedContent.getProcessHandler();
final RunContentDescriptor selectedContent =
project == null ? null : ExecutionManager.getInstance(project).getContentManager().getSelectedContent();
processHandler = selectedContent == null ? null : selectedContent.getProcessHandler();
}
return processHandler;
}
@@ -172,27 +247,28 @@ public class StopAction extends DumbAwareAction implements AnAction.TransparentU
final List<RunContentDescriptor> activeDescriptors = new ArrayList<RunContentDescriptor>();
for (RunContentDescriptor descriptor : runningProcesses) {
final ProcessHandler processHandler = descriptor.getProcessHandler();
if (processHandler != null && !processHandler.isProcessTerminated()) {
if (processHandler != null && !processHandler.isProcessTerminating() && !processHandler.isProcessTerminated()) {
activeDescriptors.add(descriptor);
}
}
return activeDescriptors;
}
private static class HandlerItem {
private final ProcessHandler handler;
private final String displayName;
private final Icon icon;
private abstract static class HandlerItem {
final String displayName;
final Icon icon;
final boolean hasSeparator;
private HandlerItem(final ProcessHandler processHandler, final String displayName1, Icon icon) {
this.handler = processHandler;
displayName = displayName1;
private HandlerItem(String displayName, Icon icon, boolean hasSeparator) {
this.displayName = displayName;
this.icon = icon;
this.hasSeparator = hasSeparator;
}
public String toString() {
return displayName;
}
}
abstract void stop();
}
}
@@ -28,8 +28,8 @@ import com.intellij.openapi.module.Module;
*
* @author nik
*/
public class ModuleConfigurableEP extends AbstractConfigurableEP<Configurable> {
public class ModuleConfigurableEP extends ConfigurableEP<Configurable> {
public ModuleConfigurableEP(Module module) {
super(module.getPicoContainer());
super(module.getPicoContainer(), null);
}
}
@@ -19,42 +19,54 @@ package com.intellij.openapi.projectRoots.impl;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.ui.HtmlListCellRenderer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColoredListCellRendererWrapper;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author yole
*/
public class SdkListCellRenderer extends HtmlListCellRenderer<Sdk> {
private String myNullText = "";
private boolean myShowHomePath;
public class SdkListCellRenderer extends ColoredListCellRendererWrapper<Sdk> {
private final String myNullText;
private final boolean myShowHomePath;
public SdkListCellRenderer(final ListCellRenderer listCellRenderer) {
super();
public SdkListCellRenderer(@NotNull String nullText) {
this(nullText, false);
}
public SdkListCellRenderer(final String nullText, final ListCellRenderer listCellRenderer) {
super();
myNullText = nullText;
}
public SdkListCellRenderer(final String nullText, final boolean showHomePath, final ListCellRenderer listCellRenderer) {
super();
public SdkListCellRenderer(@NotNull String nullText, boolean showHomePath) {
myNullText = nullText;
myShowHomePath = showHomePath;
}
/** @deprecated use {@linkplain #SdkListCellRenderer(String)} (to remove in IDEA 13) */
@SuppressWarnings("UnusedDeclaration")
public SdkListCellRenderer(final ListCellRenderer listCellRenderer) {
this("");
}
/** @deprecated use {@linkplain #SdkListCellRenderer(String)} (to remove in IDEA 13) */
@SuppressWarnings("UnusedDeclaration")
public SdkListCellRenderer(final String nullText, final ListCellRenderer listCellRenderer) {
this(nullText);
}
/** @deprecated use {@linkplain #SdkListCellRenderer(String, boolean)} (to remove in IDEA 13) */
@SuppressWarnings("UnusedDeclaration")
public SdkListCellRenderer(final String nullText, final boolean showHomePath, final ListCellRenderer listCellRenderer) {
this(nullText, showHomePath);
}
@Override
protected void doCustomize(final JList list, final Sdk sdk, final int index, final boolean selected, final boolean hasFocus) {
if (sdk != null) {
// icon
setIcon(getSdkIcon(sdk));
// text
append(sdk.getName());
if (myShowHomePath) {
append(" (" + FileUtil.toSystemDependentName(sdk.getHomePath()) + ")",
append(" (" + FileUtil.toSystemDependentName(StringUtil.notNullize(sdk.getHomePath())) + ")",
selected ? SimpleTextAttributes.REGULAR_ATTRIBUTES : SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
}
@@ -16,7 +16,7 @@
package com.intellij.profile.codeInspection.ui;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
/**
* Register implementation of {@link ErrorOptionsProvider} in the plugin.xml to provide additional options in Editor | "Error highlighting" section:
@@ -29,6 +29,6 @@ import com.intellij.openapi.options.AbstractConfigurableEP;
*
* @author nik
*/
public class ErrorOptionsProviderEP extends AbstractConfigurableEP<ErrorOptionsProvider> {
public class ErrorOptionsProviderEP extends ConfigurableEP<ErrorOptionsProvider> {
public static final ExtensionPointName<ErrorOptionsProviderEP> EP_NAME = ExtensionPointName.create("com.intellij.errorOptionsProvider");
}
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.rename.inplace;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.impl.FinishMarkAction;
import com.intellij.openapi.command.impl.StartMarkAction;
@@ -105,7 +106,9 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer {
return super.getNameIdentifier();
}
if (currentFile != null) {
final PsiElement elementAt = currentFile.findElementAt(myEditor.getCaretModel().getOffset());
int offset = myEditor.getCaretModel().getOffset();
offset = TargetElementUtilBase.adjustOffset(myEditor.getDocument(), offset);
final PsiElement elementAt = currentFile.findElementAt(offset);
if (elementAt != null) {
final PsiElement referenceExpression = elementAt.getParent();
if (referenceExpression != null) {
@@ -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.
@@ -156,7 +156,7 @@ public abstract class AbstractTreeNode<T> extends PresentableNodeDescriptor impl
}
@Nullable
public String toTestString(Queryable.PrintInfo printInfo) {
public String toTestString(@Nullable Queryable.PrintInfo printInfo) {
if (getValue() instanceof Queryable) {
String text = Queryable.Util.print((Queryable)getValue(), printInfo, this);
if (text != null) return text;
@@ -47,9 +47,9 @@ import org.jetbrains.annotations.Nullable;
*/
public interface Configurable extends UnnamedConfigurable {
ExtensionPointName<ConfigurableEP> APPLICATION_CONFIGURABLE = ExtensionPointName.create("com.intellij.applicationConfigurable");
ExtensionPointName<ConfigurableEP<Configurable>> APPLICATION_CONFIGURABLE = ExtensionPointName.create("com.intellij.applicationConfigurable");
ExtensionPointName<ConfigurableEP> PROJECT_CONFIGURABLE = ExtensionPointName.create("com.intellij.projectConfigurable");
ExtensionPointName<ConfigurableEP<Configurable>> PROJECT_CONFIGURABLE = ExtensionPointName.create("com.intellij.projectConfigurable");
/**
* Returns the user-visible name of the settings component.
@@ -39,7 +39,7 @@ import java.util.ResourceBundle;
* @see Configurable
*/
@Tag("configurable")
public class ConfigurableEP extends AbstractExtensionPointBean {
public class ConfigurableEP<T extends UnnamedConfigurable> extends AbstractExtensionPointBean {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.ConfigurableEP");
@Attribute("displayName")
@@ -53,6 +53,7 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
public String getDisplayName() {
if (displayName != null) return displayName;
LOG.assertTrue(bundle != null, "Bundle missed for " + instanceClass);
final ResourceBundle resourceBundle = AbstractBundle.getResourceBundle(bundle, myPluginDescriptor.getPluginClassLoader());
return displayName = CommonBundle.message(resourceBundle, key);
}
@@ -61,11 +62,20 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
@AbstractCollection(surroundWithTag = false)
public ConfigurableEP[] children;
/**
* Extension point of ConfigurableEP type to calculate children
*/
@Attribute("childrenEPName")
public String childrenEPName;
@Attribute("parentId")
public String parentId;
public ConfigurableEP[] getChildren() {
for (ConfigurableEP child : children) {
child.myPicoContainer = myPicoContainer;
child.myPluginDescriptor = myPluginDescriptor;
child.isForDefaultProject = isForDefaultProject;
child.myProject = myProject;
}
return children;
}
@@ -76,9 +86,8 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
@Attribute("nonDefaultProject")
public boolean nonDefaultProject;
private boolean isForDefaultProject;
public boolean isAvailable() {
return !(nonDefaultProject && isForDefaultProject);
return !nonDefaultProject || !(myProject != null && myProject.isDefault());
}
/**
@@ -91,26 +100,27 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
@Attribute("provider")
public String providerClass;
private final AtomicNotNullLazyValue<NullableFactory<Configurable>> myFactory;
private final AtomicNotNullLazyValue<NullableFactory<T>> myFactory;
private PicoContainer myPicoContainer;
private Project myProject;
@SuppressWarnings("UnusedDeclaration")
public ConfigurableEP() {
this(ApplicationManager.getApplication().getPicoContainer());
this(ApplicationManager.getApplication().getPicoContainer(), null);
}
@SuppressWarnings("UnusedDeclaration")
public ConfigurableEP(Project project) {
this(project.getPicoContainer());
isForDefaultProject = project.isDefault();
this(project.getPicoContainer(), project);
}
private ConfigurableEP(PicoContainer picoContainer) {
protected ConfigurableEP(PicoContainer picoContainer, @Nullable Project project) {
myProject = project;
myPicoContainer = picoContainer;
myFactory = new AtomicNotNullLazyValue<NullableFactory<Configurable>>() {
myFactory = new AtomicNotNullLazyValue<NullableFactory<T>>() {
@NotNull
@Override
protected NullableFactory<Configurable> compute() {
protected NullableFactory<T> compute() {
if (providerClass != null) {
return new InstanceFromProviderFactory();
}
@@ -126,7 +136,7 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
}
@Nullable
public Configurable createConfigurable() {
public T createConfigurable() {
try {
return myFactory.getValue().create();
}
@@ -139,9 +149,18 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
return null;
}
private class InstanceFromProviderFactory extends AtomicNotNullLazyValue<ConfigurableProvider> implements NullableFactory<Configurable> {
public Configurable create() {
return getValue().createConfigurable();
public Project getProject() {
return myProject;
}
@Override
public String toString() {
return getDisplayName();
}
private class InstanceFromProviderFactory extends AtomicNotNullLazyValue<ConfigurableProvider> implements NullableFactory<T> {
public T create() {
return (T)getValue().createConfigurable();
}
@NotNull
@@ -156,14 +175,14 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
}
}
private class NewInstanceFactory extends NotNullLazyValue<Class<? extends Configurable>> implements NullableFactory<Configurable> {
public Configurable create() {
private class NewInstanceFactory extends NotNullLazyValue<Class<? extends T>> implements NullableFactory<T> {
public T create() {
return instantiate(getValue(), myPicoContainer, true);
}
@NotNull
@Override
protected Class<? extends Configurable> compute() {
protected Class<? extends T> compute() {
try {
return findClass(instanceClass);
}
@@ -173,17 +192,17 @@ public class ConfigurableEP extends AbstractExtensionPointBean {
}
}
private class ImplementationFactory extends AtomicNotNullLazyValue<Configurable> implements NullableFactory<Configurable> {
private class ImplementationFactory extends AtomicNotNullLazyValue<T> implements NullableFactory<T> {
@Override
public Configurable create() {
public T create() {
return compute();
}
@NotNull
@Override
protected Configurable compute() {
protected T compute() {
try {
final Class<Configurable> aClass = findClass(implementationClass);
final Class<T> aClass = findClass(implementationClass);
return instantiate(aClass, myPicoContainer, true);
}
catch (ClassNotFoundException e) {
@@ -0,0 +1,42 @@
/*
* 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.ui;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* Typed version of {@link ColoredListCellRenderer}.
*/
public abstract class ColoredListCellRendererWrapper<T> extends ColoredListCellRenderer {
@Override
protected final void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
@SuppressWarnings("unchecked") final T t = (T)value;
doCustomize(list, t, index, selected, hasFocus);
}
protected abstract void doCustomize(JList list, T value, int index, boolean selected, boolean hasFocus);
public void append(@NotNull SimpleColoredText text) {
int length = text.getTexts().size();
for (int i = 0; i < length; i++) {
String fragment = text.getTexts().get(i);
SimpleTextAttributes attributes = text.getAttributes().get(i);
append(fragment, attributes);
}
}
}
@@ -17,8 +17,8 @@ package com.intellij.ide;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.SystemInfo;
@@ -107,7 +107,7 @@ public class BrowserSettingsPanel extends JPanel {
myUseAlternativeBrowser.setVisible(false);
}
mySettingsProviders = AbstractConfigurableEP.createConfigurables(BrowserSettingsProviderEP.EP_NAME);
mySettingsProviders = ConfigurableWrapper.createConfigurables(BrowserSettingsProviderEP.EP_NAME);
for (BrowserSettingsProvider settingsProvider : mySettingsProviders) {
outerPanel.add(settingsProvider.createComponent());
}
@@ -16,11 +16,11 @@
package com.intellij.ide;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
/**
* @author nik
*/
public class BrowserSettingsProviderEP extends AbstractConfigurableEP<BrowserSettingsProvider> {
public class BrowserSettingsProviderEP extends ConfigurableEP<BrowserSettingsProvider> {
public static ExtensionPointName<BrowserSettingsProviderEP> EP_NAME = ExtensionPointName.create("com.intellij.browserSettingsProvider");
}
@@ -17,6 +17,7 @@ package com.intellij.ide;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.ui.components.JBRadioButton;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -189,6 +190,6 @@ public class GeneralSettingsConfigurable extends CompositeConfigurable<Searchabl
}
protected List<SearchableConfigurable> createConfigurables() {
return AbstractConfigurableEP.createConfigurables(EP_NAME);
return ConfigurableWrapper.createConfigurables(EP_NAME);
}
}
@@ -15,7 +15,7 @@
*/
package com.intellij.ide;
import com.intellij.openapi.options.AbstractConfigurableEP;
import com.intellij.openapi.options.ConfigurableEP;
import com.intellij.openapi.options.SearchableConfigurable;
/**
@@ -29,5 +29,5 @@ import com.intellij.openapi.options.SearchableConfigurable;
*
* @author nik
*/
public class GeneralSettingsConfigurableEP extends AbstractConfigurableEP<SearchableConfigurable> {
public class GeneralSettingsConfigurableEP extends ConfigurableEP<SearchableConfigurable> {
}
@@ -70,9 +70,11 @@ public class ErrorViewStructure extends AbstractTreeStructure {
// simple messages
synchronized (myLock) {
for (final ErrorTreeElementKind kind : ourMessagesOrder) {
if (ErrorTreeElementKind.WARNING.equals(kind) || ErrorTreeElementKind.NOTE.equals(kind)) {
if (myCanHideWarnings && ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) {
continue;
if (myCanHideWarnings) {
if (ErrorTreeElementKind.WARNING.equals(kind) || ErrorTreeElementKind.NOTE.equals(kind)) {
if (ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) {
continue;
}
}
}
final List<ErrorTreeElement> elems = mySimpleMessages.get(kind);
@@ -274,6 +276,13 @@ public class ErrorViewStructure extends AbstractTreeStructure {
}
}
@Nullable
public GroupingElement lookupGroupingElement(String groupName) {
synchronized (myLock) {
return myGroupNameToElementMap.get(groupName);
}
}
public GroupingElement getGroupingElement(String groupName, Object data, VirtualFile file) {
synchronized (myLock) {
GroupingElement element = myGroupNameToElementMap.get(groupName);
@@ -351,6 +360,35 @@ public class ErrorViewStructure extends AbstractTreeStructure {
}
}
public void removeElement(final ErrorTreeElement element) {
if (element == myRoot) {
return;
}
if (element instanceof GroupingElement) {
removeGroup(((GroupingElement)element).getName());
}
else if (element instanceof NavigatableMessageElement){
final NavigatableMessageElement navElement = (NavigatableMessageElement)element;
final GroupingElement parent = navElement.getParent();
if (parent != null) {
synchronized (myLock) {
final List<NavigatableMessageElement> groupMessages = myGroupNameToMessagesMap.get(parent.getName());
if (groupMessages != null) {
groupMessages.remove(navElement);
}
}
}
}
else {
synchronized (myLock) {
final List<ErrorTreeElement> simples = mySimpleMessages.get(element.getKind());
if (simples != null) {
simples.remove(element);
}
}
}
}
private static class MyNavigatableWithDataElement extends NavigatableMessageElement {
private final VirtualFile myVf;
private final CustomizeColoredTreeCellRenderer myCustomizeColoredTreeCellRenderer;
@@ -68,6 +68,7 @@ import java.util.List;
public final class ActionManagerImpl extends ActionManagerEx implements ApplicationComponent {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl");
private static final int DEACTIVATED_TIMER_DELAY = 5000;
private static final int TIMER_DELAY = 500;
private static final int UPDATE_DELAY_AFTER_TYPING = 500;
@@ -1193,7 +1194,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public void applicationDeactivated(IdeFrame ideFrame) {
setDelay(30000);
setDelay(DEACTIVATED_TIMER_DELAY);
}
});
}
@@ -108,13 +108,15 @@ public class IndentSelectionAction extends EditorAction {
if (bulkMode) ((DocumentEx)document).setInBulkUpdate(true);
try {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
IndentStrategy indentStrategy = LanguageIndentStrategy.getIndentStrategy(file);
List<Integer> nonModifiableLines = new ArrayList<Integer>();
if (!LanguageIndentStrategy.isDefault(indentStrategy)) {
for (int i = startIndex; i <= endIndex; i++) {
if (!canIndent(document, file, i, indentStrategy)) {
nonModifiableLines.add(i);
if (project != null) {
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
IndentStrategy indentStrategy = LanguageIndentStrategy.getIndentStrategy(file);
if (!LanguageIndentStrategy.isDefault(indentStrategy)) {
for (int i = startIndex; i <= endIndex; i++) {
if (!canIndent(document, file, i, indentStrategy)) {
nonModifiableLines.add(i);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More