From 3c25e2b4004adecf13cbfd1a18967b4bce3492e6 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 11 Feb 2013 18:20:01 +0100 Subject: [PATCH 01/42] IDEA-100792 (for manually configured browser, use it's icon in Open action) --- .../ide/browsers/BrowsersConfiguration.java | 17 +++++++++++ .../ide/browsers/OpenFileInBrowserAction.java | 29 ++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java index 64729f6a3f41..04794c6c8bdc 100644 --- a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java +++ b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java @@ -23,7 +23,9 @@ import com.intellij.ide.browsers.impl.DefaultUrlOpener; import com.intellij.openapi.components.*; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.WindowsRegistryUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; @@ -34,6 +36,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.io.File; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; @@ -239,6 +242,20 @@ public class BrowsersConfiguration implements PersistentStateComponent return null; } + @Nullable + public static BrowserFamily findFamilyByPath(@Nullable String path) { + if (!StringUtil.isEmptyOrSpaces(path)) { + String name = FileUtil.getNameWithoutExtension(new File(path).getName()); + for (BrowserFamily family : BrowserFamily.values()) { + if (name.equalsIgnoreCase(family.getExecutionPath())) { + return family; + } + } + } + + return null; + } + /** * Gets data from Windows registry, may take some time to run (up to ~300ms) * diff --git a/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java b/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java index 2326b1ce4af2..13ff48c2a989 100644 --- a/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java +++ b/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java @@ -1,6 +1,22 @@ +/* + * Copyright 2000-2013 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.ide.browsers; import com.intellij.ide.BrowserUtil; +import com.intellij.ide.GeneralSettings; import com.intellij.ide.browsers.impl.WebBrowserServiceImpl; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -27,6 +43,7 @@ public class OpenFileInBrowserAction extends DumbAwareAction { final WebBrowserUrlProvider browserUrlProvider = WebBrowserServiceImpl.getProvider(file); final boolean isHtmlFile = HtmlUtil.isHtmlFile(file); presentation.setEnabled(browserUrlProvider != null || isHtmlFile); + String text = getTemplatePresentation().getText(); String description = getTemplatePresentation().getDescription(); @@ -46,10 +63,20 @@ public class OpenFileInBrowserAction extends DumbAwareAction { presentation.setText(text); presentation.setDescription(description); + + GeneralSettings settings = GeneralSettings.getInstance(); + if (!settings.isUseDefaultBrowser()) { + BrowsersConfiguration.BrowserFamily family = BrowsersConfiguration.findFamilyByPath(settings.getBrowserPath()); + if (family != null) { + presentation.setIcon(family.getIcon()); + } + } + if (ActionPlaces.isPopupPlace(e.getPlace())) { presentation.setVisible(presentation.isEnabled()); } - } else { + } + else { presentation.setVisible(false); presentation.setEnabled(false); } From e8e17ebd3fb813cbc9a49d60ea6707451e0610e6 Mon Sep 17 00:00:00 2001 From: Fedor Korotkov Date: Mon, 11 Feb 2013 19:32:18 +0400 Subject: [PATCH 02/42] Fix action bg color. --- .../codeInsight/intention/impl/FileLevelIntentionComponent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java index 65adeb9dfa31..009ca7f10a0e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java @@ -49,6 +49,7 @@ public class FileLevelIntentionComponent extends EditorNotificationPanel { final List> intentions, final Project project, final PsiFile psiFile, final Editor editor) { myProject = project; + myBackground = getColor(severity); final ShowIntentionsPass.IntentionsInfo info = new ShowIntentionsPass.IntentionsInfo(); @@ -72,7 +73,6 @@ public class FileLevelIntentionComponent extends EditorNotificationPanel { myLabel.setText(description); myLabel.setIcon(SeverityRegistrar.getInstance(project).compare(severity, HighlightSeverity.ERROR) >= 0 ? AllIcons.Actions.QuickfixBulb : AllIcons.Actions.IntentionBulb); - myBackground = getColor(severity); new ClickListener() { @Override From 51986c682ab9a387d5e116dee5651a4fb9584297 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 11 Feb 2013 18:46:34 +0100 Subject: [PATCH 03/42] parameter info: wrap in scrollbar and bound the height, otherwise it could be shown above the screen (IDEA-100819) --- .../hint/ParameterInfoComponent.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java index fe1b4496139f..3880ca5872e1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java @@ -21,6 +21,7 @@ import com.intellij.lang.parameterInfo.ParameterInfoUIContextEx; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import com.intellij.ui.Gray; +import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.SideBorder; import com.intellij.ui.StrikeoutLabel; import com.intellij.util.ui.UIUtil; @@ -55,7 +56,7 @@ class ParameterInfoComponent extends JPanel{ protected int myWidthLimit; public ParameterInfoComponent(Object[] objects, Editor editor,@NotNull ParameterInfoHandler handler) { - super(new GridBagLayout()); + super(new BorderLayout()); JComponent editorComponent = editor.getComponent(); JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane(); @@ -66,19 +67,36 @@ class ParameterInfoComponent extends JPanel{ myObjects = objects; - setLayout(new GridBagLayout()); setBackground(BACKGROUND_COLOR); myHandler = handler; myPanels = new OneElementComponent[myObjects.length]; + final JPanel panel = new JPanel(new GridBagLayout()); for(int i = 0; i < myObjects.length; i++) { myPanels[i] = new OneElementComponent(); - add(myPanels[i], new GridBagConstraints(0,i,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0)); + panel.add(myPanels[i], new GridBagConstraints(0,i,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.HORIZONTAL,new Insets(0,0,0,0),0,0)); } + final JScrollPane pane = ScrollPaneFactory.createScrollPane(panel); + pane.setBorder(null); + pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + add(pane, BorderLayout.CENTER); + myCurrentParameterIndex = -1; } + @Override + public Dimension getPreferredSize() { + int size = myPanels.length; + final Dimension preferredSize = super.getPreferredSize(); + if (size >= 0 && size <= 20) { + return preferredSize; + } + else { + return new Dimension(preferredSize.width + 20, 200); + } + } + public Object getHighlighted() { return myHighlighted; } From a5e24aae6400b3f0c0076607cac2ea9c11045aa1 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 11 Feb 2013 18:57:42 +0100 Subject: [PATCH 04/42] NPE --- .../source/resolve/PsiResolveHelperImpl.java | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index 63ea6bdab1cc..431665b045e2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -1033,38 +1033,40 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } final Pair result; - if (constraint == null && methodCall instanceof PsiCallExpression) { - - final PsiExpressionList argumentList = ((PsiCallExpression)methodCall).getArgumentList(); - if (argumentList != null && preparedKey == null && PsiUtil.getLanguageLevel(argumentList).isAtLeast(LanguageLevel.JDK_1_8)) { - for (PsiExpression expression : argumentList.getExpressions()) { - if (expression instanceof PsiLambdaExpression || expression instanceof PsiMethodReferenceExpression) { - final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, false); - if (functionalInterfaceType == null || PsiUtil.resolveClassInType(functionalInterfaceType) == typeParameter){ - return getFailedInferenceConstraint(typeParameter); - } - final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); - - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); - if (method == null || methodParamsDependOn(typeParameter, expression, - functionalInterfaceType, method.getParameterList().getParameters(), - LambdaUtil.getSubstitutor(method, resolveResult))) { - if (expression instanceof PsiMethodReferenceExpression) { + if (constraint == null) { + if (methodCall instanceof PsiCallExpression) { + final PsiExpressionList argumentList = ((PsiCallExpression)methodCall).getArgumentList(); + if (argumentList != null && preparedKey == null && PsiUtil.getLanguageLevel(argumentList).isAtLeast(LanguageLevel.JDK_1_8)) { + for (PsiExpression expression : argumentList.getExpressions()) { + if (expression instanceof PsiLambdaExpression || expression instanceof PsiMethodReferenceExpression) { + final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, false); + if (functionalInterfaceType == null || PsiUtil.resolveClassInType(functionalInterfaceType) == typeParameter){ return getFailedInferenceConstraint(typeParameter); } - return null; + final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); + + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); + if (method == null || methodParamsDependOn(typeParameter, expression, + functionalInterfaceType, method.getParameterList().getParameters(), + LambdaUtil.getSubstitutor(method, resolveResult))) { + if (expression instanceof PsiMethodReferenceExpression) { + return getFailedInferenceConstraint(typeParameter); + } + return null; + } } } } - } - final PsiSubstitutor finalSubstitutor = substitutor.put(typeParameter, null); - PsiClassType[] superTypes = typeParameter.getSuperTypes(); - if (superTypes.length == 0) return null; - PsiType superType = finalSubstitutor.substitute(superTypes[0]); - if (superType == null) superType = PsiType.getJavaLangObject(manager, scope); - if (superType == null) return null; - return policy.getInferredTypeWithNoConstraint(manager, superType); + final PsiSubstitutor finalSubstitutor = substitutor.put(typeParameter, null); + PsiClassType[] superTypes = typeParameter.getSuperTypes(); + if (superTypes.length == 0) return null; + PsiType superType = finalSubstitutor.substitute(superTypes[0]); + if (superType == null) superType = PsiType.getJavaLangObject(manager, scope); + if (superType == null) return null; + return policy.getInferredTypeWithNoConstraint(manager, superType); + } + return null; } else { PsiType guess = constraint.getFirst(); From 9561ad705d86a728bf0b9542bdd15451d776594e Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 11 Feb 2013 19:08:58 +0100 Subject: [PATCH 05/42] generate toString(): replace policy: remember user choice where to insert, it would be used for the initial toString() generation (IDEA-100244) --- .../org/jetbrains/generate/tostring/config/ReplacePolicy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/ReplacePolicy.java b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/ReplacePolicy.java index 2d01a464840f..e5714ed2a11e 100644 --- a/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/ReplacePolicy.java +++ b/plugins/generate-tostring/src/org/jetbrains/generate/tostring/config/ReplacePolicy.java @@ -36,7 +36,7 @@ public class ReplacePolicy implements ConflictResolutionPolicy { } public void setNewMethodStrategy(InsertNewMethodStrategy strategy) { - // not needed here + DuplicatePolicy.getInstance().setNewMethodStrategy(strategy); } public PsiMethod applyMethod(PsiClass clazz, PsiMethod existingMethod, @NotNull PsiMethod newMethod, Editor editor) throws IncorrectOperationException { From 4262a070295d1aa8fa100775ba635705a2e782e9 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 11 Feb 2013 18:02:37 +0400 Subject: [PATCH 06/42] grammar-kit runtime extracted to platform --- .../intellij/lang/impl/PsiBuilderAdapter.java | 4 + .../intellij/lang/impl/PsiBuilderImpl.java | 13 +- .../lang/parser/GeneratedParserUtilBase.java | 795 ++++++++++++++++++ 3 files changed, 808 insertions(+), 4 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java index 49ff31dd0b26..6d32701a79fd 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java @@ -32,6 +32,10 @@ public class PsiBuilderAdapter implements PsiBuilder { myDelegate = delegate; } + public PsiBuilder getDelegate() { + return myDelegate; + } + @Override public Project getProject() { return myDelegate.getProject(); diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index c69755ba7002..e0d559f1cbbc 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -22,7 +22,10 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiFile; import com.intellij.psi.TokenType; @@ -31,14 +34,16 @@ import com.intellij.psi.impl.source.resolve.FileContextUtil; import com.intellij.psi.impl.source.text.BlockSupportImpl; import com.intellij.psi.impl.source.text.DiffLog; import com.intellij.psi.impl.source.tree.*; -import com.intellij.psi.impl.source.tree.Factory; import com.intellij.psi.text.BlockSupport; import com.intellij.psi.tree.*; import com.intellij.util.CharTable; import com.intellij.util.ExceptionUtil; import com.intellij.util.ThreeState; import com.intellij.util.TripleFunction; -import com.intellij.util.containers.*; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.LimitedPool; +import com.intellij.util.containers.Stack; import com.intellij.util.diff.DiffTreeChangeBuilder; import com.intellij.util.diff.FlyweightCapableTreeStructure; import com.intellij.util.diff.ShallowNodeComparator; @@ -798,7 +803,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder, AS clearCachedTokenType(); } - private boolean whitespaceOrComment(IElementType token) { + public boolean whitespaceOrComment(IElementType token) { return myWhitespaces.contains(token) || myComments.contains(token); } diff --git a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java new file mode 100644 index 000000000000..fd0860fbe45d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java @@ -0,0 +1,795 @@ +// This class is a runtime engine for parsers generated by Grammar-Kit. +// Do not modify or refactor without complete investigation and/or review. +package com.intellij.lang.parser; + +import com.intellij.lang.*; +import com.intellij.lang.impl.PsiBuilderAdapter; +import com.intellij.lang.impl.PsiBuilderImpl; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringHash; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiReference; +import com.intellij.psi.TokenType; +import com.intellij.psi.impl.source.resolve.FileContextUtil; +import com.intellij.psi.impl.source.tree.CompositePsiElement; +import com.intellij.psi.tree.ICompositeElementType; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.Function; +import com.intellij.util.containers.LimitedPool; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedList; + +/** + * @author gregsh + */ +@SuppressWarnings("StringEquality") +public class GeneratedParserUtilBase { + + private static final Logger LOG = Logger.getInstance("com.intellij.lang.parser.GeneratedParserUtilBase"); + + public static final IElementType DUMMY_BLOCK = new DummyBlockElementType(); + + public interface Parser { + boolean parse(PsiBuilder builder, int level); + } + + public static final Parser TOKEN_ADVANCER = new Parser() { + @Override + public boolean parse(PsiBuilder builder, int level) { + if (builder.eof()) return false; + builder.advanceLexer(); + return true; + } + }; + + public static final Parser TRUE_CONDITION = new Parser() { + @Override + public boolean parse(PsiBuilder builder, int level) { + return true; + } + }; + + public static boolean eof(PsiBuilder builder_, int level_) { + return builder_.eof(); + } + + public static boolean recursion_guard_(PsiBuilder builder_, int level_, String funcName_) { + if (level_ > 1000) { + builder_.error("Maximum recursion level (" + 1000 + ") reached in " + funcName_); + return false; + } + return true; + } + + public static void empty_element_parsed_guard_(PsiBuilder builder_, int offset_, String funcName_) { + builder_.error("Empty element parsed in " + funcName_ +" at offset " + offset_); + } + + public static boolean invalid_left_marker_guard_(PsiBuilder builder_, PsiBuilder.Marker marker_, String funcName_) { + //builder_.error("Invalid left marker encountered in " + funcName_ +" at offset " + builder_.getCurrentOffset()); + boolean goodMarker = marker_ != null && ((LighterASTNode)marker_).getTokenType() != TokenType.ERROR_ELEMENT; + if (!goodMarker) return false; + ErrorState state = ErrorState.get(builder_); + + Frame frame = state.frameStack.isEmpty() ? null : state.frameStack.getLast(); + return frame == null || frame.errorReportedAt <= builder_.getCurrentOffset(); + } + + public static boolean consumeTokens(PsiBuilder builder_, int pin_, IElementType... tokens_) { + ErrorState state = ErrorState.get(builder_); + if (state.completionState != null && state.predicateSign) { + addCompletionVariant(builder_, state, state.completionState, tokens_, builder_.getCurrentOffset()); + } + // suppress single token completion + CompletionState completionState = state.completionState; + state.completionState = null; + boolean result_ = true; + boolean pinned_ = false; + for (int i = 0, tokensLength = tokens_.length; i < tokensLength; i++) { + if (pin_ > 0 && i == pin_) pinned_ = result_; + if ((result_ || pinned_) && !consumeToken(builder_, tokens_[i])) { + result_ = false; + if (pin_ < 0 || pinned_) report_error_(builder_, state, false); + } + } + state.completionState = completionState; + return pinned_ || result_; + } + + public static boolean consumeToken(PsiBuilder builder_, IElementType token) { + if (nextTokenIsInner(builder_, token, true)) { + builder_.advanceLexer(); + return true; + } + return false; + } + + public static boolean consumeTokenFast(PsiBuilder builder_, IElementType token) { + if (builder_.getTokenType() == token) { + builder_.advanceLexer(); + return true; + } + return false; + } + + public static boolean consumeTokenFast(PsiBuilder builder_, String text) { + if (Comparing.strEqual(builder_.getTokenText(), text, ErrorState.get(builder_).caseSensitive)) { + builder_.advanceLexer(); + return true; + } + return false; + } + + public static boolean nextTokenIsFast(PsiBuilder builder_, IElementType token) { + return builder_.getTokenType() == token; + } + + public static boolean nextTokenIs(PsiBuilder builder_, IElementType token) { + return nextTokenIsInner(builder_, token, false); + } + + public static boolean nextTokenIsInner(PsiBuilder builder_, IElementType token, boolean force) { + ErrorState state = ErrorState.get(builder_); + if (state.completionState != null && !force) return true; + IElementType tokenType = builder_.getTokenType(); + if (!state.suppressErrors && state.predicateCount < 2) { + addVariant(builder_, state, token); + } + return token == tokenType; + } + + public static boolean replaceVariants(PsiBuilder builder_, int variantCount, String frameName) { + ErrorState state = ErrorState.get(builder_); + if (!state.suppressErrors && state.predicateCount < 2 && state.predicateSign) { + state.clearVariants(true, state.variants.size() - variantCount); + addVariantInner(state, builder_.getCurrentOffset(), frameName); + } + return true; + } + + public static void addVariant(PsiBuilder builder_, String text) { + addVariant(builder_, ErrorState.get(builder_), text); + } + + private static void addVariant(PsiBuilder builder_, ErrorState state, Object o) { + int offset = builder_.getCurrentOffset(); + addVariantInner(state, offset, o); + + CompletionState completionState = state.completionState; + if (completionState != null && state.predicateSign) { + addCompletionVariant(builder_, state, completionState, o, offset); + } + } + + private static void addVariantInner(ErrorState state, int offset, Object o) { + Variant variant = state.VARIANTS.alloc().init(offset, o); + if (state.predicateSign) { + state.variants.add(variant); + if (state.lastExpectedVariantOffset < variant.offset) { + state.lastExpectedVariantOffset = variant.offset; + } + } + else { + state.unexpected.add(variant); + } + } + + public static boolean consumeToken(PsiBuilder builder_, String text) { + ErrorState state = ErrorState.get(builder_); + if (!state.suppressErrors && state.predicateCount < 2) { + addVariant(builder_, state, text); + } + return consumeTokenInner(builder_, text, state.caseSensitive); + } + + public static boolean consumeTokenInner(PsiBuilder builder_, String text, boolean caseSensitive) { + final CharSequence sequence = builder_.getOriginalText(); + final int offset = builder_.getCurrentOffset(); + final int endOffset = offset + text.length(); + CharSequence tokenText = sequence.subSequence(offset, Math.min(endOffset, sequence.length())); + + if (Comparing.equal(text, tokenText, caseSensitive)) { + int count = 0; + while (true) { + final int nextOffset = builder_.rawTokenTypeStart(++ count); + if (nextOffset > endOffset) { + return false; + } + else if (nextOffset == endOffset) { + break; + } + } + while (count-- > 0) builder_.advanceLexer(); + return true; + } + return false; + } + + private static void addCompletionVariant(PsiBuilder builder_, + ErrorState state, + CompletionState completionState, + Object o, + int offset) { + boolean add = false; + int diff = completionState.offset - offset; + String text = completionState.convertItem(o); + int length = text == null? 0 : text.length(); + if (length == 0) return; + if (diff == 0) { + add = true; + } + else if (diff > 0 && diff <= length) { + CharSequence fragment = builder_.getOriginalText().subSequence(offset, completionState.offset); + add = StringUtil.startsWithIgnoreCase(text, fragment.toString()); + } + else if (diff < 0) { + for (int i=-1; ; i--) { + IElementType type = builder_.rawLookup(i); + int tokenStart = builder_.rawTokenTypeStart(i); + if (((PsiBuilderImpl)((Builder)builder_).getDelegate()).whitespaceOrComment(type)) { + diff = completionState.offset - tokenStart; + } + else if (type != null && tokenStart < completionState.offset) { + CharSequence fragment = builder_.getOriginalText().subSequence(tokenStart, completionState.offset); + if (StringUtil.startsWithIgnoreCase(text, fragment.toString())) { + diff = completionState.offset - tokenStart; + } + break; + } + else break; + } + add = diff >= 0 && diff < length; + } + add = add && length > 1 && !(text.charAt(0) == '<' && text.charAt(length - 1) == '>') && + !(text.charAt(0) == '\'' && text.charAt(length - 1) == '\'' && length < 5); + if (add) { + completionState.items.add(text); + } + } + + + public static final String _SECTION_NOT_ = "_SECTION_NOT_"; + public static final String _SECTION_AND_ = "_SECTION_AND_"; + public static final String _SECTION_RECOVER_ = "_SECTION_RECOVER_"; + public static final String _SECTION_GENERAL_ = "_SECTION_GENERAL_"; + + public static void enterErrorRecordingSection(PsiBuilder builder_, int level, @NotNull String sectionType, @Nullable String frameName) { + ErrorState state = ErrorState.get(builder_); + Frame frame = state.FRAMES.alloc().init(builder_.getCurrentOffset(), level, sectionType, frameName, state.variants.size()); + state.frameStack.add(frame); + if (sectionType == _SECTION_AND_) { + if (state.predicateCount == 0 && !state.predicateSign) { + throw new AssertionError("Incorrect false predicate sign"); + } + state.predicateCount++; + } + else if (sectionType == _SECTION_NOT_) { + if (state.predicateCount == 0) { + state.predicateSign = false; + } + else { + state.predicateSign = !state.predicateSign; + } + state.predicateCount++; + } + } + + public static boolean exitErrorRecordingSection(PsiBuilder builder_, + int level, + boolean result, + boolean pinned, + @NotNull String sectionType, + @Nullable Parser eatMore) { + ErrorState state = ErrorState.get(builder_); + + Frame frame = state.frameStack.pollLast(); + int initialOffset = builder_.getCurrentOffset(); + if (frame == null || level != frame.level || !sectionType.equals(frame.section)) { + LOG.error("Unbalanced error section: got " + new Frame().init(initialOffset, level, sectionType, "", 0) + ", expected " + frame); + if (frame != null) state.FRAMES.recycle(frame); + return result; + } + if (sectionType == _SECTION_AND_ || sectionType == _SECTION_NOT_) { + state.predicateCount--; + if (sectionType == _SECTION_NOT_) state.predicateSign = !state.predicateSign; + state.FRAMES.recycle(frame); + return result; + } + if (!result && !pinned && initialOffset == frame.offset && state.lastExpectedVariantOffset == frame.offset && + frame.name != null && state.variants.size() - frame.variantCount > 1) { + state.clearVariants(true, frame.variantCount); + addVariantInner(state, initialOffset, frame.name); + } + if (sectionType == _SECTION_RECOVER_ && !state.suppressErrors && eatMore != null) { + state.suppressErrors = true; + final boolean eatMoreFlagOnce = !builder_.eof() && eatMore.parse(builder_, frame.level + 1); + final int lastErrorPos = getLastVariantOffset(state, initialOffset); + boolean eatMoreFlag = eatMoreFlagOnce || !result && frame.offset == initialOffset && lastErrorPos > frame.offset; + + final LighterASTNode latestDoneMarker = + (pinned || result) && (state.altMode || lastErrorPos > initialOffset) && + eatMoreFlagOnce ? builder_.getLatestDoneMarker() : null; + PsiBuilder.Marker extensionMarker = null; + IElementType extensionTokenType = null; + if (latestDoneMarker instanceof PsiBuilder.Marker && frame.offset == latestDoneMarker.getStartOffset()) { + extensionMarker = ((PsiBuilder.Marker)latestDoneMarker).precede(); + extensionTokenType = latestDoneMarker.getTokenType(); + ((PsiBuilder.Marker)latestDoneMarker).drop(); + } + // advance to the last error pos + // skip tokens until lastErrorPos. parseAsTree might look better here... + int parenCount = 0; + while ((eatMoreFlag || parenCount > 0) && builder_.getCurrentOffset() < lastErrorPos) { + if (state.braces != null) { + if (builder_.getTokenType() == state.braces[0].getLeftBraceType()) parenCount ++; + else if (builder_.getTokenType() == state.braces[0].getRightBraceType()) parenCount --; + } + builder_.advanceLexer(); + eatMoreFlag = eatMore.parse(builder_, frame.level + 1); + } + boolean errorReported = frame.errorReportedAt == initialOffset; + if (errorReported) { + if (eatMoreFlag) { + builder_.advanceLexer(); + parseAsTree(state, builder_, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore); + } + } + else if (eatMoreFlag) { + errorReported = reportError(builder_, state, true, true); + parseAsTree(state, builder_, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore); + } + else if (eatMoreFlagOnce || (!result && frame.offset != builder_.getCurrentOffset())) { + errorReported = reportError(builder_, state, true, false); + } + if (extensionMarker != null) { + extensionMarker.done(extensionTokenType); + } + state.suppressErrors = false; + if (errorReported || result) { + state.clearVariants(true, 0); + state.clearVariants(false, 0); + state.lastExpectedVariantOffset = -1; + } + if (!result && eatMoreFlagOnce && frame.offset != builder_.getCurrentOffset()) result = true; + } + else if (!result && pinned && frame.errorReportedAt < 0) { + // do not report if there're errors after current offset + if (getLastVariantOffset(state, initialOffset) == initialOffset) { + // do not force, inner recoverRoot might have skipped some tokens + if (reportError(builder_, state, false, false)) { + frame.errorReportedAt = initialOffset; + } + } + } + // propagate errorReportedAt up the stack to avoid duplicate reporting + Frame prevFrame = state.frameStack.isEmpty() ? null : state.frameStack.getLast(); + if (prevFrame != null && prevFrame.errorReportedAt < frame.errorReportedAt) prevFrame.errorReportedAt = frame.errorReportedAt; + state.FRAMES.recycle(frame); + return result; + } + + public static boolean report_error_(PsiBuilder builder_, boolean result_) { + if (!result_) report_error_(builder_, ErrorState.get(builder_), false); + return result_; + } + + public static void report_error_(PsiBuilder builder_, ErrorState state, boolean advance) { + Frame frame = state.frameStack.isEmpty()? null : state.frameStack.getLast(); + if (frame == null) { + LOG.error("Unbalanced error section: got null , expected " + frame); + return; + } + int offset = builder_.getCurrentOffset(); + if (frame.errorReportedAt < offset && getLastVariantOffset(state, builder_.getCurrentOffset()) <= offset) { + if (reportError(builder_, state, true, advance)) { + frame.errorReportedAt = offset; + } + } + } + + private static int getLastVariantOffset(ErrorState state, int defValue) { + return state.lastExpectedVariantOffset < 0? defValue : state.lastExpectedVariantOffset; + } + + private static boolean reportError(PsiBuilder builder_, ErrorState state, boolean force, boolean advance) { + String expectedText = state.getExpectedText(builder_); + boolean notEmpty = StringUtil.isNotEmpty(expectedText); + if (force || notEmpty || advance) { + String gotText = builder_.eof()? "unexpected end of file" : + notEmpty? "got '" + builder_.getTokenText() +"'" : + "'" + builder_.getTokenText() +"' unexpected"; + String message = expectedText + gotText; + if (advance) { + PsiBuilder.Marker mark = builder_.mark(); + builder_.advanceLexer(); + mark.error(message); + } + else { + builder_.error(message); + } + return true; + } + return false; + } + + + public static final Key COMPLETION_STATE_KEY = Key.create("COMPLETION_STATE_KEY"); + + public static class CompletionState implements Function { + public final int offset; + public final Collection items = new THashSet(); + + public CompletionState(int offset) { + this.offset = offset; + } + + @Nullable + public String convertItem(Object o) { + return o instanceof Object[] ? StringUtil.join((Object[]) o, this, " ") : o.toString(); + } + + @Override + public String fun(Object o) { + return o.toString(); + } + } + + public static class Builder extends PsiBuilderAdapter { + public final ErrorState state; + public final PsiParser parser; + + public Builder(PsiBuilder builder, ErrorState state, PsiParser parser) { + super(builder); + this.state = state; + this.parser = parser; + } + + public Lexer getLexer() { + return ((PsiBuilderImpl)myDelegate).getLexer(); + } + } + + public static PsiBuilder adapt_builder_(IElementType root, PsiBuilder builder, PsiParser parser) { + ErrorState state = new ErrorState(); + ErrorState.initState(root, builder, state); + return new Builder(builder, state, parser); + } + + public static class ErrorState { + int predicateCount; + boolean predicateSign = true; + boolean suppressErrors; + public final LinkedList frameStack = new LinkedList(); + public CompletionState completionState; + + private boolean caseSensitive; + public BracePair[] braces; + public boolean altMode; + + private int lastExpectedVariantOffset = -1; + public MyList variants = new MyList(500); + public MyList unexpected = new MyList(10); + + final LimitedPool VARIANTS = new LimitedPool(1000, new LimitedPool.ObjectFactory() { + public Variant create() { + return new Variant(); + } + + public void cleanup(final Variant o) { + } + }); + final LimitedPool FRAMES = new LimitedPool(100, new LimitedPool.ObjectFactory() { + public Frame create() { + return new Frame(); + } + + public void cleanup(final Frame o) { + } + }); + + public static ErrorState get(PsiBuilder builder) { + return ((Builder)builder).state; + } + + private static void initState(IElementType root, PsiBuilder builder, ErrorState state) { + PsiFile file = builder.getUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY); + state.completionState = file == null? null: file.getUserData(COMPLETION_STATE_KEY); + Language language = file == null? root.getLanguage() : file.getLanguage(); + state.caseSensitive = language.isCaseSensitive(); + PairedBraceMatcher matcher = LanguageBraceMatching.INSTANCE.forLanguage(language); + state.braces = matcher == null ? null : matcher.getPairs(); + if (state.braces != null && state.braces.length == 0) state.braces = null; + } + + public String getExpectedText(PsiBuilder builder_) { + int offset = builder_.getCurrentOffset(); + StringBuilder sb = new StringBuilder(); + if (addExpected(sb, offset, true)) { + sb.append(" expected, "); + } + else if (addExpected(sb, offset, false)) sb.append(" unexpected, "); + return sb.toString(); + } + + private static final int MAX_VARIANTS_TO_DISPLAY = Integer.MAX_VALUE; + private boolean addExpected(StringBuilder sb, int offset, boolean expected) { + MyList list = expected ? variants : unexpected; + String[] strings = new String[list.size()]; + long[] hashes = new long[strings.length]; + Arrays.fill(strings, ""); + int count = 0; + loop: for (Variant variant : list) { + if (offset == variant.offset) { + String text = variant.object.toString(); + long hash = StringHash.calc(text); + for (int i=0; i 0) { + if (count > MAX_VARIANTS_TO_DISPLAY) { + sb.append(" and ..."); + break; + } + else { + sb.append(", "); + } + } + char c = s.charAt(0); + String displayText = c == '<' || StringUtil.isJavaIdentifierStart(c) ? s : '\'' + s + '\''; + sb.append(displayText); + } + if (count > 1 && count < MAX_VARIANTS_TO_DISPLAY) { + int idx = sb.lastIndexOf(", "); + sb.replace(idx, idx + 1, " or"); + } + return count > 0; + } + + public void clearVariants(boolean expected, int start) { + MyList list = expected? variants : unexpected; + for (int i = start, len = list.size(); i < len; i ++) { + VARIANTS.recycle(list.get(i)); + } + list.setSize(start); + } + } + + public static class Frame { + public int offset; + public int level; + public String section; + public String name; + public int variantCount; + public int errorReportedAt; + + public Frame() { + } + + public Frame init(int offset, int level, String section, String name, int variantCount) { + this.offset = offset; + this.level = level; + this.section = section; + this.name = name; + this.variantCount = variantCount; + this.errorReportedAt = -1; + return this; + } + + @Override + public String toString() { + return "<"+offset+", "+section+", "+level+">"; + } + } + + + public static class Variant { + int offset; + Object object; + + public Variant init(int offset, Object text) { + this.offset = offset; + this.object = text; + return this; + } + + @Override + public String toString() { + return "<" + offset + ", " + object + ">"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Variant variant = (Variant)o; + + if (offset != variant.offset) return false; + if (!this.object.equals(variant.object)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = offset; + result = 31 * result + object.hashCode(); + return result; + } + } + + @Nullable + private static IElementType getClosingBracket(ErrorState state, IElementType type) { + if (state.braces == null) return null; + for (BracePair pair : state.braces) { + if (type == pair.getLeftBraceType()) return pair.getRightBraceType(); + } + return null; + } + + + private static final int MAX_CHILDREN_IN_TREE = 10; + public static boolean parseAsTree(ErrorState state, final PsiBuilder builder_, int level, final IElementType chunkType, + boolean checkBraces, final Parser parser, final Parser eatMoreCondition) { + final LinkedList> parenList = new LinkedList>(); + final LinkedList> siblingList = new LinkedList>(); + PsiBuilder.Marker marker = null; + + final Runnable checkSiblingsRunnable = new Runnable() { + public void run() { + main: + while (!siblingList.isEmpty()) { + final Pair parenPair = parenList.peek(); + final int rating = siblingList.getFirst().second; + int count = 0; + for (Pair pair : siblingList) { + if (pair.second != rating || parenPair != null && pair.first == parenPair.second) break main; + if (++count >= MAX_CHILDREN_IN_TREE) { + final PsiBuilder.Marker parentMarker = pair.first.precede(); + while (count-- > 0) { + siblingList.removeFirst(); + } + parentMarker.done(chunkType); + siblingList.addFirst(Pair.create(parentMarker, rating + 1)); + continue main; + } + } + break; + } + } + }; + boolean checkParens = state.braces != null && checkBraces; + int totalCount = 0; + int tokenCount = 0; + if (checkParens && builder_.rawLookup(-1) == state.braces[0].getLeftBraceType()) { + LighterASTNode doneMarker = builder_.getLatestDoneMarker(); + if (doneMarker != null && doneMarker.getStartOffset() == builder_.rawTokenTypeStart(-1) && doneMarker.getTokenType() == TokenType.ERROR_ELEMENT) { + parenList.add(Pair.create(((PsiBuilder.Marker)doneMarker).precede(), (PsiBuilder.Marker)null)); + } + } + while (true) { + final IElementType tokenType = builder_.getTokenType(); + if (checkParens && (tokenType == state.braces[0].getLeftBraceType() || tokenType == state.braces[0].getRightBraceType() && !parenList.isEmpty())) { + if (marker != null) { + marker.done(chunkType); + siblingList.addFirst(Pair.create(marker, 1)); + marker = null; + tokenCount = 0; + } + if (tokenType == state.braces[0].getLeftBraceType()) { + final Pair prev = siblingList.peek(); + parenList.addFirst(Pair.create(builder_.mark(), prev == null ? null : prev.first)); + } + checkSiblingsRunnable.run(); + builder_.advanceLexer(); + if (tokenType == state.braces[0].getRightBraceType()) { + final Pair pair = parenList.removeFirst(); + pair.first.done(chunkType); + // drop all markers inside parens + while (!siblingList.isEmpty() && siblingList.getFirst().first != pair.second) { + siblingList.removeFirst(); + } + siblingList.addFirst(Pair.create(pair.first, 1)); + checkSiblingsRunnable.run(); + } + } + else { + if (marker == null) { + marker = builder_.mark(); + } + final boolean result = (state.altMode && !parenList.isEmpty() || eatMoreCondition.parse(builder_, level + 1)) && parser.parse(builder_, level + 1); + if (result) { + tokenCount++; + totalCount++; + } + if (!result) { + break; + } + } + + if (tokenCount >= MAX_CHILDREN_IN_TREE && marker != null) { + marker.done(chunkType); + siblingList.addFirst(Pair.create(marker, 1)); + checkSiblingsRunnable.run(); + marker = null; + tokenCount = 0; + } + } + if (marker != null) { + marker.drop(); + } + for (Pair pair : parenList) { + pair.first.drop(); + } + return totalCount != 0; + } + + private static class DummyBlockElementType extends IElementType implements ICompositeElementType{ + DummyBlockElementType() { + super("DUMMY_BLOCK", Language.ANY); + } + + @NotNull + @Override + public ASTNode createCompositeNode() { + return new DummyBlock(); + } + } + + public static class DummyBlock extends CompositePsiElement { + DummyBlock() { + super(DUMMY_BLOCK); + } + + @Override + public PsiReference[] getReferences() { + return PsiReference.EMPTY_ARRAY; + } + + @Override + public boolean canNavigateToSource() { + return false; + } + + @Override + public boolean canNavigate() { + return false; + } + + @NotNull + @Override + public Language getLanguage() { + return getParent().getLanguage(); + } + } + + protected static class MyList extends ArrayList { + public MyList(int initialCapacity) { + super(initialCapacity); + } + + protected void setSize(int fromIndex) { + super.removeRange(fromIndex, size()); + } + } +} From 85d03f4964dd84cb924faed8a3fa1d7aeed0e055 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 11 Feb 2013 21:58:05 +0400 Subject: [PATCH 07/42] throw FileComparisonFailure --- .../com/intellij/testFramework/UsefulTestCase.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index bcf5dba4e160..2ffc651befb7 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -25,10 +25,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.impl.StartMarkAction; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; @@ -40,6 +37,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.refactoring.rename.inplace.InplaceRefactoring; +import com.intellij.rt.execution.junit.FileComparisonFailure; import com.intellij.testFramework.exceptionCases.AbstractExceptionCase; import com.intellij.util.Consumer; import com.intellij.util.Function; @@ -621,7 +619,7 @@ public abstract class UsefulTestCase extends TestCase { return testName.replaceAll("_.*", ""); } - protected static void assertSameLinesWithFile(final String filePath, final String actualText) { + protected static void assertSameLinesWithFile(String filePath, String actualText) { String fileText; try { if (OVERWRITE_TESTDATA) { @@ -633,7 +631,11 @@ public abstract class UsefulTestCase extends TestCase { catch (IOException e) { throw new RuntimeException(e); } - assertSameLines(fileText, actualText); + String expected = StringUtil.convertLineSeparators(fileText.trim()); + String actual = StringUtil.convertLineSeparators(actualText.trim()); + if (!Comparing.equal(expected, actual)) { + throw new FileComparisonFailure(null, expected, actual, filePath); + } } public static void clearFields(final Object test) throws IllegalAccessException { From 58eed460a7525f1e0a10f91fbbebca852b7f2f5a Mon Sep 17 00:00:00 2001 From: Nikolay Matveev Date: Mon, 11 Feb 2013 22:30:09 +0400 Subject: [PATCH 08/42] nullizeByCondition to ObjectUtils --- platform/util/src/com/intellij/util/ObjectUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/util/src/com/intellij/util/ObjectUtils.java b/platform/util/src/com/intellij/util/ObjectUtils.java index fe917abfad43..8e5e52d94bd4 100644 --- a/platform/util/src/com/intellij/util/ObjectUtils.java +++ b/platform/util/src/com/intellij/util/ObjectUtils.java @@ -15,6 +15,7 @@ */ package com.intellij.util; +import com.intellij.openapi.util.Condition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -56,8 +57,8 @@ public class ObjectUtils { } @Nullable - public static T nullizeIfSubtype(@Nullable T obj, @NotNull Class clazz) { - if (clazz.isInstance(obj)) { + public static T nullizeByCondition(@Nullable final T obj, @NotNull final Condition condition) { + if (condition.value(obj)) { return null; } return obj; From 5244a1d9f44dcf9cf37371624275fc859885347f Mon Sep 17 00:00:00 2001 From: Kirill Safonov Date: Mon, 11 Feb 2013 20:11:00 +0400 Subject: [PATCH 09/42] NPE --- .../analysis/HighlightingSettingsPerFile.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java index 5fda4d7037e5..a7c6c4556020 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightingSettingsPerFile.java @@ -59,13 +59,15 @@ public class HighlightingSettingsPerFile implements PersistentStateComponent filtered = - DumbService.getInstance(project).filterByDumbAwareness(Arrays.asList(providers)); - for (DefaultHighlightingSettingProvider p : filtered) { - FileHighlighingSetting setting = p.getDefaultSetting(project, virtualFile); - if (setting != null) { - return setting; + if (virtualFile != null) { + DefaultHighlightingSettingProvider[] providers = DefaultHighlightingSettingProvider.EP_NAME.getExtensions(); + List filtered = + DumbService.getInstance(project).filterByDumbAwareness(Arrays.asList(providers)); + for (DefaultHighlightingSettingProvider p : filtered) { + FileHighlighingSetting setting = p.getDefaultSetting(project, virtualFile); + if (setting != null) { + return setting; + } } } return FileHighlighingSetting.FORCE_HIGHLIGHTING; From 333724b6468e347c4f5cf6eeef96f498e7867900 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 11 Feb 2013 18:25:02 +0100 Subject: [PATCH 10/42] Nullability --- xml/impl/src/com/intellij/ide/browsers/UrlOpener.java | 5 +++-- .../src/com/intellij/ide/browsers/impl/DefaultUrlOpener.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java b/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java index 36ba41ef2f54..5f9c49d5a3c7 100644 --- a/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java +++ b/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -16,9 +16,10 @@ package com.intellij.ide.browsers; import com.intellij.openapi.extensions.ExtensionPointName; +import org.jetbrains.annotations.NotNull; public abstract class UrlOpener { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.jetbrains.urlOpener"); - public abstract boolean openUrl(BrowsersConfiguration.BrowserFamily family, String url); + public abstract boolean openUrl(@NotNull BrowsersConfiguration.BrowserFamily family, String url); } diff --git a/xml/impl/src/com/intellij/ide/browsers/impl/DefaultUrlOpener.java b/xml/impl/src/com/intellij/ide/browsers/impl/DefaultUrlOpener.java index ae37d74240d5..88f74b1c7e9d 100644 --- a/xml/impl/src/com/intellij/ide/browsers/impl/DefaultUrlOpener.java +++ b/xml/impl/src/com/intellij/ide/browsers/impl/DefaultUrlOpener.java @@ -41,7 +41,7 @@ public class DefaultUrlOpener extends UrlOpener { private static final Logger LOG = Logger.getInstance(DefaultUrlOpener.class); @Override - public boolean openUrl(BrowsersConfiguration.BrowserFamily family, @Nullable String url) { + public boolean openUrl(@NotNull BrowsersConfiguration.BrowserFamily family, @Nullable String url) { return launchBrowser(family, url, false); } From e99a8591a2a1bc218006ba88a3dfdface5b0521a Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 11 Feb 2013 18:37:25 +0100 Subject: [PATCH 11/42] Browser API cleanup (launch method moved to suitable class) --- .../ide/browsers/BrowsersConfiguration.java | 6 +++--- .../ide/browsers/OpenUrlHyperlinkInfo.java | 4 ++-- .../src/com/intellij/ide/browsers/UrlOpener.java | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java index 04794c6c8bdc..fa17cf55268f 100644 --- a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java +++ b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java @@ -152,9 +152,7 @@ public class BrowsersConfiguration implements PersistentStateComponent } myBrowserToSettingsMap.put(browserFamily, new WebBrowserSettings(path, Boolean.parseBoolean(active), specificSettings)); } - catch (IllegalArgumentException e) { - // skip - } + catch (IllegalArgumentException ignored) { } } } @@ -194,6 +192,8 @@ public class BrowsersConfiguration implements PersistentStateComponent return ServiceManager.getService(BrowsersConfiguration.class); } + /** @deprecated use {@link DefaultUrlOpener} (to remove in IDEA 13) */ + @SuppressWarnings("unused") public static void launchBrowser(final @Nullable BrowserFamily family, @NotNull final String url) { if (family == null) { BrowserUtil.launchBrowser(url); diff --git a/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java b/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java index 880afc2a27ac..fe8fe0632216 100644 --- a/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java +++ b/xml/impl/src/com/intellij/ide/browsers/OpenUrlHyperlinkInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -85,7 +85,7 @@ public class OpenUrlHyperlinkInfo implements HyperlinkWithPopupMenuInfo { @Override public void actionPerformed(AnActionEvent e) { - BrowsersConfiguration.launchBrowser(myFamily, myUrl); + UrlOpener.launchBrowser(myFamily, myUrl); } } } diff --git a/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java b/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java index 5f9c49d5a3c7..62d59d4c9522 100644 --- a/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java +++ b/xml/impl/src/com/intellij/ide/browsers/UrlOpener.java @@ -15,11 +15,26 @@ */ package com.intellij.ide.browsers; +import com.intellij.ide.BrowserUtil; import com.intellij.openapi.extensions.ExtensionPointName; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public abstract class UrlOpener { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.jetbrains.urlOpener"); + public static void launchBrowser(@Nullable BrowsersConfiguration.BrowserFamily family, @NotNull String url) { + if (family == null) { + BrowserUtil.launchBrowser(url); + } + else { + for (UrlOpener urlOpener : EP_NAME.getExtensions()) { + if (urlOpener.openUrl(family, url)) { + return; + } + } + } + } + public abstract boolean openUrl(@NotNull BrowsersConfiguration.BrowserFamily family, String url); } From fb5af99d0d6ed3b81a09a9d74b8e7fc426fee642 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 11 Feb 2013 18:41:12 +0100 Subject: [PATCH 12/42] Browser API cleanup (static service methods made instance ones) --- .../src/com/intellij/ide/browsers/BrowsersConfiguration.java | 4 ++-- .../com/intellij/ide/browsers/OpenFileInBrowserAction.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java index fa17cf55268f..fa4a3c37be9e 100644 --- a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java +++ b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java @@ -233,7 +233,7 @@ public class BrowsersConfiguration implements PersistentStateComponent } @Nullable - public static BrowserFamily findFamilyByName(@Nullable String name) { + public BrowserFamily findFamilyByName(@Nullable String name) { for (BrowserFamily family : BrowserFamily.values()) { if (family.getName().equals(name)) { return family; @@ -243,7 +243,7 @@ public class BrowsersConfiguration implements PersistentStateComponent } @Nullable - public static BrowserFamily findFamilyByPath(@Nullable String path) { + public BrowserFamily findFamilyByPath(@Nullable String path) { if (!StringUtil.isEmptyOrSpaces(path)) { String name = FileUtil.getNameWithoutExtension(new File(path).getName()); for (BrowserFamily family : BrowserFamily.values()) { diff --git a/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java b/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java index 13ff48c2a989..c64ca67b1492 100644 --- a/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java +++ b/xml/impl/src/com/intellij/ide/browsers/OpenFileInBrowserAction.java @@ -66,7 +66,7 @@ public class OpenFileInBrowserAction extends DumbAwareAction { GeneralSettings settings = GeneralSettings.getInstance(); if (!settings.isUseDefaultBrowser()) { - BrowsersConfiguration.BrowserFamily family = BrowsersConfiguration.findFamilyByPath(settings.getBrowserPath()); + BrowsersConfiguration.BrowserFamily family = BrowsersConfiguration.getInstance().findFamilyByPath(settings.getBrowserPath()); if (family != null) { presentation.setIcon(family.getIcon()); } From 05e9d289822188918c4e7ffbc9a4b435e87cccdc Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 11 Feb 2013 20:12:33 +0100 Subject: [PATCH 13/42] Browser API cleanup (pornographically named method moved out of public interface) --- .../intellij/ide/BrowserSettingsProvider.java | 8 +- .../intellij/ide/BrowserSettingsPanel.java | 17 +--- .../src/messages/XmlBundle.properties | 4 +- .../src/META-INF/XmlPlugin.xml | 2 +- .../ide/browsers/BrowsersConfiguration.java | 48 ---------- .../ide/browsers/WebBrowsersPanel.java | 93 +++++++++++-------- .../impl/BrowserConfigurationHelper.java | 64 +++++++++++++ .../BrowserSettingsProviderImpl.java | 19 +--- 8 files changed, 128 insertions(+), 127 deletions(-) create mode 100644 xml/impl/src/com/intellij/ide/browsers/impl/BrowserConfigurationHelper.java rename xml/impl/src/com/intellij/ide/browsers/{ => impl}/BrowserSettingsProviderImpl.java (74%) diff --git a/platform/platform-api/src/com/intellij/ide/BrowserSettingsProvider.java b/platform/platform-api/src/com/intellij/ide/BrowserSettingsProvider.java index 01f628bb0e4f..63576284ba03 100644 --- a/platform/platform-api/src/com/intellij/ide/BrowserSettingsProvider.java +++ b/platform/platform-api/src/com/intellij/ide/BrowserSettingsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -21,8 +21,6 @@ import com.intellij.openapi.options.UnnamedConfigurable; * @author spleaner */ public abstract class BrowserSettingsProvider implements UnnamedConfigurable { - public void disposeUIResources() { - } - - public void applySettingsFromWindowsRegistry() {} + @Override + public void disposeUIResources() { } } diff --git a/platform/platform-impl/src/com/intellij/ide/BrowserSettingsPanel.java b/platform/platform-impl/src/com/intellij/ide/BrowserSettingsPanel.java index 54a77de5aa90..0a66235679e3 100644 --- a/platform/platform-impl/src/com/intellij/ide/BrowserSettingsPanel.java +++ b/platform/platform-impl/src/com/intellij/ide/BrowserSettingsPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -111,21 +111,6 @@ public class BrowserSettingsPanel extends JPanel { for (BrowserSettingsProvider settingsProvider : mySettingsProviders) { outerPanel.add(settingsProvider.createComponent()); } - if (SystemInfo.isWindows) { - JPanel wrapperPanel = new JPanel(new BorderLayout()); - JButton registryButton = new JButton("Retrieve settings from Windows registry"); - registryButton.setMnemonic('W'); - registryButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - for (BrowserSettingsProvider settingsProvider : mySettingsProviders) { - settingsProvider.applySettingsFromWindowsRegistry(); - } - } - }); - wrapperPanel.add(registryButton, BorderLayout.EAST); - outerPanel.add(wrapperPanel); - } add(outerPanel, BorderLayout.NORTH); } diff --git a/platform/platform-resources-en/src/messages/XmlBundle.properties b/platform/platform-resources-en/src/messages/XmlBundle.properties index e581c3658a20..04ed0e5f9dbe 100644 --- a/platform/platform-resources-en/src/messages/XmlBundle.properties +++ b/platform/platform-resources-en/src/messages/XmlBundle.properties @@ -248,4 +248,6 @@ zen.coding.incorrect.abbreviation.error=Incorrect abbreviation title.cannot.create.html.file=Cannot create HTML file new.html.file.action=HTML File new.html.file.action.description=Creates new HTML file -html5.outline.mode=HTML5 Outline \ No newline at end of file +html5.outline.mode=HTML5 Outline + +read.win.registry=Retrieve settings from &Windows registry diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index f8aa0b319f3e..5bf0b9d30736 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -375,7 +375,7 @@ - + diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java index fa4a3c37be9e..3eafa6e21725 100644 --- a/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java +++ b/xml/impl/src/com/intellij/ide/browsers/BrowsersConfiguration.java @@ -24,7 +24,6 @@ import com.intellij.openapi.components.*; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.WindowsRegistryUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; @@ -38,7 +37,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.File; import java.util.ArrayList; -import java.util.EnumMap; import java.util.List; import java.util.Map; @@ -255,50 +253,4 @@ public class BrowsersConfiguration implements PersistentStateComponent return null; } - - /** - * Gets data from Windows registry, may take some time to run (up to ~300ms) - * - * @return Map[BrowserFamily -> "path to .exe"] - */ - @NotNull - public static EnumMap getWindowsBrowsersEXE() { - EnumMap map = new EnumMap(BrowserFamily.class); - if (SystemInfo.isWindows) { - List sections = WindowsRegistryUtil.readRegistryBranch("HKEY_LOCAL_MACHINE\\SOFTWARE\\Clients\\StartMenuInternet"); - for (String section : sections) { - BrowserFamily family = getFamily(section); - if (family == null) { - continue; //We ignore "unknown" browsers like Maxthon, RockMelt, SeaMonkey, Deepnet Explorer, Avant Browser etc. - } - String pathToExe = WindowsRegistryUtil.readRegistryDefault( - "HKLM\\SOFTWARE\\Clients\\StartMenuInternet\\" + section + "\\shell\\open\\command"); - if (pathToExe != null) { - map.put(family, pathToExe); - } - } - } - return map; - } - - @Nullable - private static BrowserFamily getFamily(String registryName) { - registryName = registryName.toLowerCase(); - if (registryName.contains("firefox")) { - return BrowserFamily.FIREFOX; - } - if (registryName.contains("iexplore")) { - return BrowserFamily.EXPLORER; - } - if (registryName.contains("opera")) { - return BrowserFamily.OPERA; - } - if (registryName.contains("safari")) { - return BrowserFamily.SAFARI; - } - if (registryName.contains("google")) { - return BrowserFamily.CHROME; - } - return null; - } } diff --git a/xml/impl/src/com/intellij/ide/browsers/WebBrowsersPanel.java b/xml/impl/src/com/intellij/ide/browsers/WebBrowsersPanel.java index e5f53e7f8268..a7debbe2c2c2 100644 --- a/xml/impl/src/com/intellij/ide/browsers/WebBrowsersPanel.java +++ b/xml/impl/src/com/intellij/ide/browsers/WebBrowsersPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -16,13 +16,14 @@ package com.intellij.ide.browsers; import com.intellij.ide.IdeBundle; +import com.intellij.ide.browsers.impl.BrowserConfigurationHelper; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.ui.IdeBorderFactory; import com.intellij.util.containers.HashMap; import com.intellij.xml.XmlBundle; @@ -32,7 +33,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.EnumMap; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -60,6 +60,8 @@ public class WebBrowsersPanel extends JPanel { createIndividualSettings(BrowsersConfiguration.BrowserFamily.SAFARI, mySettingsPanel); createIndividualSettings(BrowsersConfiguration.BrowserFamily.CHROME, mySettingsPanel); createIndividualSettings(BrowsersConfiguration.BrowserFamily.OPERA, mySettingsPanel); + + createPlatformSpecificAction(mySettingsPanel); } private void createIndividualSettings(@NotNull final BrowsersConfiguration.BrowserFamily family, final JPanel container) { @@ -125,53 +127,62 @@ public class WebBrowsersPanel extends JPanel { if (settings == null) { settings = family.createBrowserSpecificSettings(); } - - if (ShowSettingsUtil.getInstance().editConfigurable(mySettingsPanel, settings.createConfigurable())) { + if (settings != null && ShowSettingsUtil.getInstance().editConfigurable(mySettingsPanel, settings.createConfigurable())) { myConfiguration.updateBrowserSpecificSettings(family, settings); } } - public void applySettingsFromWindowsRegistry() { - if (!SystemInfo.isWindows) { - return; - } - ApplicationManager.getApplication() - .executeOnPooledThread(new SwingWorker, Void>() { + private void createPlatformSpecificAction(JPanel container) { + if (SystemInfo.isWindows) { + JButton registryButton = new JButton(XmlBundle.message("read.win.registry")); + registryButton.addActionListener(new ActionListener() { @Override - protected EnumMap doInBackground() throws Exception { - return BrowsersConfiguration.getWindowsBrowsersEXE(); - } - - @Override - protected void done() { - EnumMap map = null; - try { - map = get(); - } - catch (InterruptedException ignored) { - } - catch (ExecutionException ignored) { - } - if (myBrowserSettingsMap == null) { - return;//we are disposed - } - if (map != null && !map.isEmpty()) { - for (BrowsersConfiguration.BrowserFamily family : BrowsersConfiguration.BrowserFamily.values()) { - Pair pair = myBrowserSettingsMap.get(family); - String pathToExe = map.get(family); - if (pathToExe != null) { - pair.first.setSelected(true); - pair.second.setText(pathToExe); - } - else { - pair.first.setSelected(false); - } - } - } + public void actionPerformed(ActionEvent e) { + applySettingsFromWindowsRegistry(); } }); + + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + panel.add(registryButton, BorderLayout.EAST); + container.add(panel); + } } + private void applySettingsFromWindowsRegistry() { + ApplicationManager.getApplication().executeOnPooledThread(new SwingWorker, Void>() { + @Override + protected Map doInBackground() throws Exception { + return BrowserConfigurationHelper.getBrowserPathsFromRegistry(); + } + + @Override + protected void done() { + Map map = null; + try { + map = get(); + } + catch (InterruptedException ignore) { } + catch (ExecutionException ignore) { } + + if (myBrowserSettingsMap == null || map == null || map.isEmpty()) { + return; + } + + for (BrowsersConfiguration.BrowserFamily family : BrowsersConfiguration.BrowserFamily.values()) { + Pair pair = myBrowserSettingsMap.get(family); + String pathToExe = map.get(family); + if (pathToExe != null) { + pair.first.setSelected(true); + pair.second.setText(pathToExe); + } + else { + pair.first.setSelected(false); + } + } + } + }); + } public void dispose() { myBrowserSettingsMap = null; diff --git a/xml/impl/src/com/intellij/ide/browsers/impl/BrowserConfigurationHelper.java b/xml/impl/src/com/intellij/ide/browsers/impl/BrowserConfigurationHelper.java new file mode 100644 index 000000000000..c534910d003e --- /dev/null +++ b/xml/impl/src/com/intellij/ide/browsers/impl/BrowserConfigurationHelper.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2013 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.ide.browsers.impl; + +import com.intellij.ide.browsers.BrowsersConfiguration; +import com.intellij.openapi.util.io.WindowsRegistryUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.EnumMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +public class BrowserConfigurationHelper { + private static final String START_MENU_KEY = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Clients\\StartMenuInternet"; + + /** + * Read data from Windows registry (may take some time to run). + */ + @NotNull + public static Map getBrowserPathsFromRegistry() { + Map map = + new EnumMap(BrowsersConfiguration.BrowserFamily.class); + + List sections = WindowsRegistryUtil.readRegistryBranch(START_MENU_KEY); + for (String section : sections) { + BrowsersConfiguration.BrowserFamily family = getFamily(section); + if (family != null) { + String pathToExe = WindowsRegistryUtil.readRegistryDefault(START_MENU_KEY + "\\" + section + "\\shell\\open\\command"); + if (pathToExe != null) { + map.put(family, pathToExe); + } + } + } + + return map; + } + + @Nullable + private static BrowsersConfiguration.BrowserFamily getFamily(String registryName) { + registryName = registryName.toLowerCase(); + for (BrowsersConfiguration.BrowserFamily family : BrowsersConfiguration.BrowserFamily.values()) { + if (registryName.contains(family.getName().toLowerCase(Locale.US))) { + return family; + } + } + + return null; + } +} diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowserSettingsProviderImpl.java b/xml/impl/src/com/intellij/ide/browsers/impl/BrowserSettingsProviderImpl.java similarity index 74% rename from xml/impl/src/com/intellij/ide/browsers/BrowserSettingsProviderImpl.java rename to xml/impl/src/com/intellij/ide/browsers/impl/BrowserSettingsProviderImpl.java index e639095481a6..568a265d1a57 100644 --- a/xml/impl/src/com/intellij/ide/browsers/BrowserSettingsProviderImpl.java +++ b/xml/impl/src/com/intellij/ide/browsers/impl/BrowserSettingsProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.ide.browsers; +package com.intellij.ide.browsers.impl; import com.intellij.ide.BrowserSettingsProvider; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.ide.browsers.BrowsersConfiguration; +import com.intellij.ide.browsers.WebBrowsersPanel; import com.intellij.openapi.options.ConfigurationException; import org.jetbrains.annotations.NotNull; @@ -26,8 +27,6 @@ import javax.swing.*; * @author spleaner */ public class BrowserSettingsProviderImpl extends BrowserSettingsProvider { - private static final Logger LOG = Logger.getInstance("#com.intellij.ide.browsers.BrowserSettingsProviderImpl"); - private WebBrowsersPanel mySettingsPanel; private final BrowsersConfiguration myConfiguration; @@ -35,12 +34,6 @@ public class BrowserSettingsProviderImpl extends BrowserSettingsProvider { myConfiguration = configuration; } - @Override - public void applySettingsFromWindowsRegistry() { - if (mySettingsPanel != null) - mySettingsPanel.applySettingsFromWindowsRegistry(); - } - public JComponent createComponent() { if (mySettingsPanel == null) { mySettingsPanel = new WebBrowsersPanel(myConfiguration); @@ -50,17 +43,14 @@ public class BrowserSettingsProviderImpl extends BrowserSettingsProvider { } public boolean isModified() { - LOG.assertTrue(mySettingsPanel != null); return mySettingsPanel.isModified(); } public void apply() throws ConfigurationException { - LOG.assertTrue(mySettingsPanel != null); mySettingsPanel.apply(); } public void reset() { - LOG.assertTrue(mySettingsPanel != null); mySettingsPanel.reset(); } @@ -68,5 +58,4 @@ public class BrowserSettingsProviderImpl extends BrowserSettingsProvider { mySettingsPanel.dispose(); mySettingsPanel = null; } - } From bfff38cf9dbe7ec5b5be1a19877c3c057dfaefb5 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Mon, 11 Feb 2013 22:24:05 +0400 Subject: [PATCH 14/42] RUBY-13071: (refactoring) work with RegExpLanguageHost encapsulated into RegExpLanguageHosts --- .../lang/regexp/RegExpLanguageHosts.java | 68 ++++++++++++++++++- .../regexp/validation/RegExpAnnotator.java | 47 +++---------- 2 files changed, 76 insertions(+), 39 deletions(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java index d36e7e6a009c..e70cf47b3f94 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java @@ -15,15 +15,79 @@ */ package org.intellij.lang.regexp; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.util.ClassExtension; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; +import org.intellij.lang.regexp.psi.RegExpChar; +import org.intellij.lang.regexp.psi.RegExpGroup; +import org.intellij.lang.regexp.psi.RegExpPyCondRef; +import org.intellij.lang.regexp.psi.RegExpQuantifier; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author yole */ -public class RegExpLanguageHosts extends ClassExtension { - public static final RegExpLanguageHosts INSTANCE = new RegExpLanguageHosts(); +public final class RegExpLanguageHosts extends ClassExtension { + private static final RegExpLanguageHosts INSTANCE = new RegExpLanguageHosts(); + + public static RegExpLanguageHosts getInstance() { + return INSTANCE; + } private RegExpLanguageHosts() { super("com.intellij.regExpLanguageHost"); } + + @Nullable + private static RegExpLanguageHost findRegExpHost(@Nullable final PsiElement element) { + if (element == null) { + return null; + } + PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); + if (host instanceof RegExpLanguageHost) { + return (RegExpLanguageHost)host; + } + if (host != null) { + return INSTANCE.forClass(host.getClass()); + } + return null; + } + + public boolean isRedundantEscape(@NotNull final RegExpChar ch, @NotNull final String text) { + if (text.length() <= 1) { + return false; + } + final RegExpLanguageHost host = findRegExpHost(ch); + if (host != null) { + final char c = text.charAt(1); + final boolean needsEscaping = host.characterNeedsEscaping(c); + return !needsEscaping; + } + else { + return !("\\]".equals(text) || "\\}".equals(text)); + } + } + + public boolean supportsNamedGroupSyntax(@Nullable final RegExpGroup group) { + final RegExpLanguageHost host = findRegExpHost(group); + return host != null && host.supportsNamedGroupSyntax(group); + } + + public boolean supportsPerl5EmbeddedComments(@Nullable final PsiComment comment) { + final RegExpLanguageHost host = findRegExpHost(comment); + return host != null && host.supportsPerl5EmbeddedComments(); + } + + public boolean supportsPythonConditionalRefs(@Nullable final RegExpPyCondRef condRef) { + final RegExpLanguageHost host = findRegExpHost(condRef); + return host != null && host.supportsPythonConditionalRefs(); + } + + public boolean supportsPossessiveQuantifiers(@Nullable final RegExpQuantifier quantifier) { + final RegExpLanguageHost host = findRegExpHost(quantifier); + return host != null && host.supportsPossessiveQuantifiers(); + } } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java index 29626c69d04d..e6e7a021f91f 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java @@ -21,20 +21,22 @@ import com.intellij.lang.ASTNode; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; -import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.util.PsiTreeUtil; import org.intellij.lang.regexp.*; import org.intellij.lang.regexp.psi.*; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.math.BigInteger; public final class RegExpAnnotator extends RegExpElementVisitor implements Annotator { private AnnotationHolder myHolder; + private final RegExpLanguageHosts myLanguageHosts; + + public RegExpAnnotator() { + myLanguageHosts = RegExpLanguageHosts.getInstance(); + } public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) { assert myHolder == null : "unsupported concurrent annotator invocation"; @@ -95,7 +97,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } else { final String text = ch.getUnescapedText(); - if (text.startsWith("\\") && isRedundantEscape(ch, text)) { + if (text.startsWith("\\") && myLanguageHosts.isRedundantEscape(ch, text)) { final ASTNode astNode = ch.getNode().getFirstChildNode(); if (astNode != null && astNode.getElementType() == RegExpTT.REDUNDANT_ESCAPE) { final Annotation a = myHolder.createWeakWarningAnnotation(ch, "Redundant character escape"); @@ -105,31 +107,6 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } } - private static boolean isRedundantEscape(RegExpChar ch, String text) { - if (text.length() <= 1) return false; - RegExpLanguageHost host = findRegExpHost(ch); - if (host != null) { - final char c = text.charAt(1); - final boolean needsEscaping = host.characterNeedsEscaping(c); - return !needsEscaping; - } - else { - return !("\\]".equals(text) || "\\}".equals(text)); - } - } - - @Nullable - private static RegExpLanguageHost findRegExpHost(PsiElement element) { - PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); - if (host instanceof RegExpLanguageHost) { - return (RegExpLanguageHost)host; - } - if (host != null) { - return RegExpLanguageHosts.INSTANCE.forClass(host.getClass()); - } - return null; - } - public void visitRegExpProperty(RegExpProperty property) { final ASTNode category = property.getCategoryNode(); if (category == null) { @@ -180,8 +157,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } } if (group.isPythonNamedGroup() || group.isRubyNamedGroup()) { - RegExpLanguageHost host = findRegExpHost(group); - if (host == null || !host.supportsNamedGroupSyntax(group)) { + if (!myLanguageHosts.supportsNamedGroupSyntax(group)) { myHolder.createErrorAnnotation(group, "This named group syntax is not supported"); } } @@ -212,8 +188,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitComment(PsiComment comment) { if (comment.getText().startsWith("(?#")) { - RegExpLanguageHost host = findRegExpHost(comment); - if (host == null || !host.supportsPerl5EmbeddedComments()) { + if (!myLanguageHosts.supportsPerl5EmbeddedComments(comment)) { myHolder.createErrorAnnotation(comment, "Embedded comments are not supported"); } } @@ -221,8 +196,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpPyCondRef(RegExpPyCondRef condRef) { - RegExpLanguageHost host = findRegExpHost(condRef); - if (host == null || !host.supportsPythonConditionalRefs()) { + if (!myLanguageHosts.supportsPythonConditionalRefs(condRef)) { myHolder.createErrorAnnotation(condRef, "Conditional references are not supported"); } } @@ -280,8 +254,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } } if (quantifier.getType() == RegExpQuantifier.Type.POSSESSIVE) { - RegExpLanguageHost host = findRegExpHost(quantifier); - if (host != null && !host.supportsPossessiveQuantifiers()) { + if (!myLanguageHosts.supportsPossessiveQuantifiers(quantifier)) { myHolder.createErrorAnnotation(quantifier, "Nested quantifier in regexp"); } } From 40663aef8f53ee186285a2fe73893abdffbb5676 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Mon, 11 Feb 2013 23:57:10 +0400 Subject: [PATCH 15/42] RUBY-13071: (refactoring) RegExpPropertiesProvider iface merged into RegExpLanguageHost --- .../DefaultRegExpPropertiesProvider.java | 14 ++++--- .../regexp/RegExpCompletionContributor.java | 14 ++----- .../regexp/RegExpDocumentationProvider.java | 2 +- .../lang/regexp/RegExpLanguageHost.java | 10 +++++ .../lang/regexp/RegExpLanguageHosts.java | 31 ++++++++++++++++ .../lang/regexp/RegExpPropertiesProvider.java | 17 --------- .../regexp/RegExpPropertiesProviders.java | 21 ----------- .../regexp/psi/impl/RegExpPropertyImpl.java | 4 +- .../regexp/validation/RegExpAnnotator.java | 3 +- .../test/test/RegExpCompletionTest.java | 7 ++-- .../com/intellij/psi/impl/JavaRegExpHost.java | 37 ++++++++++++++++++- 11 files changed, 95 insertions(+), 65 deletions(-) delete mode 100644 RegExpSupport/src/org/intellij/lang/regexp/RegExpPropertiesProvider.java delete mode 100644 RegExpSupport/src/org/intellij/lang/regexp/RegExpPropertiesProviders.java diff --git a/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java b/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java index 5c88ac26106c..b0e6e888a810 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java @@ -4,7 +4,13 @@ import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -final class DefaultRegExpPropertiesProvider implements RegExpPropertiesProvider { +public final class DefaultRegExpPropertiesProvider { + private static final DefaultRegExpPropertiesProvider INSTANCE = new DefaultRegExpPropertiesProvider(); + + public static DefaultRegExpPropertiesProvider getInstance() { + return INSTANCE; + } + private final String[][] myPropertyNames = { { "Cn", "UNASSIGNED" }, { "Lu", "UPPERCASE_LETTER" }, @@ -98,10 +104,9 @@ final class DefaultRegExpPropertiesProvider implements RegExpPropertiesProvider {"e", "escape character ('\\u001B')"} }; - public DefaultRegExpPropertiesProvider() { + private DefaultRegExpPropertiesProvider() { } - @Override public boolean isValidCategory(@NotNull String category) { if (category.startsWith("In")) { try { @@ -121,7 +126,6 @@ final class DefaultRegExpPropertiesProvider implements RegExpPropertiesProvider return false; } - @Override @Nullable public String getPropertyDescription(@Nullable final String name) { if (StringUtil.isEmptyOrSpaces(name)) { @@ -135,14 +139,12 @@ final class DefaultRegExpPropertiesProvider implements RegExpPropertiesProvider return null; } - @Override @NotNull public String[][] getAllKnownProperties() { return myPropertyNames; } @NotNull - @Override public String[][] getKnownCharacterClasses() { return myCharacterClasses; } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java index 158f4a90534f..51f1bd83ba04 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpCompletionContributor.java @@ -90,7 +90,7 @@ public final class RegExpCompletionContributor extends CompletionContributor { public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) { - for (String[] stringArray : getProvider(parameters).getAllKnownProperties()) { + for (String[] stringArray : RegExpLanguageHosts.getInstance().getAllKnownProperties(parameters.getPosition())) { result.addElement( TailTypeDecorator.withTail(createLookupElement(stringArray[0], null, emptyIcon), TailType.createSimpleTailType('}'))); } @@ -102,7 +102,7 @@ public final class RegExpCompletionContributor extends CompletionContributor { public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) { - for (String[] stringArray : getProvider(parameters).getAllKnownProperties()) { + for (String[] stringArray : RegExpLanguageHosts.getInstance().getAllKnownProperties(parameters.getPosition())) { addLookupElement(result, "{" + stringArray[0] + "}", stringArray.length > 1 ? stringArray[1]:null, PlatformIcons.PROPERTY_ICON); } } @@ -114,19 +114,13 @@ public final class RegExpCompletionContributor extends CompletionContributor { final ProcessingContext context, @NotNull final CompletionResultSet result) { - final RegExpPropertiesProvider provider = getProvider(parameters); - for (final String[] completion : provider.getKnownCharacterClasses()) { + for (final String[] completion : RegExpLanguageHosts.getInstance().getKnownCharacterClasses(parameters.getPosition())) { addLookupElement(result, completion[0], completion[1], emptyIcon); } - for (String[] stringArray : provider.getAllKnownProperties()) { + for (String[] stringArray : RegExpLanguageHosts.getInstance().getAllKnownProperties(parameters.getPosition())) { addLookupElement(result, "p{" + stringArray[0] + "}", stringArray.length > 1? stringArray[1]:null, PlatformIcons.PROPERTY_ICON); } } } - - @NotNull - private static RegExpPropertiesProvider getProvider(@NotNull final CompletionParameters parameters) { - return RegExpPropertiesProviders.getInstance().forLanguage(parameters.getOriginalFile().getLanguage()); - } } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java index 86add8bd7658..7f1da1937ee4 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpDocumentationProvider.java @@ -34,7 +34,7 @@ public final class RegExpDocumentationProvider extends AbstractDocumentationProv final RegExpProperty prop = (RegExpProperty)element; final ASTNode node = prop.getCategoryNode(); if (node != null) { - final String description = RegExpPropertiesProviders.forNode(node).getPropertyDescription(node.getText()); + final String description = RegExpLanguageHosts.getInstance().getPropertyDescription(node.getPsi(), node.getText()); if (description != null) { if (prop.isNegated()) { return "Property block stands for characters not matching " + description; diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java index c283f19e87af..9208a3239fc3 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java @@ -16,6 +16,8 @@ package org.intellij.lang.regexp; import org.intellij.lang.regexp.psi.RegExpGroup; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author yole @@ -26,4 +28,12 @@ public interface RegExpLanguageHost { boolean supportsPossessiveQuantifiers(); boolean supportsPythonConditionalRefs(); boolean supportsNamedGroupSyntax(RegExpGroup group); + + boolean isValidCategory(@NotNull String category); + @NotNull + String[][] getAllKnownProperties(); + @Nullable + String getPropertyDescription(@Nullable final String name); + @NotNull + String[][] getKnownCharacterClasses(); } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java index e70cf47b3f94..636c97193d2a 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java @@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable; */ public final class RegExpLanguageHosts extends ClassExtension { private static final RegExpLanguageHosts INSTANCE = new RegExpLanguageHosts(); + private final DefaultRegExpPropertiesProvider myDefaultProvider; public static RegExpLanguageHosts getInstance() { return INSTANCE; @@ -39,6 +40,7 @@ public final class RegExpLanguageHosts extends ClassExtension { - private static final RegExpPropertiesProviders INSTANCE = new RegExpPropertiesProviders(); - - public static RegExpPropertiesProviders getInstance() { - return INSTANCE; - } - - public RegExpPropertiesProviders() { - super("com.intellij.regExpPropertiesProvider", new DefaultRegExpPropertiesProvider()); - } - - public static RegExpPropertiesProvider forNode(@NotNull final ASTNode node) { - return getInstance().forLanguage(node.getPsi().getContainingFile().getLanguage()); - } -} diff --git a/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpPropertyImpl.java b/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpPropertyImpl.java index 42ddbebdf31e..5c97ac35489b 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpPropertyImpl.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpPropertyImpl.java @@ -25,7 +25,7 @@ import com.intellij.psi.PsiReference; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PlatformIcons; -import org.intellij.lang.regexp.RegExpPropertiesProviders; +import org.intellij.lang.regexp.RegExpLanguageHosts; import org.intellij.lang.regexp.RegExpTT; import org.intellij.lang.regexp.psi.RegExpElementVisitor; import org.intellij.lang.regexp.psi.RegExpProperty; @@ -106,7 +106,7 @@ public class RegExpPropertyImpl extends RegExpElementImpl implements RegExpPrope if (categoryNode != null && categoryNode.getText().startsWith("In") && !categoryNode.getText().startsWith("Intelli")) { return UNICODE_BLOCKS; } else { - final String[][] knownProperties = RegExpPropertiesProviders.forNode(getNode()).getAllKnownProperties(); + final String[][] knownProperties = RegExpLanguageHosts.getInstance().getAllKnownProperties(getElement()); final Object[] objects = new Object[knownProperties.length]; for (int i = 0; i < objects.length; i++) { final String[] prop = knownProperties[i]; diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java index e6e7a021f91f..1d32bf8ab6eb 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java @@ -112,8 +112,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot if (category == null) { return; } - final RegExpPropertiesProvider provider = RegExpPropertiesProviders.forNode(category); - if(!provider.isValidCategory(category.getText())) { + if(!myLanguageHosts.isValidCategory(category.getPsi(), category.getText())) { final Annotation a = myHolder.createErrorAnnotation(category, "Unknown character category"); if (a != null) { // IDEA-9381 diff --git a/RegExpSupport/test/test/RegExpCompletionTest.java b/RegExpSupport/test/test/RegExpCompletionTest.java index 6d2fd262d7c9..a408a540a99a 100644 --- a/RegExpSupport/test/test/RegExpCompletionTest.java +++ b/RegExpSupport/test/test/RegExpCompletionTest.java @@ -19,8 +19,7 @@ import com.intellij.openapi.application.PathManager; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase; import com.intellij.util.ArrayUtil; -import org.intellij.lang.regexp.RegExpLanguage; -import org.intellij.lang.regexp.RegExpPropertiesProviders; +import org.intellij.lang.regexp.DefaultRegExpPropertiesProvider; import java.io.File; import java.util.ArrayList; @@ -60,7 +59,7 @@ public class RegExpCompletionTest extends CodeInsightFixtureTestCase { private void doBackSlashVariantsTest() throws Throwable { java.util.List nameList = new ArrayList(Arrays.asList("d", "D", "s", "S", "w", "W", "b", "B", "A", "G", "Z", "z", "Q", "E", "t", "n", "r", "f", "a", "e")); - for (String[] stringArray : RegExpPropertiesProviders.getInstance().forLanguage(RegExpLanguage.INSTANCE).getAllKnownProperties()) { + for (String[] stringArray : DefaultRegExpPropertiesProvider.getInstance().getAllKnownProperties()) { nameList.add("p{" + stringArray[0] + "}"); } myFixture.testCompletionVariants(getInputDataFileName(getTestName(true)), ArrayUtil.toStringArray(nameList)); @@ -68,7 +67,7 @@ public class RegExpCompletionTest extends CodeInsightFixtureTestCase { public void testPropertyVariants() throws Throwable { java.util.List nameList = new ArrayList(); - for (String[] stringArray : RegExpPropertiesProviders.getInstance().forLanguage(RegExpLanguage.INSTANCE).getAllKnownProperties()) { + for (String[] stringArray : DefaultRegExpPropertiesProvider.getInstance().getAllKnownProperties()) { nameList.add("{" + stringArray[0] + "}"); } myFixture.testCompletionVariants(getInputDataFileName(getTestName(true)), ArrayUtil.toStringArray(nameList)); diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaRegExpHost.java b/java/java-impl/src/com/intellij/psi/impl/JavaRegExpHost.java index 6d05e6aff9dd..21a03d7e2bc3 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaRegExpHost.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaRegExpHost.java @@ -16,18 +16,28 @@ package com.intellij.psi.impl; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ModuleRootManager; +import org.intellij.lang.regexp.DefaultRegExpPropertiesProvider; import org.intellij.lang.regexp.RegExpLanguageHost; import org.intellij.lang.regexp.psi.RegExpGroup; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author yole */ public class JavaRegExpHost implements RegExpLanguageHost { + + private final DefaultRegExpPropertiesProvider myPropertiesProvider; + + public JavaRegExpHost() { + myPropertiesProvider = DefaultRegExpPropertiesProvider.getInstance(); + } + @Override public boolean characterNeedsEscaping(char c) { return c == ']' || c == '}'; @@ -51,7 +61,7 @@ public class JavaRegExpHost implements RegExpLanguageHost { @Override public boolean supportsNamedGroupSyntax(RegExpGroup group) { if (group.isRubyNamedGroup()) { - final Module module = ModuleUtil.findModuleForPsiElement(group); + final Module module = ModuleUtilCore.findModuleForPsiElement(group); if (module != null) { final Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); if (sdk != null && sdk.getSdkType() instanceof JavaSdk) { @@ -62,4 +72,27 @@ public class JavaRegExpHost implements RegExpLanguageHost { } return false; } + + @Override + public boolean isValidCategory(@NotNull String category) { + return myPropertiesProvider.isValidCategory(category); + } + + @NotNull + @Override + public String[][] getAllKnownProperties() { + return myPropertiesProvider.getAllKnownProperties(); + } + + @Nullable + @Override + public String getPropertyDescription(@Nullable String name) { + return myPropertiesProvider.getPropertyDescription(name); + } + + @NotNull + @Override + public String[][] getKnownCharacterClasses() { + return myPropertiesProvider.getKnownCharacterClasses(); + } } From 149159c6cfc45f99b11010482b3a148d5c8d7f37 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 11 Feb 2013 21:09:30 +0100 Subject: [PATCH 16/42] IDEA-100840 ("No-op method in abstract class": Complains about native methods) --- .../NoopMethodInAbstractClassInspection.java | 17 ++++++----------- .../NoopMethodInAbstractClass.java | 8 ++++++++ .../noop_method_in_abstract_class/expected.xml | 9 +++++++++ ...NoopMethodInAbstractClassInspectionTest.java | 10 ++++++++++ 4 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/NoopMethodInAbstractClass.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/expected.xml create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspectionTest.java diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspection.java index 761a5ed58279..dfcd908d8e77 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,26 +28,22 @@ public class NoopMethodInAbstractClassInspection extends BaseInspection { @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "noop.method.in.abstract.class.display.name"); + return InspectionGadgetsBundle.message("noop.method.in.abstract.class.display.name"); } @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "noop.method.in.abstract.class.problem.descriptor"); + return InspectionGadgetsBundle.message("noop.method.in.abstract.class.problem.descriptor"); } public BaseInspectionVisitor buildVisitor() { return new NoopMethodInAbstractClassVisitor(); } - private static class NoopMethodInAbstractClassVisitor - extends BaseInspectionVisitor { + private static class NoopMethodInAbstractClassVisitor extends BaseInspectionVisitor { @Override public void visitMethod(@NotNull PsiMethod method) { - //no call to super, so we don't drill into anonymous classes if (method.isConstructor()) { return; } @@ -55,14 +51,13 @@ public class NoopMethodInAbstractClassInspection extends BaseInspection { if (containingClass == null) { return; } - if (containingClass.isInterface() || - containingClass.isAnnotationType()) { + if (containingClass.isInterface() || containingClass.isAnnotationType()) { return; } if (!containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) { return; } - if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.NATIVE)) { return; } if (!MethodUtils.isEmpty(method)) { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/NoopMethodInAbstractClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/NoopMethodInAbstractClass.java new file mode 100644 index 000000000000..214152da741d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/NoopMethodInAbstractClass.java @@ -0,0 +1,8 @@ +package com.siyeh.igtest.classlayout.noop_method_in_abstract_class; + +abstract class NoopMethodInAbstractClass { + + void foo() {} + + native int bar(); +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/expected.xml new file mode 100644 index 000000000000..79ebd7255099 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/classlayout/noop_method_in_abstract_class/expected.xml @@ -0,0 +1,9 @@ + + + + NoopMethodInAbstractClass.java + 5 + No-op method in abstract class + No-op Method <code>foo()</code> should be made abstract #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspectionTest.java new file mode 100644 index 000000000000..a7737a07f77c --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/classlayout/NoopMethodInAbstractClassInspectionTest.java @@ -0,0 +1,10 @@ +package com.siyeh.ig.classlayout; + +import com.siyeh.ig.IGInspectionTestCase; + +public class NoopMethodInAbstractClassInspectionTest extends IGInspectionTestCase { + + public void test() throws Exception { + doTest("com/siyeh/igtest/classlayout/noop_method_in_abstract_class", new NoopMethodInAbstractClassInspection()); + } +} \ No newline at end of file From f6c91bd770f4bdf7ccc2603356d1b2c98a8d68e6 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 11 Feb 2013 21:18:54 +0100 Subject: [PATCH 17/42] external build: perform dependency analysis and mark found dependencies even if there were errors during the first phase of make. Integration of changes, on the other hand, should happen only if the corresponding phase of make succeeds --- .../jetbrains/jps/builders/java/JavaBuilderUtil.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java index 58b6a4ca4aba..db367a6d56d5 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java @@ -67,9 +67,6 @@ public class JavaBuilderUtil { ModuleChunk chunk, Collection filesToCompile, Collection successfullyCompiled) throws IOException { - if (Utils.errorsDetected(context)) { - return false; - } try { boolean additionalPassRequired = false; @@ -161,6 +158,14 @@ public class JavaBuilderUtil { globalMappings.differentiateOnRebuild(delta); } + if (Utils.errorsDetected(context)) { + // important: perform dependency analysis and mark found dependencies even if there were errors during the first phase of make. + // Integration of changes should happen only if the corresponding phase of make succeeds + // In case of errors this wil ensure that all dependencies marked after the first phase + // will be compiled during the first phase of the next make + return false; + } + context.processMessage(new ProgressMessage("Updating dependency information... [" + chunk.getName() + "]")); globalMappings.integrate(delta); From 8d38241ecebc2d659d04d02acb535a1e0ba0d139 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Feb 2013 15:53:13 +0100 Subject: [PATCH 18/42] don't highlight empty headless-implementation-class as error --- plugins/devkit/src/dom/Component.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/devkit/src/dom/Component.java b/plugins/devkit/src/dom/Component.java index ddb9cec7250f..aa5936b30a3c 100644 --- a/plugins/devkit/src/dom/Component.java +++ b/plugins/devkit/src/dom/Component.java @@ -44,6 +44,7 @@ public interface Component extends DomElement { @NotNull @Convert(PluginPsiClassConverter.class) + @ExtendClass(allowEmpty=true) GenericDomValue getHeadlessImplementationClass(); @NotNull From b05ab2863cc36787b7bf5499e5eeac1200d78af6 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Feb 2013 17:55:21 +0100 Subject: [PATCH 19/42] initial version of quickfix to register extension point --- plugins/devkit/resources/META-INF/plugin.xml | 2 +- .../quickfix/RegisterExtensionFix.java | 92 ++++++++++++++++ .../RegisterExtensionFixProvider.java | 101 ++++++++++++++++++ .../quickfix/RegisterInspectionFix.java | 23 ++-- .../RegisterInspectionFixProvider.java | 50 --------- 5 files changed, 211 insertions(+), 57 deletions(-) create mode 100644 plugins/devkit/src/inspections/quickfix/RegisterExtensionFix.java create mode 100644 plugins/devkit/src/inspections/quickfix/RegisterExtensionFixProvider.java delete mode 100644 plugins/devkit/src/inspections/quickfix/RegisterInspectionFixProvider.java diff --git a/plugins/devkit/resources/META-INF/plugin.xml b/plugins/devkit/resources/META-INF/plugin.xml index 3ef7a655605c..8413b924237f 100644 --- a/plugins/devkit/resources/META-INF/plugin.xml +++ b/plugins/devkit/resources/META-INF/plugin.xml @@ -84,7 +84,7 @@ - + diff --git a/plugins/devkit/src/inspections/quickfix/RegisterExtensionFix.java b/plugins/devkit/src/inspections/quickfix/RegisterExtensionFix.java new file mode 100644 index 000000000000..f233f6ea4821 --- /dev/null +++ b/plugins/devkit/src/inspections/quickfix/RegisterExtensionFix.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.devkit.inspections.quickfix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.Consumer; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.PsiNavigateUtil; +import com.intellij.util.xml.DomFileElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.Extension; +import org.jetbrains.idea.devkit.dom.Extensions; +import org.jetbrains.idea.devkit.dom.IdeaPlugin; + +/** + * @author yole + */ +public class RegisterExtensionFix implements IntentionAction { + private final PsiClass myExtensionClass; + private final String myEPName; + + public RegisterExtensionFix(PsiClass extensionClass, String epName) { + myExtensionClass = extensionClass; + myEPName = epName; + } + + @NotNull + @Override + public String getText() { + return "Register extension"; + } + + @NotNull + @Override + public String getFamilyName() { + return getText(); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return true; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + RegisterInspectionFix.choosePluginDescriptor(project, editor, file, new Consumer>() { + @Override + public void consume(DomFileElement element) { + doFix(element); + } + }); + } + + private void doFix(final DomFileElement element) { + Extension extension = new WriteCommandAction(element.getFile().getProject(), element.getFile()) { + @Override + protected void run(Result result) throws Throwable { + Extensions extensions = RegisterInspectionFix.getExtension(element.getRootElement(), myEPName); + Extension extension = extensions.addExtension(myEPName); + XmlTag tag = extension.getXmlTag(); + tag.setAttribute("implementation", myExtensionClass.getQualifiedName()); + result.setResult(extension); + } + }.execute().throwException().getResultObject(); + PsiNavigateUtil.navigate(extension.getXmlTag()); + } + + @Override + public boolean startInWriteAction() { + return false; + } +} diff --git a/plugins/devkit/src/inspections/quickfix/RegisterExtensionFixProvider.java b/plugins/devkit/src/inspections/quickfix/RegisterExtensionFixProvider.java new file mode 100644 index 000000000000..21d0e05c4e9c --- /dev/null +++ b/plugins/devkit/src/inspections/quickfix/RegisterExtensionFixProvider.java @@ -0,0 +1,101 @@ +/* + * 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 org.jetbrains.idea.devkit.inspections.quickfix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.GlobalInspectionTool; +import com.intellij.codeInspection.InspectionEP; +import com.intellij.codeInspection.LocalInspectionEP; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.reference.UnusedDeclarationFixProvider; +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.ProjectScope; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlTag; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Avdeev + * Date: 1/19/12 + */ +public class RegisterExtensionFixProvider implements UnusedDeclarationFixProvider { + + @NotNull + @Override + public IntentionAction[] getQuickFixes(PsiElement element) { + if (!(element instanceof PsiIdentifier)) return IntentionAction.EMPTY_ARRAY; + PsiElement parent = element.getParent(); + if (!(parent instanceof PsiClass)) return IntentionAction.EMPTY_ARRAY; + PsiClass parentClass = (PsiClass)parent; + if (InheritanceUtil.isInheritor(parentClass, LocalInspectionTool.class.getName())) { + return new IntentionAction[] { new RegisterInspectionFix(parentClass, LocalInspectionEP.LOCAL_INSPECTION) }; + } + if (InheritanceUtil.isInheritor(parentClass, GlobalInspectionTool.class.getName())) { + return new IntentionAction[] { new RegisterInspectionFix(parentClass, InspectionEP.GLOBAL_INSPECTION) }; + } + PsiField epField = findEPNameField(parentClass); + if (epField != null) { + String epName = findEPNameForClass(epField.getContainingClass()); + if (epName != null) { + return new IntentionAction[] { new RegisterExtensionFix(parentClass, epName) }; + } + } + return IntentionAction.EMPTY_ARRAY; + } + + private static String findEPNameForClass(PsiClass aClass) { + GlobalSearchScope scope = GlobalSearchScope.getScopeRestrictedByFileTypes(ProjectScope.getAllScope(aClass.getProject()), XmlFileType.INSTANCE); + for (PsiReference reference : ReferencesSearch.search(aClass, scope)) { + XmlTag tag = PsiTreeUtil.getParentOfType(reference.getElement(), XmlTag.class); + if (tag != null && "extensionPoint".equals(tag.getName())) { + String qName = tag.getAttributeValue("qualifiedName"); + if (qName != null) { + return qName; + } + String name = tag.getAttributeValue("name"); + if (name != null) { + return "com.intellij." + name; + } + } + } + return null; + } + + private static PsiField findEPNameField(PsiClass aClass) { + for (PsiField field : aClass.getFields()) { + if (field.getType() instanceof PsiClassType) { + PsiClassType classType = (PsiClassType)field.getType(); + PsiClassType.ClassResolveResult resolved = classType.resolveGenerics(); + PsiClass fieldClass = resolved.getElement(); + if (fieldClass != null && ExtensionPointName.class.getName().equals(fieldClass.getQualifiedName())) { + return field; + } + } + } + for (PsiClass superClass: aClass.getSupers()) { + PsiField epField = findEPNameField(superClass); + if (epField != null) { + return epField; + } + } + return null; + } +} diff --git a/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java b/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java index b709bf83719d..6eace3d6321f 100644 --- a/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java +++ b/plugins/devkit/src/inspections/quickfix/RegisterInspectionFix.java @@ -37,6 +37,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; import com.intellij.psi.xml.XmlTag; +import com.intellij.util.Consumer; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PsiNavigateUtil; import com.intellij.util.containers.ContainerUtil; @@ -84,6 +85,16 @@ class RegisterInspectionFix implements IntentionAction { @Override public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { + choosePluginDescriptor(project, editor, file, new Consumer>() { + @Override + public void consume(DomFileElement element) { + doFix(element, project, file); + } + }); + } + + public static void choosePluginDescriptor(final Project project, Editor editor, final PsiFile file, + final Consumer> consumer) { Module module = ModuleUtil.findModuleForPsiElement(file); assert module != null; List> elements = @@ -103,7 +114,7 @@ class RegisterInspectionFix implements IntentionAction { } if (elements.size() == 1) { - doFix(elements.get(0), project, file); + consumer.consume(elements.get(0)); return; } @@ -127,7 +138,7 @@ class RegisterInspectionFix implements IntentionAction { @Override public PopupStep onChosen(DomFileElement selectedValue, boolean finalChoice) { - doFix(selectedValue, project, file); + consumer.consume(selectedValue); return FINAL_CHOICE; } }; @@ -137,12 +148,11 @@ class RegisterInspectionFix implements IntentionAction { private void doFix(DomFileElement selectedValue, final Project project, final PsiFile file) { final IdeaPlugin plugin = selectedValue.getRootElement(); - final List extensionsList = plugin.getExtensions(); Extension extension = new WriteCommandAction(project, file) { @Override protected void run(Result result) throws Throwable { - final Extensions extensions = getExtension(plugin, extensionsList); + final Extensions extensions = getExtension(plugin, myEp.getName()); Extension extension = extensions.addExtension(myEp.getName()); XmlTag tag = extension.getXmlTag(); tag.setAttribute("implementationClass", myPsiClass.getQualifiedName()); @@ -152,11 +162,12 @@ class RegisterInspectionFix implements IntentionAction { PsiNavigateUtil.navigate(extension.getXmlTag()); } - private Extensions getExtension(IdeaPlugin plugin, List extensionsList) { + public static Extensions getExtension(IdeaPlugin plugin, String epName) { + final List extensionsList = plugin.getExtensions(); Extensions extensions = null; for (Extensions e : extensionsList) { String s = e.getDefaultExtensionNs().getStringValue(); - if (s != null && myEp.getName().startsWith(s)) { + if (s != null && epName.startsWith(s)) { extensions = e; break; } diff --git a/plugins/devkit/src/inspections/quickfix/RegisterInspectionFixProvider.java b/plugins/devkit/src/inspections/quickfix/RegisterInspectionFixProvider.java deleted file mode 100644 index c136d2726839..000000000000 --- a/plugins/devkit/src/inspections/quickfix/RegisterInspectionFixProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 org.jetbrains.idea.devkit.inspections.quickfix; - -import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.codeInspection.GlobalInspectionTool; -import com.intellij.codeInspection.InspectionEP; -import com.intellij.codeInspection.LocalInspectionEP; -import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.codeInspection.reference.UnusedDeclarationFixProvider; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiIdentifier; -import com.intellij.psi.util.InheritanceUtil; -import org.jetbrains.annotations.NotNull; - -/** - * @author Dmitry Avdeev - * Date: 1/19/12 - */ -public class RegisterInspectionFixProvider implements UnusedDeclarationFixProvider { - - @NotNull - @Override - public IntentionAction[] getQuickFixes(PsiElement element) { - if (!(element instanceof PsiIdentifier)) return IntentionAction.EMPTY_ARRAY; - PsiElement parent = element.getParent(); - if (!(parent instanceof PsiClass)) return IntentionAction.EMPTY_ARRAY; - if (InheritanceUtil.isInheritor((PsiClass)parent, LocalInspectionTool.class.getName())) { - return new IntentionAction[] { new RegisterInspectionFix((PsiClass)parent, LocalInspectionEP.LOCAL_INSPECTION) }; - } - if (InheritanceUtil.isInheritor((PsiClass)parent, GlobalInspectionTool.class.getName())) { - return new IntentionAction[] { new RegisterInspectionFix((PsiClass)parent, InspectionEP.GLOBAL_INSPECTION) }; - } - return IntentionAction.EMPTY_ARRAY; - } -} From a0cf0534dda60fac780218e4089abd610123bcac Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Feb 2013 19:34:50 +0100 Subject: [PATCH 20/42] poor man's hacky xinclude implementation made a little bit more flexible --- .../src/com/intellij/util/xmlb/JDOMXIncluder.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java b/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java index 1936d7e00bb1..8a764574f686 100644 --- a/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java +++ b/platform/util/src/com/intellij/util/xmlb/JDOMXIncluder.java @@ -257,8 +257,8 @@ public class JDOMXIncluder { //xpointer($1) @NonNls public static Pattern XPOINTER_PATTERN = Pattern.compile("xpointer\\((.*)\\)"); - // /$1/* - public static Pattern CHILDREN_PATTERN = Pattern.compile("\\/(.*)\\/\\*"); + // /$1(/$2)?/* + public static Pattern CHILDREN_PATTERN = Pattern.compile("/([^/]*)(/[^/]*)?/\\*"); @Nullable private static List extractNeededChildren(final Element element, List remoteElements) { @@ -283,8 +283,13 @@ public class JDOMXIncluder { Element e = (Element)remoteElements.get(0); - if (e.getName().equals(rootTagName)) return - new ArrayList(e.getContent()); + if (e.getName().equals(rootTagName)) { + String subTagName = matcher.group(2); + if (subTagName != null) { + e = e.getChild(subTagName.substring(1)); // cut off the slash + } + return new ArrayList(e.getContent()); + } else return Collections.emptyList(); } From 0031d85394001e50712ab6ae7ecaf5ec08cd309b Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Feb 2013 20:19:52 +0100 Subject: [PATCH 21/42] ensure we have plugin DOM in *Extensions and *ExtensionPoints files --- .../src/META-INF/LangExtensionPoints.xml | 1073 ++++++------ .../src/META-INF/LangExtensions.xml | 1451 +++++++++-------- .../src/META-INF/PlatformExtensionPoints.xml | 246 +-- .../src/META-INF/PlatformExtensions.xml | 470 +++--- .../src/META-INF/PlatformLangPlugin.xml | 14 +- .../src/META-INF/PlatformPlugin.xml | 8 +- .../src/META-INF/VcsExtensionPoints.xml | 84 +- .../src/META-INF/VcsExtensions.xml | 67 +- .../src/META-INF/xdebugger.xml | 4 +- resources/src/idea/RichPlatformPlugin.xml | 14 +- 10 files changed, 1742 insertions(+), 1689 deletions(-) diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 2188c29f1126..df03c22ed87c 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -1,589 +1,594 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - + - + - - + + - - - - - - - + + + + + + + - + - + - - - + + + - + - + - + - + - - - + + + - - - + + + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - - + + - + - - + + - + - + - - + + - + + + + + - - diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 434bfa988305..060290a71f2e 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -1,809 +1,824 @@ - - - + + + + - + - + - + - - + + - + - + - + - - - + + + - + - - - + + + - + - + - + - + - + - - - - - - + + + + + + - - - - + + + + - + - + - + - + - + - + - + - - + + - + - + - + - - + + - - + + - - - - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - - - - - - - - - - + + + + + + + + + + - + - + - + - + - - - - + + + + - + - - - - + + + + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.intellij.codeInsight.intention.impl.EditFoldingOptionsAction + + + com.intellij.codeInsight.intention.impl.QuickEditAction + Language Injection + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - com.intellij.codeInsight.intention.impl.EditFoldingOptionsAction - - - com.intellij.codeInsight.intention.impl.QuickEditAction - Language Injection - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + + - + - + - + - - - - + - + - + + + + - + - + - + - - + - + - + + - - + + + + + + + + + + + + + + - - - - - - diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 3926f1a73f93..21bba329f243 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -1,155 +1,181 @@ - - - + + + + - + - + - + - + + + - + + + - + - + - + - + - + + + - + - - - + + + - - + + + - + - - - + + - - + - - - + + + - - + + - + - - + + + - + + + - - + - - - - + + + - - + + - - + - - - + + - + + + + - - - - + + - - - - + + + + - + + + - - - + + - + - - - + + + + - + + + + - - - + - - + + + - + - + - - - - + - + - - + + + - + + - - + - + - - + + + + + + + + + + + + + + + + + + + + diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index ad4b9242c132..05554f6067b5 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -1,296 +1,298 @@ - - - - + + + + + - - + + - + - + - + - - - - + + + + - - + + - + - - + + - + - + - - - - - + + + + + - + - - - + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - - - + + + + + + - + - - - - - + + + + + - + - + - - - - + + + + - + - - - + + + - + - + - + - + - + - + - + - + - - + + - - + + - - - + + + - - + + - - + + - - + + - - - - - + + + + + - - + - + - + - + - - + + - - - - - - + + + + + + - - - + + + - - + + - - - - - - - + + + + + + + - + - - - + + + - + - - - - + + + + - + - - - + + + - - + + - + - - + + - + - - - - + + + + - - + + + diff --git a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml index 6c318b5e79ef..9057536b9935 100644 --- a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml +++ b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml @@ -11,15 +11,15 @@ - - - + + + - - - + + + @@ -90,7 +90,7 @@ - + diff --git a/platform/platform-resources/src/META-INF/PlatformPlugin.xml b/platform/platform-resources/src/META-INF/PlatformPlugin.xml index 38ea712e97ff..b7b3395aaa03 100644 --- a/platform/platform-resources/src/META-INF/PlatformPlugin.xml +++ b/platform/platform-resources/src/META-INF/PlatformPlugin.xml @@ -6,13 +6,13 @@ - - + + - - + + diff --git a/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml b/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml index 8541a4543a4b..aff52957aed9 100644 --- a/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml @@ -1,52 +1,54 @@ - - - - - + + + + + + - + - + - + - + - + - + - + - - - - - + + + - - - - - + + + + + + + - \ No newline at end of file + + diff --git a/platform/platform-resources/src/META-INF/VcsExtensions.xml b/platform/platform-resources/src/META-INF/VcsExtensions.xml index bee6fb41085e..5b77969e431d 100644 --- a/platform/platform-resources/src/META-INF/VcsExtensions.xml +++ b/platform/platform-resources/src/META-INF/VcsExtensions.xml @@ -1,40 +1,43 @@ - - + + + - - - - - - - + + + + + + + - + - + - - + + - - - + + + - + - - - - + + + + + + + + + + - - - - diff --git a/platform/platform-resources/src/META-INF/xdebugger.xml b/platform/platform-resources/src/META-INF/xdebugger.xml index e46191a84a1c..3a47c11d583f 100644 --- a/platform/platform-resources/src/META-INF/xdebugger.xml +++ b/platform/platform-resources/src/META-INF/xdebugger.xml @@ -1,4 +1,4 @@ - + com.intellij.xdebugger.XDebuggerManager @@ -37,4 +37,4 @@ - + diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml index 6c954350cad5..d8d26ecf56e1 100644 --- a/resources/src/idea/RichPlatformPlugin.xml +++ b/resources/src/idea/RichPlatformPlugin.xml @@ -27,9 +27,9 @@ - - - + + + @@ -97,9 +97,9 @@ - - - + + + @@ -383,7 +383,7 @@ - + From f24bda7784dc6595f762fed0fc87e5494580f03e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Feb 2013 21:27:54 +0100 Subject: [PATCH 22/42] DOM for new subtag of --- plugins/devkit/src/dom/ExtensionPoint.java | 6 ++ plugins/devkit/src/dom/With.java | 42 ++++++++++ .../dom/impl/PluginFieldNameConverter.java | 77 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 plugins/devkit/src/dom/With.java create mode 100644 plugins/devkit/src/dom/impl/PluginFieldNameConverter.java diff --git a/plugins/devkit/src/dom/ExtensionPoint.java b/plugins/devkit/src/dom/ExtensionPoint.java index 1c5662e63108..c05fbf8b8c27 100644 --- a/plugins/devkit/src/dom/ExtensionPoint.java +++ b/plugins/devkit/src/dom/ExtensionPoint.java @@ -21,6 +21,8 @@ import com.intellij.util.xml.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.devkit.dom.impl.PluginPsiClassConverter; +import java.util.List; + /** * @author mike */ @@ -50,4 +52,8 @@ public interface ExtensionPoint extends DomElement { @NotNull GenericAttributeValue getArea(); + + @NotNull + @SubTagList("with") + List getWithElements(); } diff --git a/plugins/devkit/src/dom/With.java b/plugins/devkit/src/dom/With.java new file mode 100644 index 000000000000..f5054ce100f2 --- /dev/null +++ b/plugins/devkit/src/dom/With.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.devkit.dom; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import com.intellij.util.xml.Attribute; +import com.intellij.util.xml.Convert; +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.GenericAttributeValue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.devkit.dom.impl.PluginFieldNameConverter; +import org.jetbrains.idea.devkit.dom.impl.PluginPsiClassConverter; + +/** + * @author yole + */ +public interface With extends DomElement { + @NotNull + @Attribute("attribute") + @Convert(PluginFieldNameConverter.class) + GenericAttributeValue getAttribute(); + + + @NotNull + @Attribute("implements") + @Convert(PluginPsiClassConverter.class) + GenericAttributeValue getImplements(); +} diff --git a/plugins/devkit/src/dom/impl/PluginFieldNameConverter.java b/plugins/devkit/src/dom/impl/PluginFieldNameConverter.java new file mode 100644 index 000000000000..aebdd1e1d88e --- /dev/null +++ b/plugins/devkit/src/dom/impl/PluginFieldNameConverter.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.devkit.dom.impl; + +import com.intellij.psi.*; +import com.intellij.util.xml.ConvertContext; +import com.intellij.util.xml.ResolvingConverter; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.devkit.dom.ExtensionPoint; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * @author yole + */ +public class PluginFieldNameConverter extends ResolvingConverter { + @NotNull + @Override + public Collection getVariants(ConvertContext context) { + PsiClass aClass = getEPBeanClass(context); + if (aClass == null) return Collections.emptyList(); + List result = new ArrayList(); + for (PsiField field : aClass.getAllFields()) { + if (!field.hasModifierProperty(PsiModifier.STATIC)) { + PsiType type = field.getType(); + if (type instanceof PsiClassType) { + PsiClass resolved = ((PsiClassType)type).resolve(); + if (resolved != null && CommonClassNames.JAVA_LANG_STRING.equals(resolved.getQualifiedName())) { + result.add(field); + } + } + } + } + return result; + } + + @Nullable + @Override + public PsiField fromString(@Nullable @NonNls String s, ConvertContext context) { + PsiClass value = getEPBeanClass(context); + if (value == null) return null; + return value.findFieldByName(s, true); + } + + @Nullable + @Override + public String toString(@Nullable PsiField field, ConvertContext context) { + return field == null ? null : field.getName(); + } + + @Nullable + private static PsiClass getEPBeanClass(ConvertContext context) { + ExtensionPoint ep = context.getInvocationElement().getParentOfType(ExtensionPoint.class, true); + if (ep == null) return null; + PsiClass value = ep.getBeanClass().getValue(); + if (value == null) return null; + return value; + } +} From 51cadd806fb24719077171e1f3312393b3795d64 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 11 Feb 2013 21:32:44 +0100 Subject: [PATCH 23/42] merge back Vladimir Krivosheev's change --- .../src/META-INF/PlatformExtensionPoints.xml | 4 ++-- .../platform-resources/src/META-INF/PlatformExtensions.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 21bba329f243..4cdac7626907 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -174,8 +174,8 @@ - + - + \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 05554f6067b5..78ea7f3ed091 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -290,7 +290,7 @@ - + From 28eabcebbb2de915927ced2c6c5898aa2c72dd4b Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 12 Feb 2013 00:37:17 +0400 Subject: [PATCH 24/42] IDEA-73118 SNAPSHOT dependencies not handled as per Maven 3.0 --- .../idea/maven/model/MavenArtifact.java | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifact.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifact.java index f61b559400e2..560e19f2f271 100644 --- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifact.java +++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/model/MavenArtifact.java @@ -16,6 +16,7 @@ package org.jetbrains.idea.maven.model; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; @@ -23,7 +24,6 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.Serializable; -import java.text.MessageFormat; public class MavenArtifact implements Serializable { @@ -177,25 +177,39 @@ public class MavenArtifact implements Serializable { public String getPathForExtraArtifact(@Nullable String extraArtifactClassifier, @Nullable String customExtension) { String path = getPath(); - if (!StringUtil.isEmptyOrSpaces(extraArtifactClassifier)) { - int repoEnd = path.lastIndexOf(getRelativePath()); - - if (repoEnd == -1) { - // unknown path format: try to add a classified at the end of the filename - int dotPos = path.lastIndexOf("."); - if (dotPos != -1) {// sometimes path doesn't contain '.'; but i can't find any reason why. - String withoutExtension = path.substring(0, dotPos); - path = MessageFormat.format("{0}-{1}.{2}", - withoutExtension, - extraArtifactClassifier, - customExtension == null ? myExtension : customExtension); - } - } - else { - String repoPath = path.substring(0, repoEnd); - path = repoPath + getRelativePathForExtraArtifact(extraArtifactClassifier, customExtension); - } + if (extraArtifactClassifier == null && customExtension == null && Comparing.equal(myVersion, myBaseVersion)) { + return path; } + + int slashPos = path.lastIndexOf('/'); + if (slashPos != -1) { + StringBuilder res = new StringBuilder(); + res.append(path, 0, slashPos + 1); + res.append(myArtifactId); + res.append('-'); + res.append(myVersion); + + String fullClassifier = getFullClassifier(extraArtifactClassifier); + if (fullClassifier != null) { + res.append('-').append(fullClassifier); + } + + res.append('.'); + res.append(customExtension == null ? myExtension : customExtension); + return res.toString(); + } + + // unknown path format: try to add a classified at the end of the filename + int dotPos = path.lastIndexOf('.'); + if (dotPos != -1) {// sometimes path doesn't contain '.'; but i can't find any reason why. + StringBuilder res = new StringBuilder(); + res.append(path, 0, dotPos); + res.append('-'); + res.append(extraArtifactClassifier); + res.append(customExtension == null ? myExtension : customExtension); + return res.toString(); + } + return path; } From 5b1c6873e05c309e178c419db5fd17660eb67987 Mon Sep 17 00:00:00 2001 From: Kirill Safonov Date: Tue, 12 Feb 2013 00:46:48 +0400 Subject: [PATCH 25/42] fix CCE --- platform/platform-impl/src/org/jetbrains/io/WebServer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/org/jetbrains/io/WebServer.java b/platform/platform-impl/src/org/jetbrains/io/WebServer.java index d858eb86688e..e3398f6babb7 100644 --- a/platform/platform-impl/src/org/jetbrains/io/WebServer.java +++ b/platform/platform-impl/src/org/jetbrains/io/WebServer.java @@ -302,6 +302,7 @@ public class WebServer { public void messageReceived(ChannelHandlerContext context, MessageEvent event) throws Exception { if (!(event.getMessage() instanceof HttpRequest)) { context.sendUpstream(event); + return; } HttpRequest request = (HttpRequest)event.getMessage(); From 18478625fdf2336a0b03be85d09a395f37c9fc1e Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 11 Feb 2013 21:47:59 +0100 Subject: [PATCH 26/42] a more reliable error handling in gdsl initialization --- .../plugins/groovy/dsl/GroovyDslFileIndex.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java index ca405965f44d..a65cb0183400 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java @@ -330,13 +330,13 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { ourStandardScripts = new SoftReference>>(executors); ref.set(executors); } - catch (OutOfMemoryError e) { - stopGdsl = true; - throw e; - } - catch (NoClassDefFoundError e) { - stopGdsl = true; - throw e; + catch (Throwable e) { + LOG.error(e); + ref.set(new ArrayList>()); + //noinspection InstanceofCatchParameter + if (e instanceof Error) { + stopGdsl = true; + } } finally { semaphore.up(); From b62addc7a5824b51edca047fd69088b6ced6c061 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 11 Feb 2013 22:16:18 +0100 Subject: [PATCH 27/42] a more reliable error handling in gdsl initialization, take 2 --- .../org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java index a65cb0183400..8f676d3bfd96 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java @@ -331,12 +331,12 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { ref.set(executors); } catch (Throwable e) { - LOG.error(e); ref.set(new ArrayList>()); //noinspection InstanceofCatchParameter if (e instanceof Error) { stopGdsl = true; } + LOG.error(e); } finally { semaphore.up(); From 3816e7c5ab28ea450789ab6e16bceb26e07a5717 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 11 Feb 2013 22:42:28 +0100 Subject: [PATCH 28/42] initialize gdsl extensions on a thread which probably has a read action already --- .../org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java index 8f676d3bfd96..2dc273d250a0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java @@ -83,6 +83,7 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { public static final String MODIFIED = "Modified"; public static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup("Groovy DSL errors", NotificationDisplayType.BALLOON, true); + private static final GroovyFrameworkConfigNotification[] EXTENSIONS = GroovyFrameworkConfigNotification.EP_NAME.getExtensions(); private final MyDataIndexer myDataIndexer = new MyDataIndexer(); private final MyInputFilter myInputFilter = new MyInputFilter(); @@ -299,7 +300,7 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { Set scriptFolders = new LinkedHashSet(); // perhaps a separate extension for that? - for (GroovyFrameworkConfigNotification extension : GroovyFrameworkConfigNotification.EP_NAME.getExtensions()) { + for (GroovyFrameworkConfigNotification extension : EXTENSIONS) { File jarPath = new File(PathUtil.getJarPathForClass(extension.getClass())); if (jarPath.isFile()) { jarPath = jarPath.getParentFile(); From 3104e292641fdff576be521ff1b33d0d3eb7470d Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 11 Feb 2013 23:05:06 +0100 Subject: [PATCH 29/42] initialize gdsl extensions on a thread which probably has a read action already, but don't mess with classloading --- .../org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java index 2dc273d250a0..81c831d3b2cf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java @@ -83,7 +83,6 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { public static final String MODIFIED = "Modified"; public static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup("Groovy DSL errors", NotificationDisplayType.BALLOON, true); - private static final GroovyFrameworkConfigNotification[] EXTENSIONS = GroovyFrameworkConfigNotification.EP_NAME.getExtensions(); private final MyDataIndexer myDataIndexer = new MyDataIndexer(); private final MyInputFilter myInputFilter = new MyInputFilter(); @@ -284,6 +283,8 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { return result; } + final GroovyFrameworkConfigNotification[] extensions = GroovyFrameworkConfigNotification.EP_NAME.getExtensions(); + final Semaphore semaphore = new Semaphore(); semaphore.down(); final AtomicReference>> ref = new AtomicReference>>(); @@ -300,7 +301,7 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { Set scriptFolders = new LinkedHashSet(); // perhaps a separate extension for that? - for (GroovyFrameworkConfigNotification extension : EXTENSIONS) { + for (GroovyFrameworkConfigNotification extension : extensions) { File jarPath = new File(PathUtil.getJarPathForClass(extension.getClass())); if (jarPath.isFile()) { jarPath = jarPath.getParentFile(); From 59a9c2d6f086716b4afbf99b3c00df3bf234ecc6 Mon Sep 17 00:00:00 2001 From: Kirill Safonov Date: Tue, 12 Feb 2013 02:29:38 +0400 Subject: [PATCH 30/42] Refactor JavaScript library scopes: 1. use the same scope for completion and resolve (based on enabled libraries) 2. library classes (minified) roots are ignored if it has source roots 3. no hacks against IDEA platform roots and scopes + roots converter --- .../core-api/src/com/intellij/psi/search/GlobalSearchScope.java | 2 +- .../openapi/vfs/impl/VirtualFilePointerContainerImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java index a64fe860486d..35026e9d64eb 100644 --- a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java +++ b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java @@ -596,7 +596,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw } } - private static class FilesScope extends GlobalSearchScope { + public static class FilesScope extends GlobalSearchScope { private final Collection myFiles; public FilesScope(final Project project, final Collection files) { diff --git a/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java b/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java index 6173a7403c1e..107f3f581267 100644 --- a/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerContainerImpl.java @@ -49,7 +49,7 @@ public class VirtualFilePointerContainerImpl extends TraceableDisposable impleme private final VirtualFilePointerListener myListener; private volatile Trinity myCachedThings; private volatile long myTimeStampOfCachedThings = -1; - @NonNls private static final String URL_ATTR = "url"; + @NonNls public static final String URL_ATTR = "url"; private boolean myDisposed; private static final boolean TRACE_CREATION = LOG.isDebugEnabled() || ApplicationManager.getApplication().isUnitTestMode(); From 4ea4cd17a4ca86deff1cff4937d4eac86d39cedc Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 12 Feb 2013 10:45:04 +0400 Subject: [PATCH 31/42] IDEA-99857 Support for web-app_3_1.xsd --- .../src/com/intellij/lang/jsp/JspVersion.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspVersion.java b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspVersion.java index 207b7c56ca8a..7e5416d69b93 100644 --- a/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspVersion.java +++ b/java/jsp-base-openapi/src/com/intellij/lang/jsp/JspVersion.java @@ -54,6 +54,17 @@ public interface JspVersion { } }; + JspVersion JSP_2_3 = new JspVersion() { + + public String getNumber() { + return "2.3"; + } + + public boolean betterThan(JspVersion other) { + return getNumber().compareTo(other.getNumber()) > 0; + } + }; + String getNumber(); boolean betterThan(JspVersion other); From 2a65849e379dcb55e42662f74be745d67edbe721 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 11 Feb 2013 22:44:23 +0400 Subject: [PATCH 32/42] xml rpc server: serve not only host, but host/ too --- .../platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java index dbf50cf1ee76..b904be2001bb 100644 --- a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java @@ -103,7 +103,7 @@ public class XmlRpcServerImpl implements XmlRpcServer { } private boolean process(QueryStringDecoder urlDecoder, HttpRequest request, ChannelHandlerContext context) throws IOException { - if (!(urlDecoder.getPath().isEmpty() || urlDecoder.getPath().equalsIgnoreCase("/RPC2"))) { + if (!(urlDecoder.getPath().isEmpty() || urlDecoder.getPath().equals("/") || urlDecoder.getPath().equalsIgnoreCase("/RPC2"))) { return false; } From b99a028cd32af82da9dd1123a13dc235d17ea298 Mon Sep 17 00:00:00 2001 From: "Nadya.Zabrodina" Date: Tue, 12 Feb 2013 11:51:43 +0400 Subject: [PATCH 33/42] IDEA-100655 Mercurial plugin (hg4idea) shouldn't ask confirmation for removing non-version files. *Change skipUnversionedAndNotUnderHg method argument to List unversionedFiles, because all VirtualFiles in filesToFilter are null. So we cannot use contains method of ChangeListManager.getUnversioned, it always return false. (see FilePathImpl constructor if forDeleted var set to true). --- .../src/org/zmlx/hg4idea/HgVFSListener.java | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java index 46ad9f88d270..cea8a470b92c 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java @@ -27,6 +27,8 @@ import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.AppUIUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.VcsBackgroundTask; import com.intellij.vcsUtil.VcsUtil; @@ -196,9 +198,15 @@ public class HgVFSListener extends VcsVFSListener { myDeletedFiles.clear(); // skip unversioned files and files which are not under Mercurial - final ChangeListManagerImpl changeListManager = ChangeListManagerImpl.getInstanceImpl(myProject); - skipUnversionedAndNotUnderHg(changeListManager, filesToDelete); - skipUnversionedAndNotUnderHg(changeListManager, filesToConfirmDeletion); + final List unversionedFiles = + ContainerUtil.map(ChangeListManagerImpl.getInstanceImpl(myProject).getUnversionedFiles(), new Function() { + @Override + public FilePath fun(VirtualFile virtualFile) { + return new FilePathImpl(virtualFile); + } + }); + skipUnversionedAndNotUnderHg(unversionedFiles, filesToDelete); + skipUnversionedAndNotUnderHg(unversionedFiles, filesToConfirmDeletion); // newly added files (which were added to the repo but never committed) should be removed from the VCS, // but without user confirmation. @@ -241,20 +249,21 @@ public class HgVFSListener extends VcsVFSListener { }.queue(); } - /** - * Changes the given collection of files by filtering out unversioned files and - * files which are not under Mercurial repository. - * @param changeListManager instance of the ChangeListManagerImpl to retrieve unversioned files from it. - * @param filesToFilter files to be filtered. - */ - private void skipUnversionedAndNotUnderHg(ChangeListManagerImpl changeListManager, Collection filesToFilter) { - for (Iterator iter = filesToFilter.iterator(); iter.hasNext(); ) { - final FilePath filePath = iter.next(); - if (HgUtil.getHgRootOrNull(myProject, filePath) == null || changeListManager.isUnversioned(filePath.getVirtualFile())) { - iter.remove(); + /** + * Changes the given collection of files by filtering out unversioned files and + * files which are not under Mercurial repository. + * + * @param unversionedFiles list of unversioned files + * @param filesToFilter files to be filtered. + */ + private void skipUnversionedAndNotUnderHg(List unversionedFiles, Collection filesToFilter) { + for (Iterator iter = filesToFilter.iterator(); iter.hasNext(); ) { + final FilePath filePath = iter.next(); + if (HgUtil.getHgRootOrNull(myProject, filePath) == null || unversionedFiles.contains(filePath)) { + iter.remove(); + } } } - } @Override protected void performDeletion( final List filesToDelete) { From 56b9f5b77cc67df28f904d9436f3f933bd1e32f5 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 8 Feb 2013 17:15:19 +0400 Subject: [PATCH 34/42] annotations --- java/jdkAnnotations/java/text/annotations.xml | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/java/jdkAnnotations/java/text/annotations.xml b/java/jdkAnnotations/java/text/annotations.xml index 3a1d14aa4e0a..44cf7daebd28 100644 --- a/java/jdkAnnotations/java/text/annotations.xml +++ b/java/jdkAnnotations/java/text/annotations.xml @@ -1,5 +1,37 @@ + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0d0972aa8b5f4b7fc3603e2bc4d36d0f21933940 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 11 Feb 2013 13:34:40 +0400 Subject: [PATCH 35/42] notnull --- .../resolve/reference/impl/providers/JavaClassReference.java | 1 + .../resolve/reference/impl/providers/PsiPackageReference.java | 1 + .../src/com/intellij/codeInsight/daemon/JavaErrorMessages.java | 2 ++ .../codeInsight/daemon/EmptyResolveMessageProvider.java | 3 +++ .../src/com/intellij/openapi/paths/PsiDynaReference.java | 1 + .../source/resolve/reference/impl/providers/FileReference.java | 1 + platform/util-rt/src/com/intellij/BundleBase.java | 3 ++- .../ant/src/com/intellij/lang/ant/dom/AntDomFileReference.java | 1 + .../groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.java | 2 ++ .../lang/properties/references/PropertyReferenceBase.java | 1 + .../lang/xpath/xslt/impl/XsltReferenceContributor.java | 1 + .../lang/xpath/xslt/impl/references/ModeReference.java | 1 + .../lang/xpath/xslt/impl/references/PrefixReference.java | 1 + .../lang/xpath/xslt/impl/references/TemplateReference.java | 1 + .../com/intellij/util/xml/impl/GenericDomValueReference.java | 1 + .../intellij/util/xml/converters/DelimitedListConverter.java | 1 + .../com/intellij/util/xml/converters/QuotedValueConverter.java | 1 + .../src/com/intellij/codeInsight/daemon/XmlErrorMessages.java | 2 ++ .../daemon/impl/analysis/encoding/XmlEncodingReference.java | 1 + .../reference/impl/providers/DtdReferencesProvider.java | 2 ++ .../reference/impl/providers/SchemaReferencesProvider.java | 1 + .../source/resolve/reference/impl/providers/URLReference.java | 1 + xml/impl/src/com/intellij/xml/util/AnchorReference.java | 1 + .../plugins/relaxNG/compact/psi/impl/PatternReference.java | 1 + .../intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java | 1 + .../plugins/relaxNG/references/PrefixReferenceProvider.java | 1 + .../plugins/relaxNG/xml/dom/impl/DefinitionReference.java | 1 + 27 files changed, 34 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java index 04dd71c7970d..09eb7879deb9 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java @@ -583,6 +583,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer return myJavaClassReferenceSet; } + @NotNull @Override public String getUnresolvedMessagePattern() { return myJavaClassReferenceSet.getUnresolvedMessagePattern(myIndex); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java index 94827c3a03f5..537b3216df4d 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiPackageReference.java @@ -60,6 +60,7 @@ public class PsiPackageReference extends PsiPolyVariantReferenceBase return subPackages.toArray(); } + @NotNull @Override public String getUnresolvedMessagePattern() { return JavaErrorMessages.message("cannot.resolve.package"); diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/JavaErrorMessages.java b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/JavaErrorMessages.java index 3fc250b1c0ab..530c87cb33f4 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/daemon/JavaErrorMessages.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/JavaErrorMessages.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon; import com.intellij.AbstractBundle; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.PropertyKey; /** @@ -31,6 +32,7 @@ public class JavaErrorMessages extends AbstractBundle { super(BUNDLE); } + @NotNull public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) { return INSTANCE.getMessage(key, params); } diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java index 2fb1dea8aea8..0cba5404e11b 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/EmptyResolveMessageProvider.java @@ -16,6 +16,8 @@ package com.intellij.codeInsight.daemon; +import org.jetbrains.annotations.NotNull; + /** * Implement this in your {@link com.intellij.psi.PsiReference} to provide custom error message. */ @@ -27,5 +29,6 @@ public interface EmptyResolveMessageProvider { * @return pattern or message * @see XmlHighlightVisitor#getErrorDescription() */ + @NotNull String getUnresolvedMessagePattern(); } diff --git a/platform/lang-impl/src/com/intellij/openapi/paths/PsiDynaReference.java b/platform/lang-impl/src/com/intellij/openapi/paths/PsiDynaReference.java index ff6e12637e68..35cfc426c60c 100644 --- a/platform/lang-impl/src/com/intellij/openapi/paths/PsiDynaReference.java +++ b/platform/lang-impl/src/com/intellij/openapi/paths/PsiDynaReference.java @@ -207,6 +207,7 @@ public class PsiDynaReference extends PsiReferenceBase } } + @NotNull @Override @SuppressWarnings({"UnresolvedPropertyKey"}) public String getUnresolvedMessagePattern() { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java index 861e6cf3e3a7..338563f3104d 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java @@ -553,6 +553,7 @@ public class FileReference implements FileReferenceOwner, PsiPolyVariantReferenc return myIndex; } + @NotNull @Override public String getUnresolvedMessagePattern() { return LangBundle.message("error.cannot.resolve") diff --git a/platform/util-rt/src/com/intellij/BundleBase.java b/platform/util-rt/src/com/intellij/BundleBase.java index 8b230fe0e160..75c72d8b87ba 100644 --- a/platform/util-rt/src/com/intellij/BundleBase.java +++ b/platform/util-rt/src/com/intellij/BundleBase.java @@ -58,7 +58,8 @@ public abstract class BundleBase { return format(value, params); } - public static String format(String value, Object... params) { + @NotNull + public static String format(@NotNull String value, @NotNull Object... params) { if (params.length > 0 && value.indexOf('{') >= 0) { return MessageFormat.format(value, params); } diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReference.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReference.java index b79dc71de44e..ad45851ff043 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReference.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReference.java @@ -47,6 +47,7 @@ public class AntDomFileReference extends FileReference implements AntDomReferenc return (AntDomFileReferenceSet)super.getFileReferenceSet(); } + @NotNull public String getUnresolvedMessagePattern() { return AntBundle.message("file.doesnt.exist", getCanonicalRepresentationText()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.java index c5788c3b889a..d2f8ba7f27ce 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy; import com.intellij.CommonBundle; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.PropertyKey; import java.lang.ref.Reference; @@ -34,6 +35,7 @@ public class GroovyBundle { @NonNls private static final String BUNDLE = "org.jetbrains.plugins.groovy.GroovyBundle"; + @NotNull public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) { return CommonBundle.message(getBundle(), key, params); } diff --git a/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java b/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java index 993be84b5d08..3c4c0d8bb655 100644 --- a/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java +++ b/plugins/properties/src/com/intellij/lang/properties/references/PropertyReferenceBase.java @@ -191,6 +191,7 @@ public abstract class PropertyReferenceBase implements PsiPolyVariantReference, return mySoft; } + @NotNull public String getUnresolvedMessagePattern() { return PropertiesBundle.message("unresolved.property.key"); } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java index 85057da43b88..e2d3277351a7 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltReferenceContributor.java @@ -134,6 +134,7 @@ public class XsltReferenceContributor { return name.equals(text) || text.endsWith(":" + name); } + @NotNull @Override public String getUnresolvedMessagePattern() { return "Unknown Type"; diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/ModeReference.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/ModeReference.java index 3867949f0b27..529fcc323124 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/ModeReference.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/ModeReference.java @@ -187,6 +187,7 @@ class ModeReference extends SimpleAttributeReference implements PsiPolyVariantRe } } + @NotNull public String getUnresolvedMessagePattern() { final QName qName = myImplicitModeElement.getQName(); if (qName != null && qName != QNameUtil.UNRESOLVED) { diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/PrefixReference.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/PrefixReference.java index 837350475d81..0cfb85649ac0 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/PrefixReference.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/PrefixReference.java @@ -70,6 +70,7 @@ public class PrefixReference extends SimpleAttributeReference implements EmptyRe return XsltNamespaceContext.resolvePrefix(getCanonicalText(), myAttribute); } + @NotNull public String getUnresolvedMessagePattern() { return "Undeclared namespace prefix ''{0}''"; } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/TemplateReference.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/TemplateReference.java index 8048ce911bec..6dc05ff99bdb 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/TemplateReference.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/references/TemplateReference.java @@ -86,6 +86,7 @@ class TemplateReference extends AttributeReference implements EmptyResolveMessag QuickFixAction.registerQuickFixAction(highlightInfo, new CreateTemplateFix(myAttribute.getParent(), myName)); } + @NotNull public String getUnresolvedMessagePattern() { return "Cannot resolve template ''{0}''"; } diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/GenericDomValueReference.java b/xml/dom-impl/src/com/intellij/util/xml/impl/GenericDomValueReference.java index 06a47b9f7644..881630e16325 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/GenericDomValueReference.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/GenericDomValueReference.java @@ -142,6 +142,7 @@ public class GenericDomValueReference extends PsiReferenceBase im return StringUtil.notNullize(getStringValue()); } + @NotNull public String getUnresolvedMessagePattern() { final ConvertContext context = getConvertContext(); return getConverter().getErrorMessage(getStringValue(), context); diff --git a/xml/dom-openapi/src/com/intellij/util/xml/converters/DelimitedListConverter.java b/xml/dom-openapi/src/com/intellij/util/xml/converters/DelimitedListConverter.java index 2e5c825dd3ee..0b6a1d5e75a9 100644 --- a/xml/dom-openapi/src/com/intellij/util/xml/converters/DelimitedListConverter.java +++ b/xml/dom-openapi/src/com/intellij/util/xml/converters/DelimitedListConverter.java @@ -251,6 +251,7 @@ public abstract class DelimitedListConverter extends ResolvingConverter extends ResolvingConverter impl return getReferenceVariants(myContext, myGenericDomValue, getRangeInElement()); } + @NotNull public String getUnresolvedMessagePattern() { return myBadQuotation? DomBundle.message("message.invalid.value.quotation") : getUnresolvedMessage(getValue()); } diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/XmlErrorMessages.java b/xml/impl/src/com/intellij/codeInsight/daemon/XmlErrorMessages.java index dab60a7a6a0c..77d0c1ee4b3b 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/XmlErrorMessages.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/XmlErrorMessages.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon; import com.intellij.CommonBundle; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.PropertyKey; import java.lang.ref.Reference; @@ -34,6 +35,7 @@ public class XmlErrorMessages { private XmlErrorMessages() { } + @NotNull public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) { return CommonBundle.message(getBundle(), key, params); } diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java index 59d987996ffa..d63164ac72a2 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/encoding/XmlEncodingReference.java @@ -65,6 +65,7 @@ public class XmlEncodingReference implements PsiReference, EmptyResolveMessagePr //return myValue.getManager().findClass(fqn, GlobalSearchScope.allScope(myValue.getProject())); } + @NotNull public String getUnresolvedMessagePattern() { //noinspection UnresolvedPropertyKey return XmlErrorMessages.message("unknown.encoding.0"); diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DtdReferencesProvider.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DtdReferencesProvider.java index 4a3fcbaddf4a..cb816495b0e7 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DtdReferencesProvider.java +++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/DtdReferencesProvider.java @@ -138,6 +138,7 @@ public class DtdReferencesProvider extends PsiReferenceProvider { }; } + @NotNull public String getUnresolvedMessagePattern() { return XmlBundle.message("xml.dtd.unresolved.element.reference", getCanonicalText()); } @@ -259,6 +260,7 @@ public class DtdReferencesProvider extends PsiReferenceProvider { }; } + @NotNull public String getUnresolvedMessagePattern() { return XmlBundle.message("xml.dtd.unresolved.entity.reference", getCanonicalText()); } diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java index b4c39f109269..d74ac1e4b2d7 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java +++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/SchemaReferencesProvider.java @@ -124,6 +124,7 @@ public class SchemaReferencesProvider extends PsiReferenceProvider { return false; } + @NotNull public String getUnresolvedMessagePattern() { return message; } diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java index f5821112427f..e1a152905db9 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java +++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/URLReference.java @@ -225,6 +225,7 @@ public class URLReference implements PsiReference, QuickFixProvider, EmptyResolv } } + @NotNull public String getUnresolvedMessagePattern() { return XmlErrorMessages.message(myIncorrectResourceMapped ? "registered.resource.is.not.recognized":"uri.is.not.registered"); } diff --git a/xml/impl/src/com/intellij/xml/util/AnchorReference.java b/xml/impl/src/com/intellij/xml/util/AnchorReference.java index 65e0c1a9522e..5bae0f65d68e 100644 --- a/xml/impl/src/com/intellij/xml/util/AnchorReference.java +++ b/xml/impl/src/com/intellij/xml/util/AnchorReference.java @@ -215,6 +215,7 @@ public class AnchorReference implements PsiReference, EmptyResolveMessageProvide return mySoft; } + @NotNull public String getUnresolvedMessagePattern() { final XmlFile xmlFile = getFile(); return xmlFile == null ? diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java index c140344f3504..8aeab6059c17 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/PatternReference.java @@ -147,6 +147,7 @@ class PatternReference extends PsiReferenceBase.Poly implements Function return false; } + @NotNull public String getUnresolvedMessagePattern() { return "Unresolved pattern reference ''{0}''"; } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java index 26d350796265..6dc7ad54df8e 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java @@ -135,6 +135,7 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference return "xsd".equals(prefix) || "xml".equals(prefix); } + @NotNull public String getUnresolvedMessagePattern() { return "Unresolved namespace prefix ''{0}''"; } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java index 27015b9ef39a..df9bcc8d5cf2 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/references/PrefixReferenceProvider.java @@ -118,6 +118,7 @@ public class PrefixReferenceProvider extends PsiReferenceProvider { return false; } + @NotNull public String getUnresolvedMessagePattern() { return "Undefined namespace prefix ''{0}''"; } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java index 2de2b477ffef..31b1950c9a8f 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/dom/impl/DefinitionReference.java @@ -153,6 +153,7 @@ public class DefinitionReference extends PsiReferenceBase.Poly Date: Tue, 12 Feb 2013 12:35:26 +0400 Subject: [PATCH 36/42] don't instantiate httpRequestHandlers if we don't need it --- .../org/jetbrains/ide/HttpRequestHandler.java | 7 ++--- .../org/jetbrains/ide/WebServerManager.java | 5 ++++ .../com/intellij/ide/XmlRpcServerImpl.java | 4 +-- .../jetbrains/ide/WebServerManagerImpl.java | 12 ++++----- .../src/org/jetbrains/io/WebServer.java | 27 +++++++------------ 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java index 62082dcc684a..4745524a01b9 100644 --- a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java +++ b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java @@ -23,13 +23,10 @@ import org.jboss.netty.handler.codec.http.QueryStringDecoder; import java.io.IOException; public abstract class HttpRequestHandler { - public boolean isSupported(HttpMethod method) { - return method == HttpMethod.GET; + public boolean isSupported(HttpRequest request) { + return request.getMethod() == HttpMethod.GET; } public abstract boolean process(QueryStringDecoder urlDecoder, HttpRequest request, ChannelHandlerContext context) throws IOException; - - public void serverStopping() { - } } diff --git a/platform/platform-api/src/org/jetbrains/ide/WebServerManager.java b/platform/platform-api/src/org/jetbrains/ide/WebServerManager.java index a2fa6e0802fb..c33154ef57bb 100644 --- a/platform/platform-api/src/org/jetbrains/ide/WebServerManager.java +++ b/platform/platform-api/src/org/jetbrains/ide/WebServerManager.java @@ -15,8 +15,10 @@ */ package org.jetbrains.ide; +import com.intellij.openapi.Disposable; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.extensions.ExtensionPointName; +import org.jetbrains.annotations.Nullable; public abstract class WebServerManager { // Your handler will be instantiated on first user request @@ -29,4 +31,7 @@ public abstract class WebServerManager { public abstract int getPort(); public abstract WebServerManager waitForStart(); + + @Nullable + public abstract Disposable getServerDisposable(); } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java index b904be2001bb..aa17b7806f69 100644 --- a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java @@ -79,8 +79,8 @@ public class XmlRpcServerImpl implements XmlRpcServer { static final class XmlRpcRequestHandler extends HttpRequestHandler { @Override - public boolean isSupported(HttpMethod method) { - return method == HttpMethod.POST || method == HttpMethod.OPTIONS; + public boolean isSupported(HttpRequest request) { + return request == HttpMethod.POST || request == HttpMethod.OPTIONS; } @Override diff --git a/platform/platform-impl/src/org/jetbrains/ide/WebServerManagerImpl.java b/platform/platform-impl/src/org/jetbrains/ide/WebServerManagerImpl.java index ca859a3a762b..854374c04033 100644 --- a/platform/platform-impl/src/org/jetbrains/ide/WebServerManagerImpl.java +++ b/platform/platform-impl/src/org/jetbrains/ide/WebServerManagerImpl.java @@ -12,6 +12,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupActivity; +import com.intellij.openapi.util.Disposer; import org.jboss.netty.channel.ChannelException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -21,7 +22,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; -class WebServerManagerImpl extends WebServerManager implements Disposable { +class WebServerManagerImpl extends WebServerManager { private static final Logger LOG = Logger.getInstance(WebServerManager.class); @NonNls @@ -102,6 +103,7 @@ class WebServerManagerImpl extends WebServerManager implements Disposable { return; } + Disposer.register(ApplicationManager.getApplication(), server); detectedPortNumber = server.start(getDefaultPort(), PORTS_COUNT, true); if (detectedPortNumber == -1) { LOG.info("web server cannot be started, cannot bind to port"); @@ -114,10 +116,8 @@ class WebServerManagerImpl extends WebServerManager implements Disposable { } @Override - public void dispose() { - if (started.get() && server != null) { - server.stop(); - LOG.info("web server stopped"); - } + @Nullable + public Disposable getServerDisposable() { + return server; } } \ No newline at end of file diff --git a/platform/platform-impl/src/org/jetbrains/io/WebServer.java b/platform/platform-impl/src/org/jetbrains/io/WebServer.java index e3398f6babb7..90d89cbd1ca0 100644 --- a/platform/platform-impl/src/org/jetbrains/io/WebServer.java +++ b/platform/platform-impl/src/org/jetbrains/io/WebServer.java @@ -15,6 +15,7 @@ */ package org.jetbrains.io; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; @@ -46,7 +47,7 @@ import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND; import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK; import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1; -public class WebServer { +public class WebServer implements Disposable { private static final String START_TIME_PATH = "/startTime"; private final ChannelGroup openChannels = new DefaultChannelGroup("web-server"); @@ -247,25 +248,15 @@ public class WebServer { } } - public void stop() { + @Override + public void dispose() { try { - for (HttpRequestHandler handler : WebServerManager.EP_NAME.getExtensions()) { - try { - handler.serverStopping(); - } - catch (Exception e) { - LOG.error(e); - } - } + openChannels.close().awaitUninterruptibly(); } finally { - try { - openChannels.close().awaitUninterruptibly(); - } - finally { - channelFactory.releaseExternalResources(); - } + channelFactory.releaseExternalResources(); } + LOG.info("web server stopped"); } public static void replaceDefaultHandler(@NotNull ChannelHandlerContext context, @NotNull SimpleChannelUpstreamHandler messageChannelHandler) { @@ -321,7 +312,7 @@ public class WebServer { if (connectedHandler == null) { for (HttpRequestHandler handler : WebServerManager.EP_NAME.getExtensions()) { try { - if (handler.isSupported(request.getMethod()) && handler.process(urlDecoder, request, context)) { + if (handler.isSupported(request) && handler.process(urlDecoder, request, context)) { if (context.getAttachment() == null) { context.setAttachment(handler); } @@ -333,7 +324,7 @@ public class WebServer { } } } - else if (connectedHandler.isSupported(request.getMethod())) { + else if (connectedHandler.isSupported(request)) { connectedHandler.process(urlDecoder, request, context); return; } From faec7ad408cdb4433035ae6f793a9a1747efdc60 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 12 Feb 2013 12:54:46 +0400 Subject: [PATCH 37/42] fix isSupported after last commit --- .../src/com/intellij/ide/XmlRpcServerImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java index aa17b7806f69..eaf066b3bea0 100644 --- a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java @@ -80,7 +80,7 @@ public class XmlRpcServerImpl implements XmlRpcServer { static final class XmlRpcRequestHandler extends HttpRequestHandler { @Override public boolean isSupported(HttpRequest request) { - return request == HttpMethod.POST || request == HttpMethod.OPTIONS; + return request.getMethod() == HttpMethod.POST || request.getMethod() == HttpMethod.OPTIONS; } @Override @@ -103,7 +103,7 @@ public class XmlRpcServerImpl implements XmlRpcServer { } private boolean process(QueryStringDecoder urlDecoder, HttpRequest request, ChannelHandlerContext context) throws IOException { - if (!(urlDecoder.getPath().isEmpty() || urlDecoder.getPath().equals("/") || urlDecoder.getPath().equalsIgnoreCase("/RPC2"))) { + if (!isXmlRpcRequest(urlDecoder.getPath())) { return false; } @@ -138,6 +138,10 @@ public class XmlRpcServerImpl implements XmlRpcServer { return false; } + private static boolean isXmlRpcRequest(String path) { + return path.isEmpty() || (path.length() == 1 && path.charAt(0) == '/') || path.equalsIgnoreCase("/RPC2"); + } + private static class XmlRpcHandlerMappingImpl implements XmlRpcHandlerMapping { protected final THashMap handlers = new THashMap(); From e6657a722f36888f7c6482078f8c82738de94bc5 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 12 Feb 2013 10:22:22 +0100 Subject: [PATCH 38/42] move tests to community --- .../afterAbstractSuperEquals.java | 15 ++++ .../generateEquals/afterArrays.java | 28 ++++++++ .../generateEquals/afterArraysFromJava15.java | 28 ++++++++ .../generateEquals/afterFields.java | 22 ++++++ .../generateEquals/afterHashCode.java | 31 ++++++++ .../generateEquals/afterInsertOverride.java | 20 ++++++ .../generateEquals/afterLangClass.java | 20 ++++++ .../generateEquals/afterLocalLangClass.java | 24 +++++++ .../generateEquals/afterNoBaseEquals.java | 12 ++++ .../generateEquals/afterNotNull.java | 18 +++++ .../generateEquals/afterOneDoubleField.java | 19 +++++ .../generateEquals/afterOneField.java | 18 +++++ .../generateEquals/afterOneFloatField.java | 18 +++++ .../generateEquals/afterPrimitiveFields.java | 22 ++++++ .../generateEquals/afterSuperEquals.java | 17 +++++ .../beforeAbstractSuperEquals.java | 5 ++ .../generateEquals/beforeArrays.java | 5 ++ .../beforeArraysFromJava15.java | 5 ++ .../generateEquals/beforeFields.java | 5 ++ .../generateEquals/beforeHashCode.java | 6 ++ .../generateEquals/beforeInsertOverride.java | 3 + .../generateEquals/beforeLangClass.java | 3 + .../generateEquals/beforeLocalLangClass.java | 7 ++ .../generateEquals/beforeNoBaseEquals.java | 2 + .../generateEquals/beforeNotNull.java | 3 + .../generateEquals/beforeOneDoubleField.java | 3 + .../generateEquals/beforeOneField.java | 3 + .../generateEquals/beforeOneFloatField.java | 3 + .../generateEquals/beforePrimitiveFields.java | 5 ++ .../generateEquals/beforeSuperEquals.java | 10 +++ .../codeInsight/GenerateEquals15Test.java | 10 +++ .../codeInsight/GenerateEqualsTest.java | 70 +++++++++++++++++++ .../codeInsight/GenerateEqualsTestCase.java | 53 ++++++++++++++ 33 files changed, 513 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterAbstractSuperEquals.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterArrays.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterArraysFromJava15.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterFields.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterHashCode.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterInsertOverride.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterLangClass.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterLocalLangClass.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterNoBaseEquals.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterNotNull.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterOneDoubleField.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterOneField.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterOneFloatField.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterPrimitiveFields.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterSuperEquals.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeAbstractSuperEquals.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeArrays.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeArraysFromJava15.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeFields.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeHashCode.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeInsertOverride.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeLangClass.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeLocalLangClass.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeNoBaseEquals.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeNotNull.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeOneDoubleField.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeOneField.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeOneFloatField.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforePrimitiveFields.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeSuperEquals.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/GenerateEquals15Test.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTestCase.java diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterAbstractSuperEquals.java b/java/java-tests/testData/codeInsight/generateEquals/afterAbstractSuperEquals.java new file mode 100644 index 000000000000..61d03b795d74 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterAbstractSuperEquals.java @@ -0,0 +1,15 @@ +abstract class SuperTest { + public abstract boolean equals(Object object); +} +class Test extends SuperTest { + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + return true; + } + + public int hashCode() { + return 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterArrays.java b/java/java-tests/testData/codeInsight/generateEquals/afterArrays.java new file mode 100644 index 000000000000..e018a504c276 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterArrays.java @@ -0,0 +1,28 @@ +import java.util.Arrays; + +class Test { + Object[] myOs; + int[][] myIIs; + int[] myIs; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + // Compare nested arrays - values of myIIs here + if (!Arrays.equals(myIs, test.myIs)) return false; + // Probably incorrect - comparing Object[] arrays with Arrays.equals + if (!Arrays.equals(myOs, test.myOs)) return false; + + return true; + } + + public int hashCode() { + int result = myOs != null ? myOs.hashCode() : 0; + result = 31 * result + (myIIs != null ? myIIs.hashCode() : 0); + result = 31 * result + (myIs != null ? myIs.hashCode() : 0); + return result; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterArraysFromJava15.java b/java/java-tests/testData/codeInsight/generateEquals/afterArraysFromJava15.java new file mode 100644 index 000000000000..cc5a036a3e24 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterArraysFromJava15.java @@ -0,0 +1,28 @@ +import java.util.Arrays; + +class Test { + Object[] myOs; + int[][] myIIs; + int[] myIs; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + // Compare nested arrays - values of myIIs here + if (!Arrays.equals(myIs, test.myIs)) return false; + // Probably incorrect - comparing Object[] arrays with Arrays.equals + if (!Arrays.equals(myOs, test.myOs)) return false; + + return true; + } + + public int hashCode() { + int result = myOs != null ? Arrays.hashCode(myOs) : 0; + result = 31 * result + (myIIs != null ? Arrays.hashCode(myIIs) : 0); + result = 31 * result + (myIs != null ? Arrays.hashCode(myIs) : 0); + return result; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterFields.java b/java/java-tests/testData/codeInsight/generateEquals/afterFields.java new file mode 100644 index 000000000000..763194e8ed96 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterFields.java @@ -0,0 +1,22 @@ +class Test { + int i; + Test a; + Test b; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (i != test.i) return false; + if (!a.equals(test.a)) return false; + if (b != null ? !b.equals(test.b) : test.b != null) return false; + + return true; + } + + public int hashCode() { + return 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterHashCode.java b/java/java-tests/testData/codeInsight/generateEquals/afterHashCode.java new file mode 100644 index 000000000000..46ae180326a7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterHashCode.java @@ -0,0 +1,31 @@ +class Test { + int i; + Test a; + Test b; + double c; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (Double.compare(test.c, c) != 0) return false; + if (i != test.i) return false; + if (!a.equals(test.a)) return false; + if (b != null ? !b.equals(test.b) : test.b != null) return false; + + return true; + } + + public int hashCode() { + int result; + long temp; + result = i; + result = 31 * result + a.hashCode(); + result = 31 * result + (b != null ? b.hashCode() : 0); + temp = c != +0.0d ? Double.doubleToLongBits(c) : 0L; + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterInsertOverride.java b/java/java-tests/testData/codeInsight/generateEquals/afterInsertOverride.java new file mode 100644 index 000000000000..142a723a06e3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterInsertOverride.java @@ -0,0 +1,20 @@ +class Test { + int i; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (i != test.i) return false; + + return true; + } + + @Override + public int hashCode() { + return i; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterLangClass.java b/java/java-tests/testData/codeInsight/generateEquals/afterLangClass.java new file mode 100644 index 000000000000..daf3edf8773b --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterLangClass.java @@ -0,0 +1,20 @@ +class Integer { + int i; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Integer integer = (Integer) o; + + if (i != integer.i) return false; + + return true; + } + + @Override + public int hashCode() { + return i; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterLocalLangClass.java b/java/java-tests/testData/codeInsight/generateEquals/afterLocalLangClass.java new file mode 100644 index 000000000000..2d604e430aa1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterLocalLangClass.java @@ -0,0 +1,24 @@ +class Test { + void foo() { + class Integer { + int i; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Integer integer = (Integer) o; + + if (i != integer.i) return false; + + return true; + } + + @Override + public int hashCode() { + return i; + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterNoBaseEquals.java b/java/java-tests/testData/codeInsight/generateEquals/afterNoBaseEquals.java new file mode 100644 index 000000000000..cc6143dcf2f1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterNoBaseEquals.java @@ -0,0 +1,12 @@ +public class Test { + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + return true; + } + + public int hashCode() { + return 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterNotNull.java b/java/java-tests/testData/codeInsight/generateEquals/afterNotNull.java new file mode 100644 index 000000000000..0ca118388bdb --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterNotNull.java @@ -0,0 +1,18 @@ +class Test { + @org.jetbrains.annotations.NotNull Object d; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (d != null ? !d.equals(test.d) : test.d != null) return false; + + return true; + } + + public int hashCode() { + return d != null ? d.hashCode() : 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterOneDoubleField.java b/java/java-tests/testData/codeInsight/generateEquals/afterOneDoubleField.java new file mode 100644 index 000000000000..1c47228b9e66 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterOneDoubleField.java @@ -0,0 +1,19 @@ +class Test { + double d; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (Double.compare(test.d, d) != 0) return false; + + return true; + } + + public int hashCode() { + final long temp = d != +0.0d ? Double.doubleToLongBits(d) : 0L; + return (int) (temp ^ (temp >>> 32)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterOneField.java b/java/java-tests/testData/codeInsight/generateEquals/afterOneField.java new file mode 100644 index 000000000000..d8a067833c50 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterOneField.java @@ -0,0 +1,18 @@ +class Test { + Object d; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (d != null ? !d.equals(test.d) : test.d != null) return false; + + return true; + } + + public int hashCode() { + return d != null ? d.hashCode() : 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterOneFloatField.java b/java/java-tests/testData/codeInsight/generateEquals/afterOneFloatField.java new file mode 100644 index 000000000000..f449b757c688 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterOneFloatField.java @@ -0,0 +1,18 @@ +class Test { + float d; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (Float.compare(test.d, d) != 0) return false; + + return true; + } + + public int hashCode() { + return (d != +0.0f ? Float.floatToIntBits(d) : 0); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterPrimitiveFields.java b/java/java-tests/testData/codeInsight/generateEquals/afterPrimitiveFields.java new file mode 100644 index 000000000000..3ccd0e0e9937 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterPrimitiveFields.java @@ -0,0 +1,22 @@ +public class Test { + int f; + public int j; + int h; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Test test = (Test) o; + + if (f != test.f) return false; + if (h != test.h) return false; + if (j != test.j) return false; + + return true; + } + + public int hashCode() { + return 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterSuperEquals.java b/java/java-tests/testData/codeInsight/generateEquals/afterSuperEquals.java new file mode 100644 index 000000000000..0cf488afa972 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterSuperEquals.java @@ -0,0 +1,17 @@ +abstract class SuperTest { + public boolean equals(Object object) { + return true; + } + public int hashCode() { + return 0; + } +} +class Test extends SuperTest { + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + return true; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeAbstractSuperEquals.java b/java/java-tests/testData/codeInsight/generateEquals/beforeAbstractSuperEquals.java new file mode 100644 index 000000000000..37b74df4587d --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeAbstractSuperEquals.java @@ -0,0 +1,5 @@ +abstract class SuperTest { + public abstract boolean equals(Object object); +} +class Test extends SuperTest { +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeArrays.java b/java/java-tests/testData/codeInsight/generateEquals/beforeArrays.java new file mode 100644 index 000000000000..1d99c4fa4160 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeArrays.java @@ -0,0 +1,5 @@ +class Test { + Object[] myOs; + int[][] myIIs; + int[] myIs; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeArraysFromJava15.java b/java/java-tests/testData/codeInsight/generateEquals/beforeArraysFromJava15.java new file mode 100644 index 000000000000..1d99c4fa4160 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeArraysFromJava15.java @@ -0,0 +1,5 @@ +class Test { + Object[] myOs; + int[][] myIIs; + int[] myIs; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeFields.java b/java/java-tests/testData/codeInsight/generateEquals/beforeFields.java new file mode 100644 index 000000000000..014c0cd40946 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeFields.java @@ -0,0 +1,5 @@ +class Test { + int i; + Test a; + Test b; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeHashCode.java b/java/java-tests/testData/codeInsight/generateEquals/beforeHashCode.java new file mode 100644 index 000000000000..fbea244fe5b5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeHashCode.java @@ -0,0 +1,6 @@ +class Test { + int i; + Test a; + Test b; + double c; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeInsertOverride.java b/java/java-tests/testData/codeInsight/generateEquals/beforeInsertOverride.java new file mode 100644 index 000000000000..0694e03bdeeb --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeInsertOverride.java @@ -0,0 +1,3 @@ +class Test { + int i; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeLangClass.java b/java/java-tests/testData/codeInsight/generateEquals/beforeLangClass.java new file mode 100644 index 000000000000..7efa66787d6d --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeLangClass.java @@ -0,0 +1,3 @@ +class Integer { + int i; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeLocalLangClass.java b/java/java-tests/testData/codeInsight/generateEquals/beforeLocalLangClass.java new file mode 100644 index 000000000000..950e3d6120d1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeLocalLangClass.java @@ -0,0 +1,7 @@ +class Test { + void foo() { + class Integer { + int i; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeNoBaseEquals.java b/java/java-tests/testData/codeInsight/generateEquals/beforeNoBaseEquals.java new file mode 100644 index 000000000000..518efb8d3010 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeNoBaseEquals.java @@ -0,0 +1,2 @@ +public class Test { +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeNotNull.java b/java/java-tests/testData/codeInsight/generateEquals/beforeNotNull.java new file mode 100644 index 000000000000..19b04f5d38a5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeNotNull.java @@ -0,0 +1,3 @@ +class Test { + @org.jetbrains.annotations.NotNull Object d; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeOneDoubleField.java b/java/java-tests/testData/codeInsight/generateEquals/beforeOneDoubleField.java new file mode 100644 index 000000000000..13973f7e09f8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeOneDoubleField.java @@ -0,0 +1,3 @@ +class Test { + double d; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeOneField.java b/java/java-tests/testData/codeInsight/generateEquals/beforeOneField.java new file mode 100644 index 000000000000..66266e6522ca --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeOneField.java @@ -0,0 +1,3 @@ +class Test { + Object d; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeOneFloatField.java b/java/java-tests/testData/codeInsight/generateEquals/beforeOneFloatField.java new file mode 100644 index 000000000000..36d4f187fafc --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeOneFloatField.java @@ -0,0 +1,3 @@ +class Test { + float d; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforePrimitiveFields.java b/java/java-tests/testData/codeInsight/generateEquals/beforePrimitiveFields.java new file mode 100644 index 000000000000..154fdf0005d1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforePrimitiveFields.java @@ -0,0 +1,5 @@ +public class Test { + int f; + public int j; + int h; +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeSuperEquals.java b/java/java-tests/testData/codeInsight/generateEquals/beforeSuperEquals.java new file mode 100644 index 000000000000..ad4972c3b72e --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeSuperEquals.java @@ -0,0 +1,10 @@ +abstract class SuperTest { + public boolean equals(Object object) { + return true; + } + public int hashCode() { + return 0; + } +} +class Test extends SuperTest { +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEquals15Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEquals15Test.java new file mode 100644 index 000000000000..9026d776f077 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEquals15Test.java @@ -0,0 +1,10 @@ +package com.intellij.codeInsight; + +/** + * @author dsl + */ +public class GenerateEquals15Test extends GenerateEqualsTestCase { + public void testArraysFromJava15() throws Exception { + doTest(new int[]{0, 1, 2}, new int[]{0, 1, 2}, new int[0], false); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java new file mode 100644 index 000000000000..3dcaccc5b4a1 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java @@ -0,0 +1,70 @@ +package com.intellij.codeInsight; + +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.testFramework.IdeaTestUtil; + +/** + * @author dsl + */ +public class GenerateEqualsTest extends GenerateEqualsTestCase { + public void testNoBaseEquals() throws Exception { + doTest(new int[0], new int[0], new int[0], false); + } + + public void testPrimitiveFields() throws Exception { + doTest(new int[]{0, 1, 2}, new int[0], new int[0], false); + } + + public void testFields() throws Exception { + doTest(new int[]{0, 1, 2}, new int[0], new int[]{1}, false); + } + + public void testAbstractSuperEquals() throws Exception { + doTest(new int[0], new int[0], new int[0], false); + } + + public void testSuperEquals() throws Exception { + doTest(new int[0], new int[0], new int[0], false); + } + + public void testHashCode() throws Exception { + doTest(new int[]{0, 1, 2, 3}, new int[]{0, 1, 2, 3}, new int[]{1}, false); + } + + public void testArrays() throws Exception { + doTest(new int[]{0, 1, 2}, new int[]{0, 1, 2}, new int[0], false); + } + + public void testOneDoubleField() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], false); + } + + public void testOneFloatField() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], false); + } + + public void testOneField() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], false); + } + + public void testNotNull() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], false); + } + + public void testInsertOverride() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], true); + } + + public void testLangClass() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], true); + } + + public void testLocalLangClass() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], true); + } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk14(); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTestCase.java b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTestCase.java new file mode 100644 index 000000000000..6a0ce2077051 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTestCase.java @@ -0,0 +1,53 @@ +package com.intellij.codeInsight; + +import com.intellij.codeInsight.generation.GenerateEqualsHelper; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.testFramework.LightCodeInsightTestCase; + +import java.util.ArrayList; + +/** + * @author yole + */ +public abstract class GenerateEqualsTestCase extends LightCodeInsightTestCase { + protected void doTest(int[] equals, int[] hashCode, int[] nonNull, boolean insertOverride) throws Exception { + configureByFile("/codeInsight/generateEquals/before" + getTestName(false) + ".java"); + performTest(equals, hashCode, nonNull, insertOverride); + checkResultByFile("/codeInsight/generateEquals/after" + getTestName(false) + ".java"); + } + + private static void performTest(int[] equals, int[] hashCode, int[] nonNull, boolean insertOverride) { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()).clone(); + settings.GENERATE_FINAL_LOCALS = true; + settings.INSERT_OVERRIDE_ANNOTATION = insertOverride; + CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(settings); + try { + PsiElement element = getFile().findElementAt(getEditor().getCaretModel().getOffset()); + if (element == null) return; + PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); + if (aClass == null) return; + PsiField[] fields = aClass.getFields(); + new GenerateEqualsHelper(getProject(), aClass, getIndexed(fields, equals), getIndexed(fields, hashCode), getIndexed(fields, nonNull), + false) + .invoke(); + FileDocumentManager.getInstance().saveAllDocuments(); + } + finally { + CodeStyleSettingsManager.getInstance(getProject()).dropTemporarySettings(); + } + } + + private static PsiField[] getIndexed(PsiField[] fields, int[] indices) { + ArrayList result = new ArrayList(); + for (int indice : indices) { + result.add(fields[indice]); + } + return result.toArray(new PsiField[result.size()]); + } +} From d683b1ba48815a88f6ab6a82b6c21230ad429b2f Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 12 Feb 2013 13:21:42 +0400 Subject: [PATCH 39/42] Change configuration in the write action only! --- .../MavenDefaultModifiableModelsProvider.java | 58 +++--- .../maven/importing/MavenModuleImporter.java | 159 ---------------- .../maven/importing/MavenProjectImporter.java | 83 ++++---- .../MavenUIModifiableModelsProvider.java | 6 +- .../MavenAnnotationProcessorConfigurer.java | 179 ++++++++++++++++++ .../configurers/MavenCompilerConfigurer.java | 59 ++++++ .../configurers/MavenEncodingConfigurer.java | 44 +++++ .../configurers/MavenModuleConfigurer.java | 57 ++++++ .../AnnotationProcessorImportingTest.groovy | 27 +-- 9 files changed, 411 insertions(+), 261 deletions(-) create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenAnnotationProcessorConfigurer.java create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenCompilerConfigurer.java create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenEncodingConfigurer.java create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenModuleConfigurer.java diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenDefaultModifiableModelsProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenDefaultModifiableModelsProvider.java index 81ddd7cbdc2b..2599d5861775 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenDefaultModifiableModelsProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenDefaultModifiableModelsProvider.java @@ -106,47 +106,39 @@ public class MavenDefaultModifiableModelsProvider extends MavenBaseModifiableMod } public void commit() { - MavenUtil.invokeAndWaitWriteAction(myProject, new Runnable() { + ((ProjectRootManagerEx)ProjectRootManager.getInstance(myProject)).mergeRootsChangesDuring(new Runnable() { public void run() { - ((ProjectRootManagerEx)ProjectRootManager.getInstance(myProject)).mergeRootsChangesDuring(new Runnable() { - public void run() { - processExternalArtifactDependencies(); - for (Library.ModifiableModel each : myLibraryModels.values()) { - each.commit(); - } - myLibrariesModel.commit(); - Collection rootModels = myRootModels.values(); + processExternalArtifactDependencies(); + for (Library.ModifiableModel each : myLibraryModels.values()) { + each.commit(); + } + myLibrariesModel.commit(); + Collection rootModels = myRootModels.values(); - ModifiableRootModel[] rootModels1 = rootModels.toArray(new ModifiableRootModel[rootModels.size()]); - for (ModifiableRootModel model : rootModels1) { - assert !model.isDisposed() : "Already disposed: " + model; - } - ModifiableModelCommitter.multiCommit(rootModels1, myModuleModel); + ModifiableRootModel[] rootModels1 = rootModels.toArray(new ModifiableRootModel[rootModels.size()]); + for (ModifiableRootModel model : rootModels1) { + assert !model.isDisposed() : "Already disposed: " + model; + } + ModifiableModelCommitter.multiCommit(rootModels1, myModuleModel); - for (ModifiableFacetModel each : myFacetModels.values()) { - each.commit(); - } - if (myArtifactModel != null) { - myArtifactModel.commit(); - } - } - }); + for (ModifiableFacetModel each : myFacetModels.values()) { + each.commit(); + } + if (myArtifactModel != null) { + myArtifactModel.commit(); + } } }); } public void dispose() { - MavenUtil.invokeAndWaitWriteAction(myProject, new Runnable() { - public void run() { - for (ModifiableRootModel each : myRootModels.values()) { - each.dispose(); - } - myModuleModel.dispose(); - if (myArtifactModel != null) { - myArtifactModel.dispose(); - } - } - }); + for (ModifiableRootModel each : myRootModels.values()) { + each.dispose(); + } + myModuleModel.dispose(); + if (myArtifactModel != null) { + myArtifactModel.dispose(); + } } public ModalityState getModalityStateForQuestionDialogs() { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java index f7e2e59ea715..ee7fc3d3d821 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java @@ -48,13 +48,7 @@ import java.util.Map; public class MavenModuleImporter { - public static final String PROFILE_PREFIX = "Annotation profile for "; - - public static final String MAVEN_DEFAULT_ANNOTATION_PROFILE = "Maven default annotation processors profile"; - public static final String SUREFIRE_PLUGIN_LIBRARY_NAME = "maven-surefire-plugin urls"; - public static final String DEFAULT_ANNOTATION_PATH_OUTPUT = "target/generated-sources/annotations"; - public static final String DEFAULT_TEST_ANNOTATION_OUTPUT = "target/generated-test-sources/test-annotations"; private final Module myModule; private final MavenProjectsTree myMavenTree; @@ -94,26 +88,6 @@ public class MavenModuleImporter { configFolders(); configDependencies(); configLanguageLevel(); - configAnnotationProcessors(); - excludeFromCompilationArchetypeResources(); - } - - private void excludeFromCompilationArchetypeResources() { - VirtualFile directoryFile = myMavenProject.getDirectoryFile(); - - VirtualFile archetypeResourcesDir = VfsUtil.findRelativeFile(directoryFile, "src", "main", "resources", "archetype-resources"); - - if (archetypeResourcesDir != null) { - Project project = myModule.getProject(); - - CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project); - - if (!compilerConfiguration.isExcludedFromCompilation(archetypeResourcesDir)) { - ExcludedEntriesConfiguration cfg = compilerConfiguration.getExcludedEntriesConfiguration(); - - cfg.addExcludeEntryDescription(new ExcludeEntryDescription(archetypeResourcesDir, true, false, project)); - } - } } public void preConfigFacets() { @@ -267,139 +241,6 @@ public class MavenModuleImporter { } } - private void configAnnotationProcessors() { - if (Boolean.parseBoolean(System.getProperty("idea.maven.keep.annotation.processors"))) return; - - Sdk sdk = ModuleRootManager.getInstance(myModule).getSdk(); - if (sdk != null) { - String versionString = sdk.getVersionString(); - if (versionString != null) { - if (versionString.contains("1.5") || versionString.contains("1.4") || versionString.contains("1.3") || versionString.contains("1.2")) { - return; - } - } - } - - CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance( - myModule.getProject()); - - ProcessorConfigProfile currentProfile = compilerConfiguration.getAnnotationProcessingConfiguration(myModule); - - String moduleProfileName = PROFILE_PREFIX + myModule.getName(); - - if (currentProfile != compilerConfiguration.getDefaultProcessorProfile() - && !MAVEN_DEFAULT_ANNOTATION_PROFILE.equals(currentProfile.getName()) - && !moduleProfileName.equals(currentProfile.getName())) { - return; - } - - ProcessorConfigProfile moduleProfile = compilerConfiguration.findModuleProcessorProfile(moduleProfileName); - - ProcessorConfigProfile defaultMavenProfile = compilerConfiguration.findModuleProcessorProfile(MAVEN_DEFAULT_ANNOTATION_PROFILE); - - if (shouldEnableAnnotationProcessors()) { - String annotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(false); - if (annotationProcessorDirectory == null) { - annotationProcessorDirectory = DEFAULT_ANNOTATION_PATH_OUTPUT; - } - - String testAnnotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(true); - if (testAnnotationProcessorDirectory == null) { - testAnnotationProcessorDirectory = DEFAULT_TEST_ANNOTATION_OUTPUT; - } - - Map options = myMavenProject.getAnnotationProcessorOptions(); - - List processors = myMavenProject.getDeclaredAnnotationProcessors(); - - if (processors == null - && options.isEmpty() - && DEFAULT_ANNOTATION_PATH_OUTPUT.equals(annotationProcessorDirectory.replace('\\', '/')) - && DEFAULT_TEST_ANNOTATION_OUTPUT.equals(testAnnotationProcessorDirectory.replace('\\', '/'))) { - if (moduleProfile != null) { - compilerConfiguration.removeModuleProcessorProfile(moduleProfile); - } - - if (defaultMavenProfile == null) { - defaultMavenProfile = new ProcessorConfigProfileImpl(MAVEN_DEFAULT_ANNOTATION_PROFILE); - defaultMavenProfile.setEnabled(true); - defaultMavenProfile.setOutputRelativeToContentRoot(true); - defaultMavenProfile.setObtainProcessorsFromClasspath(true); - defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_ANNOTATION_PATH_OUTPUT, false); - defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_TEST_ANNOTATION_OUTPUT, true); - compilerConfiguration.addModuleProcessorProfile(defaultMavenProfile); - } - - defaultMavenProfile.addModuleName(myModule.getName()); - } - else { - if (defaultMavenProfile != null) { - defaultMavenProfile.removeModuleName(myModule.getName()); - - if (defaultMavenProfile.getModuleNames().isEmpty()) { - compilerConfiguration.removeModuleProcessorProfile(defaultMavenProfile); - } - } - - if (moduleProfile == null) { - moduleProfile = new ProcessorConfigProfileImpl(moduleProfileName); - moduleProfile.setOutputRelativeToContentRoot(true); - moduleProfile.setEnabled(true); - moduleProfile.setObtainProcessorsFromClasspath(true); - moduleProfile.addModuleName(myModule.getName()); - compilerConfiguration.addModuleProcessorProfile(moduleProfile); - } - - moduleProfile.setGeneratedSourcesDirectoryName(annotationProcessorDirectory, false); - moduleProfile.setGeneratedSourcesDirectoryName(testAnnotationProcessorDirectory, true); - - moduleProfile.clearProcessorOptions(); - for (Map.Entry entry : options.entrySet()) { - moduleProfile.setOption(entry.getKey(), entry.getValue()); - } - - moduleProfile.clearProcessors(); - - if (processors != null) { - for (String processor : processors) { - moduleProfile.addProcessor(processor); - } - } - } - } - else { - if (defaultMavenProfile != null) { - defaultMavenProfile.removeModuleName(myModule.getName()); - - if (defaultMavenProfile.getModuleNames().isEmpty()) { - compilerConfiguration.removeModuleProcessorProfile(defaultMavenProfile); - } - } - - if (moduleProfile != null) { - compilerConfiguration.removeModuleProcessorProfile(moduleProfile); - } - } - } - - @Nullable - private String getRelativeAnnotationProcessorDirectory(boolean isTest) { - String annotationProcessorDirectory = myMavenProject.getAnnotationProcessorDirectory(isTest); - File annotationProcessorDirectoryFile = new File(annotationProcessorDirectory); - if (!annotationProcessorDirectoryFile.isAbsolute()) { - return annotationProcessorDirectory; - } - - String absoluteProjectDirectory = myMavenProject.getDirectory(); - return FileUtil.getRelativePath(new File(absoluteProjectDirectory), annotationProcessorDirectoryFile); - } - - private boolean shouldEnableAnnotationProcessors() { - if ("pom".equals(myMavenProject.getPackaging())) return false; - - return myMavenProject.getProcMode() != MavenProject.ProcMode.NONE || myMavenProject.getPluginConfiguration("org.bsc.maven", "maven-processor-plugin") != null; - } - @NotNull private static DependencyScope selectScope(String mavenScope) { if (MavenConstants.SCOPE_RUNTIME.equals(mavenScope)) return DependencyScope.RUNTIME; diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java index 33889304badf..de4cd5f4c22f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java @@ -15,8 +15,6 @@ */ package org.jetbrains.idea.maven.importing; -import com.intellij.compiler.CompilerConfiguration; -import com.intellij.compiler.CompilerConfigurationImpl; import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.ModifiableModuleModel; @@ -33,13 +31,13 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.containers.Stack; import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.importing.configurers.MavenModuleConfigurer; import org.jetbrains.idea.maven.model.MavenArtifact; import org.jetbrains.idea.maven.project.*; import org.jetbrains.idea.maven.utils.MavenLog; @@ -50,9 +48,6 @@ import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions; import java.io.File; import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.UnsupportedCharsetException; import java.util.*; public class MavenProjectImporter { @@ -95,20 +90,20 @@ public class MavenProjectImporter { public List importProject() { List postTasks = new ArrayList(); - boolean hasChanges = false; + boolean hasChanges; // in the case projects are changed during importing we must memorise them myAllProjects = new LinkedHashSet(myProjectsTree.getProjects()); myAllProjects.addAll(myProjectsToImportWithChanges.keySet()); // some projects may already have been removed from the tree - hasChanges |= deleteIncompatibleModules(); + hasChanges = deleteIncompatibleModules(); myProjectsToImportWithChanges = collectProjectsToImport(myProjectsToImportWithChanges); mapMavenProjectsToModulesAndNames(); if (myProject.isDisposed()) return null; - boolean projectsHaveChanges = projectsToImportHaveChanges(); + final boolean projectsHaveChanges = projectsToImportHaveChanges(); if (projectsHaveChanges) { hasChanges = true; importModules(postTasks); @@ -128,16 +123,30 @@ public class MavenProjectImporter { removeUnusedProjectLibraries(); } - if (hasChanges) { - myModelsProvider.commit(); + final boolean finalHasChanges = hasChanges; - if (projectsHaveChanges) { - configSettings(); + MavenUtil.invokeAndWaitWriteAction(myProject, new Runnable() { + public void run() { + if (finalHasChanges) { + myModelsProvider.commit(); + + if (projectsHaveChanges) { + removeOutdatedCompilerConfigSettings(); + + for (MavenProject mavenProject : myAllProjects) { + Module module = myMavenProjectToModule.get(mavenProject); + + for (MavenModuleConfigurer configurer : MavenModuleConfigurer.getConfigurers()) { + configurer.configure(mavenProject, myProject, module); + } + } + } + } + else { + myModelsProvider.dispose(); + } } - } - else { - myModelsProvider.dispose(); - } + }); return postTasks; } @@ -381,41 +390,13 @@ public class MavenProjectImporter { myImportingSettings.getDedicatedModuleDir()); } - private void configSettings() { - MavenUtil.invokeAndWaitWriteAction(myProject, new Runnable() { - public void run() { - CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject); + private void removeOutdatedCompilerConfigSettings() { + ApplicationManager.getApplication().assertWriteAccessAllowed(); - MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(myProject); - - for (MavenProject project : myAllProjects) { - String targetLevel = project.getTargetLevel(); - - if (targetLevel != null) { - Module module = projectsManager.findModule(project); - if (module != null) { - configuration.setBytecodeTargetLevel(module, targetLevel); - } - } - - if (!Boolean.parseBoolean(System.getProperty("maven.disable.encode.import"))) { - String encoding = project.getEncoding(); - if (encoding != null) { - try { - EncodingProjectManager.getInstance(myProject).setEncoding(project.getDirectoryFile(), Charset.forName(encoding)); - } - catch (UnsupportedCharsetException ignored) {/**/} - catch (IllegalCharsetNameException ignored) {/**/} - } - } - } - - final JpsJavaCompilerOptions javacOptions = JavacConfiguration.getOptions(myProject, JavacConfiguration.class); - String options = javacOptions.ADDITIONAL_OPTIONS_STRING; - options = options.replaceFirst("(-target (\\S+))", ""); // Old IDEAs saved - javacOptions.ADDITIONAL_OPTIONS_STRING = options; - } - }); + final JpsJavaCompilerOptions javacOptions = JavacConfiguration.getOptions(myProject, JavacConfiguration.class); + String options = javacOptions.ADDITIONAL_OPTIONS_STRING; + options = options.replaceFirst("(-target (\\S+))", ""); // Old IDEAs saved + javacOptions.ADDITIONAL_OPTIONS_STRING = options; } private void importModules(final List postTasks) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenUIModifiableModelsProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenUIModifiableModelsProvider.java index f0ec25c6f429..a35f2f6fecfa 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenUIModifiableModelsProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenUIModifiableModelsProvider.java @@ -95,11 +95,7 @@ public class MavenUIModifiableModelsProvider extends MavenBaseModifiableModelsPr } public void commit() { - MavenUtil.invokeAndWaitWriteAction(myProject, new Runnable() { - public void run() { - processExternalArtifactDependencies(); - } - }); + processExternalArtifactDependencies(); } public void dispose() { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenAnnotationProcessorConfigurer.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenAnnotationProcessorConfigurer.java new file mode 100644 index 000000000000..f1604575ff51 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenAnnotationProcessorConfigurer.java @@ -0,0 +1,179 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.importing.configurers; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerConfigurationImpl; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.project.MavenProject; +import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile; +import org.jetbrains.jps.model.java.impl.compiler.ProcessorConfigProfileImpl; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + * @author Sergey Evdokimov + */ +public class MavenAnnotationProcessorConfigurer extends MavenModuleConfigurer { + + public static final String PROFILE_PREFIX = "Annotation profile for "; + public static final String MAVEN_DEFAULT_ANNOTATION_PROFILE = "Maven default annotation processors profile"; + public static final String DEFAULT_ANNOTATION_PATH_OUTPUT = "target/generated-sources/annotations"; + public static final String DEFAULT_TEST_ANNOTATION_OUTPUT = "target/generated-test-sources/test-annotations"; + + @Override + public void configure(@NotNull MavenProject mavenProject, @NotNull Project project, @Nullable Module module) { + if (module == null) return; + + Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); + if (sdk != null) { + String versionString = sdk.getVersionString(); + if (versionString != null) { + if (versionString.contains("1.5") || versionString.contains("1.4") || versionString.contains("1.3") || versionString.contains("1.2")) { + return; + } + } + } + + CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project); + + ProcessorConfigProfile currentProfile = compilerConfiguration.getAnnotationProcessingConfiguration(module); + + String moduleProfileName = PROFILE_PREFIX + module.getName(); + + if (currentProfile != compilerConfiguration.getDefaultProcessorProfile() + && !MAVEN_DEFAULT_ANNOTATION_PROFILE.equals(currentProfile.getName()) + && !moduleProfileName.equals(currentProfile.getName())) { + return; + } + + ProcessorConfigProfile moduleProfile = compilerConfiguration.findModuleProcessorProfile(moduleProfileName); + + ProcessorConfigProfile defaultMavenProfile = compilerConfiguration.findModuleProcessorProfile(MAVEN_DEFAULT_ANNOTATION_PROFILE); + + if (shouldEnableAnnotationProcessors(mavenProject)) { + String annotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(mavenProject, false); + if (annotationProcessorDirectory == null) { + annotationProcessorDirectory = DEFAULT_ANNOTATION_PATH_OUTPUT; + } + + String testAnnotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(mavenProject, true); + if (testAnnotationProcessorDirectory == null) { + testAnnotationProcessorDirectory = DEFAULT_TEST_ANNOTATION_OUTPUT; + } + + Map options = mavenProject.getAnnotationProcessorOptions(); + + List processors = mavenProject.getDeclaredAnnotationProcessors(); + + if (processors == null + && options.isEmpty() + && DEFAULT_ANNOTATION_PATH_OUTPUT.equals(annotationProcessorDirectory.replace('\\', '/')) + && DEFAULT_TEST_ANNOTATION_OUTPUT.equals(testAnnotationProcessorDirectory.replace('\\', '/'))) { + if (moduleProfile != null) { + compilerConfiguration.removeModuleProcessorProfile(moduleProfile); + } + + if (defaultMavenProfile == null) { + defaultMavenProfile = new ProcessorConfigProfileImpl(MAVEN_DEFAULT_ANNOTATION_PROFILE); + defaultMavenProfile.setEnabled(true); + defaultMavenProfile.setOutputRelativeToContentRoot(true); + defaultMavenProfile.setObtainProcessorsFromClasspath(true); + defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_ANNOTATION_PATH_OUTPUT, false); + defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_TEST_ANNOTATION_OUTPUT, true); + compilerConfiguration.addModuleProcessorProfile(defaultMavenProfile); + } + + defaultMavenProfile.addModuleName(module.getName()); + } + else { + if (defaultMavenProfile != null) { + defaultMavenProfile.removeModuleName(module.getName()); + + if (defaultMavenProfile.getModuleNames().isEmpty()) { + compilerConfiguration.removeModuleProcessorProfile(defaultMavenProfile); + } + } + + if (moduleProfile == null) { + moduleProfile = new ProcessorConfigProfileImpl(moduleProfileName); + moduleProfile.setOutputRelativeToContentRoot(true); + moduleProfile.setEnabled(true); + moduleProfile.setObtainProcessorsFromClasspath(true); + moduleProfile.addModuleName(module.getName()); + compilerConfiguration.addModuleProcessorProfile(moduleProfile); + } + + moduleProfile.setGeneratedSourcesDirectoryName(annotationProcessorDirectory, false); + moduleProfile.setGeneratedSourcesDirectoryName(testAnnotationProcessorDirectory, true); + + moduleProfile.clearProcessorOptions(); + for (Map.Entry entry : options.entrySet()) { + moduleProfile.setOption(entry.getKey(), entry.getValue()); + } + + moduleProfile.clearProcessors(); + + if (processors != null) { + for (String processor : processors) { + moduleProfile.addProcessor(processor); + } + } + } + } + else { + if (defaultMavenProfile != null) { + defaultMavenProfile.removeModuleName(module.getName()); + + if (defaultMavenProfile.getModuleNames().isEmpty()) { + compilerConfiguration.removeModuleProcessorProfile(defaultMavenProfile); + } + } + + if (moduleProfile != null) { + compilerConfiguration.removeModuleProcessorProfile(moduleProfile); + } + } + } + + @Nullable + private String getRelativeAnnotationProcessorDirectory(MavenProject mavenProject, boolean isTest) { + String annotationProcessorDirectory = mavenProject.getAnnotationProcessorDirectory(isTest); + File annotationProcessorDirectoryFile = new File(annotationProcessorDirectory); + if (!annotationProcessorDirectoryFile.isAbsolute()) { + return annotationProcessorDirectory; + } + + String absoluteProjectDirectory = mavenProject.getDirectory(); + return FileUtil.getRelativePath(new File(absoluteProjectDirectory), annotationProcessorDirectoryFile); + } + + private static boolean shouldEnableAnnotationProcessors(MavenProject mavenProject) { + if ("pom".equals(mavenProject.getPackaging())) return false; + + return mavenProject.getProcMode() != MavenProject.ProcMode.NONE + || mavenProject.getPluginConfiguration("org.bsc.maven", "maven-processor-plugin") != null; + } + +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenCompilerConfigurer.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenCompilerConfigurer.java new file mode 100644 index 000000000000..afd4bc786fef --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenCompilerConfigurer.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.importing.configurers; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerConfigurationImpl; +import com.intellij.openapi.compiler.options.ExcludeEntryDescription; +import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.project.MavenProject; + +/** + * @author Sergey Evdokimov + */ +public class MavenCompilerConfigurer extends MavenModuleConfigurer { + @Override + public void configure(@NotNull MavenProject mavenProject, @NotNull Project project, @Nullable Module module) { + if (module == null) return; + + String targetLevel = mavenProject.getTargetLevel(); + if (targetLevel != null) { + CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project); + configuration.setBytecodeTargetLevel(module, targetLevel); + } + + VirtualFile directoryFile = mavenProject.getDirectoryFile(); + + // Exclude src/main/archetype-resources + VirtualFile archetypeResourcesDir = VfsUtil.findRelativeFile(directoryFile, "src", "main", "resources", "archetype-resources"); + + if (archetypeResourcesDir != null) { + CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project); + + if (!compilerConfiguration.isExcludedFromCompilation(archetypeResourcesDir)) { + ExcludedEntriesConfiguration cfg = compilerConfiguration.getExcludedEntriesConfiguration(); + + cfg.addExcludeEntryDescription(new ExcludeEntryDescription(archetypeResourcesDir, true, false, project)); + } + } + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenEncodingConfigurer.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenEncodingConfigurer.java new file mode 100644 index 000000000000..cb05f6b3b028 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenEncodingConfigurer.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.importing.configurers; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.encoding.EncodingProjectManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.project.MavenProject; + +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; + +/** + * @author Sergey Evdokimov + */ +public class MavenEncodingConfigurer extends MavenModuleConfigurer { + @Override + public void configure(@NotNull MavenProject mavenProject, @NotNull Project project, @Nullable Module module) { + String encoding = mavenProject.getEncoding(); + if (encoding != null) { + try { + EncodingProjectManager.getInstance(project).setEncoding(mavenProject.getDirectoryFile(), Charset.forName(encoding)); + } + catch (UnsupportedCharsetException ignored) {/**/} + catch (IllegalCharsetNameException ignored) {/**/} + } + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenModuleConfigurer.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenModuleConfigurer.java new file mode 100644 index 000000000000..eb60d8253c2c --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/configurers/MavenModuleConfigurer.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.importing.configurers; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.project.MavenProject; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sergey Evdokimov + */ +public abstract class MavenModuleConfigurer { + + private static volatile List ourConfigurersList; + + public abstract void configure(@NotNull MavenProject mavenProject, @NotNull Project project, @Nullable Module module); + + public static List getConfigurers() { + List configurers = ourConfigurersList; + if (configurers == null) { + configurers = new ArrayList(); + + for (MavenModuleConfigurer configurer : new MavenModuleConfigurer[]{ + new MavenCompilerConfigurer(), + new MavenEncodingConfigurer(), + new MavenAnnotationProcessorConfigurer()}) { + + if (!Boolean.parseBoolean(System.getProperty("idea.maven.disable." + configurer.getClass().getSimpleName()))) { + configurers.add(configurer); + } + } + + ourConfigurersList = configurers; + } + + return configurers; + } + +} diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy index e5c4ec6a8386..097b891adcbc 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/AnnotationProcessorImportingTest.groovy @@ -18,7 +18,8 @@ package org.jetbrains.idea.maven.compiler import com.intellij.compiler.CompilerConfiguration import com.intellij.compiler.CompilerConfigurationImpl import org.jetbrains.idea.maven.MavenImportingTestCase -import org.jetbrains.idea.maven.importing.MavenModuleImporter +import org.jetbrains.idea.maven.importing.configurers.MavenAnnotationProcessorConfigurer + /** * @author Sergey Evdokimov */ @@ -125,10 +126,10 @@ class AnnotationProcessorImportingTest extends MavenImportingTestCase { def compilerConfiguration = ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject)) - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.MAVEN_DEFAULT_ANNOTATION_PROFILE).getModuleNames() == new HashSet(["module1"]) - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.PROFILE_PREFIX + 'module2').getProcessors() == new HashSet(["com.test.SourceCodeGeneratingAnnotationProcessor2"]) - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.PROFILE_PREFIX + 'module3') == null - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.PROFILE_PREFIX + 'module3_1') == null + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_DEFAULT_ANNOTATION_PROFILE).getModuleNames() == new HashSet(["module1"]) + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + 'module2').getProcessors() == new HashSet(["com.test.SourceCodeGeneratingAnnotationProcessor2"]) + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + 'module3') == null + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + 'module3_1') == null } public void testOverrideGeneratedOutputDir() { @@ -152,8 +153,8 @@ class AnnotationProcessorImportingTest extends MavenImportingTestCase { def compilerConfiguration = ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject)) - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.PROFILE_PREFIX + "project").getGeneratedSourcesDirectoryName(false).replace('\\', '/').endsWith("out/generated") + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + "project").getGeneratedSourcesDirectoryName(false).replace('\\', '/').endsWith("out/generated") } public void testImportAnnotationProcessorOptions() { @@ -180,8 +181,8 @@ class AnnotationProcessorImportingTest extends MavenImportingTestCase { def compilerConfiguration = ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject)) - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null - def processorOptions = compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.PROFILE_PREFIX + "project").getProcessorOptions() + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null + def processorOptions = compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + "project").getProcessorOptions() assert new HashMap(processorOptions) == ['opt1': '111', 'opt2': '222', 'opt3': '333'] } @@ -226,8 +227,8 @@ class AnnotationProcessorImportingTest extends MavenImportingTestCase { def compilerConfiguration = ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject)) - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null - def profile = compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.PROFILE_PREFIX + "project") + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null + def profile = compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + "project") assert profile.getGeneratedSourcesDirectoryName(false).replace('\\', '/').endsWith("target/metamodel") assert profile.getGeneratedSourcesDirectoryName(true).replace('\\', '/').endsWith("target/metamodelTest") } @@ -284,8 +285,8 @@ class AnnotationProcessorImportingTest extends MavenImportingTestCase { def compilerConfiguration = ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject)) - assert compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null - def profile = compilerConfiguration.findModuleProcessorProfile(MavenModuleImporter.PROFILE_PREFIX + "project") + assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_DEFAULT_ANNOTATION_PROFILE) == null + def profile = compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + "project") assert profile.getGeneratedSourcesDirectoryName(false).replace('\\', '/').endsWith("target/metamodel") assert profile.getGeneratedSourcesDirectoryName(true).replace('\\', '/').endsWith("target/metamodelTest") } From 8427a76ab4ea31b9cad8d87793f3010ef59f66e5 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 12 Feb 2013 13:24:23 +0400 Subject: [PATCH 40/42] Minor changes: Inline anonymous class --- .../idea/maven/importing/MavenProjectImporter.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java index de4cd5f4c22f..b05efa89378e 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenProjectImporter.java @@ -336,6 +336,10 @@ public class MavenProjectImporter { }, "\n"); } + private static void doRefreshFiles(Set files) { + LocalFileSystem.getInstance().refreshIoFiles(files); + } + private void scheduleRefreshResolvedArtifacts(List postTasks) { // We have to refresh all the resolved artifacts manually in order to // update all the VirtualFilePointers. It is not enough to call @@ -355,21 +359,15 @@ public class MavenProjectImporter { if (each.isResolved()) files.add(each.getFile()); } - final Runnable r = new Runnable() { - public void run() { - LocalFileSystem.getInstance().refreshIoFiles(files); - } - }; - if (ApplicationManager.getApplication().isUnitTestMode()) { - r.run(); + doRefreshFiles(files); } else { postTasks.add(new MavenProjectsProcessorTask() { public void perform(Project project, MavenEmbeddersManager embeddersManager, MavenConsole console, MavenProgressIndicator indicator) throws MavenProcessCanceledException { indicator.setText("Refreshing files..."); - r.run(); + doRefreshFiles(files); } }); } From 4558b200ccd656c611c4f2219f59862ff7c1dc25 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 12 Feb 2013 10:45:54 +0100 Subject: [PATCH 41/42] allow to delete multiple recent projects simultaneously --- .../impl/welcomeScreen/RecentProjectPanel.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java index 9f158aa2634d..7c2bc8230b4d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java @@ -28,6 +28,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.UniqueNameBuilder; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ClickListener; import com.intellij.ui.ListUtil; import com.intellij.ui.components.JBList; @@ -95,17 +96,24 @@ public class RecentProjectPanel extends JPanel { ActionListener deleteAction = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - ReopenProjectAction selection = (ReopenProjectAction)myList.getSelectedValue(); + Object[] selection = myList.getSelectedValues(); - if (selection != null) { + if (selection != null && selection.length > 0) { final int rc = Messages.showOkCancelDialog(RecentProjectPanel.this, - "Remove '" + selection.getTemplatePresentation().getText() + + "Remove '" + StringUtil.join(selection, new Function() { + @Override + public String fun(Object action) { + return ((ReopenProjectAction)action).getTemplatePresentation().getText(); + } + }, "'\n'") + "' from recent projects list?", "Remove Recent Project", Messages.getQuestionIcon()); if (rc == 0) { final RecentProjectsManagerBase manager = RecentProjectsManagerBase.getInstance(); - manager.removePath(selection.getProjectPath()); + for (Object projectAction : selection) { + manager.removePath(((ReopenProjectAction)projectAction).getProjectPath()); + } ListUtil.removeSelectedItems(myList); } } From d999759ebed2b31c736b7290e8f1b7180d6d7f94 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 12 Feb 2013 10:51:56 +0100 Subject: [PATCH 42/42] generate hashCode: prevent conflicts with 'Arrays' name --- .../generation/GenerateEqualsHelper.java | 3 ++- .../generateEquals/afterArraysClass.java | 20 +++++++++++++++++++ .../generateEquals/beforeArraysClass.java | 3 +++ .../codeInsight/GenerateEqualsTest.java | 4 ++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/generateEquals/afterArraysClass.java create mode 100644 java/java-tests/testData/codeInsight/generateEquals/beforeArraysClass.java diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateEqualsHelper.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateEqualsHelper.java index 242cac2e1489..376238573e6b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateEqualsHelper.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateEqualsHelper.java @@ -394,6 +394,7 @@ public class GenerateEqualsHelper implements Runnable { buffer.append("return 0;\n}"); } PsiMethod hashCode = myFactory.createMethodFromText(buffer.toString(), null); + hashCode = (PsiMethod)myJavaCodeStyleManager.shortenClassReferences(hashCode); return (PsiMethod)myCodeStyleManager.reformat(hashCode); } @@ -471,7 +472,7 @@ public class GenerateEqualsHelper implements Runnable { private static void adjustHashCodeToArrays(@NonNls StringBuilder buffer, final PsiField field, final String name) { if (field.getType() instanceof PsiArrayType && hasArraysHashCode(field)) { - buffer.append("Arrays.hashCode("); + buffer.append("java.util.Arrays.hashCode("); buffer.append(name); buffer.append(")"); } diff --git a/java/java-tests/testData/codeInsight/generateEquals/afterArraysClass.java b/java/java-tests/testData/codeInsight/generateEquals/afterArraysClass.java new file mode 100644 index 000000000000..7a5ff00fd37f --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/afterArraysClass.java @@ -0,0 +1,20 @@ +class Arrays { + int[] i; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Arrays arrays = (Arrays) o; + + if (!java.util.Arrays.equals(i, arrays.i)) return false; + + return true; + } + + @Override + public int hashCode() { + return i != null ? i.hashCode() : 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateEquals/beforeArraysClass.java b/java/java-tests/testData/codeInsight/generateEquals/beforeArraysClass.java new file mode 100644 index 000000000000..6e8a0cc18683 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateEquals/beforeArraysClass.java @@ -0,0 +1,3 @@ +class Arrays { + int[] i; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java index 3dcaccc5b4a1..60fbd7428679 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateEqualsTest.java @@ -63,6 +63,10 @@ public class GenerateEqualsTest extends GenerateEqualsTestCase { doTest(new int[]{0}, new int[]{0}, new int[0], true); } + public void testArraysClass() throws Exception { + doTest(new int[]{0}, new int[]{0}, new int[0], true); + } + @Override protected Sdk getProjectJDK() { return IdeaTestUtil.getMockJdk14();