diff --git a/images/src/org/intellij/images/fileTypes/ImageDocumentationProvider.java b/images/src/org/intellij/images/fileTypes/ImageDocumentationProvider.java index 49199eb0da7e..eeaef61d2463 100644 --- a/images/src/org/intellij/images/fileTypes/ImageDocumentationProvider.java +++ b/images/src/org/intellij/images/fileTypes/ImageDocumentationProvider.java @@ -16,6 +16,7 @@ package org.intellij.images.fileTypes; import com.intellij.lang.documentation.AbstractDocumentationProvider; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileWithId; @@ -39,7 +40,7 @@ public class ImageDocumentationProvider extends AbstractDocumentationProvider { if (element instanceof PsiFileSystemItem && !((PsiFileSystemItem)element).isDirectory()) { final VirtualFile file = ((PsiFileSystemItem)element).getVirtualFile(); - if (file instanceof VirtualFileWithId) { + if (file instanceof VirtualFileWithId && !DumbService.isDumb(element.getProject())) { ImageInfoIndex.processValues(file, new FileBasedIndex.ValueProcessor() { public boolean process(VirtualFile file, ImageInfoIndex.ImageInfo value) { int imageWidth = value.width; diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java index eabbb0172e21..4fb04e2fd577 100644 --- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java +++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurable.java @@ -32,6 +32,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiMethodUtil; import com.intellij.ui.EditorTextFieldWithBrowseButton; import com.intellij.ui.PanelWithAnchor; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -64,7 +65,7 @@ public class ApplicationConfigurable extends SettingsEditor myPathField; private final JBCheckBox myCbEnabled; final TextFieldWithHistory myFieldWithHistory; + private JComponent myAnchor; public AlternativeJREPanel() { super(new GridBagLayout()); @@ -79,6 +80,9 @@ public class AlternativeJREPanel extends JPanel implements PanelWithAnchor { } }); enabledChanged(); + + setAnchor(myCbEnabled); + updateUI(); } @@ -112,11 +116,12 @@ public class AlternativeJREPanel extends JPanel implements PanelWithAnchor { @Override public JComponent getAnchor() { - return myCbEnabled.getAnchor(); + return myAnchor; } @Override public void setAnchor(JComponent anchor) { + myAnchor = anchor; myCbEnabled.setAnchor(anchor); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java index e132351f1a8e..acee2ff5e846 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java @@ -99,8 +99,6 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { myEntryTable = new JBTable(myModel); myEntryTable.setShowGrid(false); myEntryTable.setDragEnabled(false); - myEntryTable.setShowHorizontalLines(false); - myEntryTable.setShowVerticalLines(false); myEntryTable.setIntercellSpacing(new Dimension(0, 0)); myEntryTable.setDefaultRenderer(ClasspathTableItem.class, new TableItemRenderer(getStructureConfigurableContext())); @@ -152,7 +150,6 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { } } }; - setFixedColumnWidth(ClasspathTableModel.EXPORT_COLUMN, ClasspathTableModel.EXPORT_COLUMN_NAME); setFixedColumnWidth(ClasspathTableModel.SCOPE_COLUMN, DependencyScope.COMPILE.toString() + " "); // leave space for combobox border @@ -246,13 +243,9 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { } private void setFixedColumnWidth(final int columnIndex, final String textToMeasure) { - final FontMetrics fontMetrics = myEntryTable.getFontMetrics(myEntryTable.getFont()); - final int width = fontMetrics.stringWidth(" " + textToMeasure + " ") + 4; - final TableColumn checkboxColumn = myEntryTable.getTableHeader().getColumnModel().getColumn(columnIndex); - checkboxColumn.setWidth(width); - checkboxColumn.setPreferredWidth(width); - checkboxColumn.setMaxWidth(width); - checkboxColumn.setMinWidth(width); + final TableColumn column = myEntryTable.getTableHeader().getColumnModel().getColumn(columnIndex); + column.setResizable(false); + column.setMaxWidth(column.getPreferredWidth()); } @Override diff --git a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form index 088e84e16f18..9fff54900ceb 100644 --- a/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form +++ b/java/java-impl/src/com/intellij/application/options/CodeStyleGenerationConfigurable.form @@ -13,7 +13,7 @@ - + diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaParameterTypeInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaParameterTypeInspection.java index ecf4e0f7a310..2431d6a0530f 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaParameterTypeInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaParameterTypeInspection.java @@ -72,30 +72,35 @@ public class RedundantLambdaParameterTypeInspection extends BaseJavaLocalInspect if (parameters.length == 0) return; final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, false); if (functionalInterfaceType != null) { - if (!LambdaUtil.isLambdaFullyInferred(expression, functionalInterfaceType)) { - final PsiElement parent = expression.getParent(); - if (parent instanceof PsiExpressionList) { - final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiCallExpression && ((PsiCallExpression)gParent).getTypeArguments().length == 0) { - final PsiMethod method = ((PsiCallExpression)gParent).resolveMethod(); - if (method == null) return; - final int idx = LambdaUtil.getLambdaIdx((PsiExpressionList)parent, expression); - if (idx < 0) return; + final PsiElement parent = expression.getParent(); + if (parent instanceof PsiExpressionList) { + final PsiElement gParent = parent.getParent(); + if (gParent instanceof PsiCallExpression && ((PsiCallExpression)gParent).getTypeArguments().length == 0) { + final PsiMethod method = ((PsiCallExpression)gParent).resolveMethod(); + if (method == null) return; + final int idx = LambdaUtil.getLambdaIdx((PsiExpressionList)parent, expression); + if (idx < 0) return; - final PsiTypeParameter[] typeParameters = method.getTypeParameters(); - final PsiExpression[] arguments = ((PsiExpressionList)parent).getExpressions(); - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(holder.getProject()); - arguments[idx] = javaPsiFacade.getElementFactory().createExpressionFromText("null", expression); - final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper() - .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, PsiSubstitutor.EMPTY, - gParent, DefaultParameterTypeInferencePolicy.INSTANCE); - - for (PsiTypeParameter parameter : typeParameters) { - final PsiType psiType = substitutor.substitute(parameter); - if (psiType == null || LambdaUtil.dependsOnTypeParams(psiType, expression, parameter)) return; + final PsiTypeParameter[] typeParameters = method.getTypeParameters(); + final PsiExpression[] arguments = ((PsiExpressionList)parent).getExpressions(); + final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(holder.getProject()); + arguments[idx] = javaPsiFacade.getElementFactory().createExpressionFromText("(" + StringUtil.join(expression.getParameterList().getParameters(), new Function() { + @Override + public String fun(PsiParameter parameter) { + return parameter.getName(); } + }, ", ") + ") -> {}", expression); + final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper() + .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, PsiSubstitutor.EMPTY, + gParent, DefaultParameterTypeInferencePolicy.INSTANCE); + + for (PsiTypeParameter parameter : typeParameters) { + final PsiType psiType = substitutor.substitute(parameter); + if (psiType == null || LambdaUtil.dependsOnTypeParams(psiType, expression, parameter)) return; } } + } else if (!LambdaUtil.isLambdaFullyInferred(expression, functionalInterfaceType)) { + return; } holder.registerProblem(expression.getParameterList(), "Redundant parameter type declarations", ProblemHighlightType.LIKE_UNUSED_SYMBOL, new RemoveTypeDeclarationsFix()); diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java index b763cb939894..43a95af1c708 100644 --- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/ParameterCanBeLocalInspection.java @@ -65,7 +65,7 @@ public class ParameterCanBeLocalInspection extends BaseJavaLocalInspectionTool { final List result = new ArrayList(); for (PsiParameter parameter : getWriteBeforeRead(parameters, body)) { final PsiIdentifier identifier = parameter.getNameIdentifier(); - if (identifier != null) { + if (identifier != null && identifier.isPhysical()) { result.add(createProblem(manager, identifier, isOnTheFly)); } } diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java index 3094ba6fd86c..0f97ae6d9949 100644 --- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java +++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesDialog.java @@ -17,37 +17,31 @@ package com.intellij.find.findUsages; import com.intellij.find.FindBundle; import com.intellij.find.FindSettings; -import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; -import com.intellij.psi.search.LocalSearchScope; -import com.intellij.psi.search.PsiSearchHelper; import com.intellij.psi.util.MethodSignatureUtil; -import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.StateRestoringCheckBox; -import com.intellij.usageView.UsageViewUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; -public abstract class JavaFindUsagesDialog extends AbstractFindUsagesDialog { - protected final PsiElement myPsiElement; +public abstract class JavaFindUsagesDialog extends CommonFindUsagesDialog { private StateRestoringCheckBox myCbIncludeOverloadedMethods; private boolean myIncludeOverloadedMethodsAvailable = false; - protected JavaFindUsagesDialog(PsiElement element, Project project, FindUsagesOptions findUsagesOptions, boolean toShowInNewTab, boolean mustOpenInNewTab, + protected JavaFindUsagesDialog(@NotNull PsiElement element, + @NotNull Project project, + @NotNull FindUsagesOptions findUsagesOptions, + boolean toShowInNewTab, + boolean mustOpenInNewTab, boolean isSingleFile, FindUsagesHandler handler) { - super(project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, isTextSearch(element, isSingleFile, handler), !isSingleFile && !element.getManager().isInProject(element)); - myPsiElement = element; + super(element, project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler); myIncludeOverloadedMethodsAvailable = element instanceof PsiMethod && MethodSignatureUtil.hasOverloads((PsiMethod)element); init(); } - private static boolean isTextSearch(PsiElement element, boolean isSingleFile, FindUsagesHandler handler) { - return FindUsagesUtil.isSearchForTextOccurrencesAvailable(element, isSingleFile, handler); - } public void calcFindUsagesOptions(T options) { if (options instanceof JavaMethodFindUsagesOptions) { @@ -85,28 +79,10 @@ public abstract class JavaFindUsagesDialog exte } } - @Override - protected boolean isInFileOnly() { - return super.isInFileOnly() || - myPsiElement != null && PsiSearchHelper.SERVICE.getInstance(myPsiElement.getProject()).getUseScope(myPsiElement)instanceof LocalSearchScope; - } - - @Override - public void configureLabelComponent(final SimpleColoredComponent coloredComponent) { - coloredComponent.append(StringUtil.capitalize(UsageViewUtil.getType(myPsiElement))); - coloredComponent.append(" "); - coloredComponent.append(UsageViewUtil.getDescriptiveName(myPsiElement)); - } - protected final PsiElement getPsiElement() { return myPsiElement; } - @Override - protected void doHelpAction() { - HelpManager.getInstance().invokeHelp(FindUsagesManager.getHelpID(myPsiElement)); - } - protected T getFindUsagesOptions() { return (T)myFindUsagesOptions; } diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java index 3059580b3f2a..b316b2b2c3c1 100644 --- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java +++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java @@ -66,18 +66,17 @@ import java.util.*; * @author peter */ public class JavaFindUsagesHandler extends FindUsagesHandler{ - private static final Logger LOG = Logger.getInstance("#com.intellij.find.findUsages.DefaultFindUsagesHandler"); + private static final Logger LOG = Logger.getInstance("#com.intellij.find.findUsages.JavaFindUsagesHandler"); public static final String ACTION_STRING = FindBundle.message("find.super.method.warning.action.verb"); private final PsiElement[] myElementsToSearch; private final JavaFindUsagesHandlerFactory myFactory; - public JavaFindUsagesHandler(@NotNull PsiElement psiElement, JavaFindUsagesHandlerFactory factory) { + public JavaFindUsagesHandler(@NotNull PsiElement psiElement, @NotNull JavaFindUsagesHandlerFactory factory) { this(psiElement, PsiElement.EMPTY_ARRAY, factory); } - - public JavaFindUsagesHandler(@NotNull PsiElement psiElement, @NotNull PsiElement[] elementsToSearch, JavaFindUsagesHandlerFactory factory) { + public JavaFindUsagesHandler(@NotNull PsiElement psiElement, @NotNull PsiElement[] elementsToSearch, @NotNull JavaFindUsagesHandlerFactory factory) { super(psiElement); myElementsToSearch = elementsToSearch; myFactory = factory; @@ -714,14 +713,14 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{ @Override - protected boolean isSearchForTextOccurencesAvailable(PsiElement psiElement, boolean isSingleFile) { + protected boolean isSearchForTextOccurencesAvailable(@NotNull PsiElement psiElement, boolean isSingleFile) { if (isSingleFile) return false; return new JavaNonCodeSearchElementDescriptionProvider().getElementDescription(psiElement, NonCodeSearchDescriptionLocation.NON_JAVA) != null; } @Override - public Collection findReferencesToHighlight(final PsiElement target, final SearchScope searchScope) { + public Collection findReferencesToHighlight(@NotNull final PsiElement target, final SearchScope searchScope) { if (target instanceof PsiMethod) { final PsiMethod[] superMethods = ((PsiMethod)target).findDeepestSuperMethods(); if (superMethods.length == 0) { diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java index b3eddb8ab732..f4b9a342257e 100644 --- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java +++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java @@ -133,7 +133,7 @@ public class JavaRearranger implements Rearranger, @NotNull JavaElementArrangementEntry target) { if (previous == null) { - return 0; + return -1; } CommonCodeStyleSettings commonSettings = settings.getCommonSettings(JavaLanguage.INSTANCE); @@ -152,7 +152,7 @@ public class JavaRearranger implements Rearranger, else { return commonSettings.BLANK_LINES_AROUND_METHOD; } - default: return 0; + default: return commonSettings.BLANK_LINES_AROUND_CLASS; } } diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index d177c88dd1eb..74302d038d6f 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -114,7 +114,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo AlignmentInColumnsHelper alignmentInColumnsHelper) { super(node, wrap, createBlockAlignment(alignmentStrategy, node)); mySettings = settings; - myIndentSettings = settings.getRootSettings().getIndentOptions(StdFileTypes.JAVA); + myIndentSettings = settings.getIndentOptions(); myIndent = indent; myWrapManager = wrapManager; myAlignmentStrategy = alignmentStrategy; diff --git a/java/java-impl/src/com/intellij/refactoring/util/JavaNonCodeSearchElementDescriptionProvider.java b/java/java-impl/src/com/intellij/refactoring/util/JavaNonCodeSearchElementDescriptionProvider.java index 98550659d4fe..9c4d816cae6e 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/JavaNonCodeSearchElementDescriptionProvider.java +++ b/java/java-impl/src/com/intellij/refactoring/util/JavaNonCodeSearchElementDescriptionProvider.java @@ -16,23 +16,23 @@ package com.intellij.refactoring.util; import com.intellij.psi.*; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; /** * @author yole */ public class JavaNonCodeSearchElementDescriptionProvider implements ElementDescriptionProvider { + @Override public String getElementDescription(@NotNull final PsiElement element, @NotNull final ElementDescriptionLocation location) { if (!(location instanceof NonCodeSearchDescriptionLocation)) return null; NonCodeSearchDescriptionLocation ncdLocation = (NonCodeSearchDescriptionLocation) location; if (element instanceof PsiPackage) { return ncdLocation.isNonJava() ? ((PsiPackage)element).getQualifiedName() : ((PsiPackage)element).getName(); } - else if (element instanceof PsiClass) { + if (element instanceof PsiClass) { return ncdLocation.isNonJava() ? ((PsiClass)element).getQualifiedName() : ((PsiClass)element).getName(); } - else if (element instanceof PsiMember) { + if (element instanceof PsiMember) { PsiMember member = (PsiMember)element; String name = member.getName(); if (name == null) return null; diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index a6ad3c5ee309..98716b199593 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -76,6 +76,7 @@ public class LambdaUtil { public static boolean isLambdaFullyInferred(PsiLambdaExpression expression, PsiType functionalInterfaceType) { if (expression.getParameterList().getParametersCount() > 0 || getFunctionalInterfaceReturnType(functionalInterfaceType) != PsiType.VOID) { //todo check that void lambdas without params check + if (functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()) return false; return !dependsOnTypeParams(functionalInterfaceType, expression); } return true; @@ -144,8 +145,8 @@ public class LambdaUtil { return false; } - if (!lambdaFormalType - .isAssignableFrom(GenericsUtil.eliminateWildcards(resolveResult.getSubstitutor().substitute(methodSignature.getSubstitutor().substitute(methodParameterType))))) { + if (!TypeConversionUtil.erasure(lambdaFormalType) + .isAssignableFrom(TypeConversionUtil.erasure(GenericsUtil.eliminateWildcards(resolveResult.getSubstitutor().substitute(methodSignature.getSubstitutor().substitute(methodParameterType)))))) { return false; } } @@ -216,12 +217,12 @@ public class LambdaUtil { private static List findFunctionCandidates(PsiClass psiClass) { if (psiClass.isInterface()) { final List methods = new ArrayList(); - final PsiMethod[] psiClassMethods = psiClass.getAllMethods(); - for (PsiMethod psiMethod : psiClassMethods) { + final Collection visibleSignatures = psiClass.getVisibleSignatures(); + for (HierarchicalMethodSignature signature : visibleSignatures) { + final PsiMethod psiMethod = signature.getMethod(); if (!psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue; - final PsiClass methodContainingClass = psiMethod.getContainingClass(); - if (!overridesPublicObjectMethod(psiMethod)) { - methods.add(getMethodSignature(psiMethod, psiClass, methodContainingClass)); + if (!overridesPublicObjectMethod(psiMethod) && !PsiUtil.isExtensionMethod(psiMethod)) { + methods.add(signature); } } @@ -289,7 +290,7 @@ public class LambdaUtil { final PsiLambdaExpression lambdaExpression, final PsiExpression expression) { final PsiParameter[] lambdaParams = lambdaExpression.getParameterList().getParameters(); - LOG.assertTrue(lambdaParams.length == methodParameters.length, "lambda params: " + lambdaExpression.getParameterList().getText() + "; method params: " + Arrays.toString(methodParameters)); + if (lambdaParams.length != methodParameters.length) return false; final boolean [] independent = new boolean[]{true}; expression.accept(new JavaRecursiveElementWalkingVisitor() { @Override @@ -389,7 +390,7 @@ public class LambdaUtil { if (type == null) { type = getFunctionalInterfaceType(lambdaExpression, false); } - final PsiClassType.ClassResolveResult resolveResult = type instanceof PsiClassType ? ((PsiClassType)type).resolveGenerics() : null; + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type); if (resolveResult != null) { final PsiMethod method = getFunctionalInterfaceMethod(type); if (method != null) { @@ -433,6 +434,9 @@ public class LambdaUtil { final PsiElement gParent = parent.getParent(); if (gParent instanceof PsiCallExpression) { myMethod = ((PsiCallExpression)gParent).resolveMethod(); + if (myMethod != null && PsiTreeUtil.isAncestor(myMethod, expression, false)) { + myMethod = null; + } } } } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiType.java b/java/java-psi-api/src/com/intellij/psi/PsiType.java index 2c3af2dd9499..5ed21bd5fdd0 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiType.java @@ -174,7 +174,6 @@ public abstract class PsiType implements PsiAnnotationOwner { * @param visitor the visitor to accept the type. * @return the value returned by the visitor. */ - @Nullable public abstract A accept(@NotNull PsiTypeVisitor visitor); /** diff --git a/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java b/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java index 57c30fa5449a..a9ac4262a9c1 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java @@ -71,6 +71,8 @@ public class PsiTypeVisitor { @Nullable public A visitLambdaExpressionType(PsiLambdaExpressionType lambdaExpressionType) { final PsiLambdaExpression lambdaExpression = lambdaExpressionType.getExpression(); - return visitType(lambdaExpression.getFunctionalInterfaceType()); + final PsiType interfaceType = lambdaExpression.getFunctionalInterfaceType(); + if (interfaceType != null) return interfaceType.accept(this); + return visitType(interfaceType); } } 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 17cb593b58a7..1a73fd6e64bb 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 @@ -15,7 +15,6 @@ */ package com.intellij.psi.impl.source.resolve; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -186,6 +185,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { PsiType upperBound = PsiType.NULL; if (paramTypes.length > 0) { sortLambdaExpressionsLast(paramTypes, argTypes); + boolean rawType = false; + boolean nullPassed = false; for (int j = 0; j < argTypes.length; j++) { PsiType argumentType = argTypes[j]; if (argumentType == null) continue; @@ -193,6 +194,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { PsiType parameterType = paramTypes[j]; if (parameterType == null) break; + rawType |= parameterType instanceof PsiClassType && ((PsiClassType)parameterType).isRaw(); + nullPassed |= argumentType == PsiType.NULL; if (parameterType instanceof PsiEllipsisType) { parameterType = ((PsiEllipsisType)parameterType).getComponentType(); @@ -203,6 +206,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { final Pair currentSubstitution; if (argumentType instanceof PsiLambdaExpressionType) { currentSubstitution = inferSubstitutionFromLambda(typeParameter, (PsiLambdaExpressionType)argumentType, lowerBound); + if (rawType && currentSubstitution == FAILED_INFERENCE || nullPassed && currentSubstitution == null) return new Pair(null, ConstraintType.EQUALS); } else { currentSubstitution = getSubstitutionForTypeParameterConstraint(typeParameter, parameterType, argumentType, true, PsiUtil.getLanguageLevel(typeParameter)); @@ -592,7 +596,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { if (constraintFromFormalParams != null) return constraintFromFormalParams; final PsiParameter[] methodParameters = method.getParameterList().getParameters(); - final PsiSubstitutor subst = resolveResult.getSubstitutor(); + final PsiSubstitutor subst = + TypeConversionUtil.getSuperClassSubstitutor(method.getContainingClass(), resolveResult.getElement(), resolveResult.getSubstitutor()); final boolean methodParamsDependOnTypeParams = methodParamsDependOnTypeParams(lambdaExpression, methodParameters, subst, typeParam); final PsiType returnType = subst.substitute(method.getReturnType()); if (returnType != null && returnType != PsiType.VOID) { @@ -891,8 +896,10 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { return getFailedInferenceConstraint(typeParameter); } final PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); - if (method == null || methodParamsDependOnTypeParams((PsiLambdaExpression)expression, method.getParameterList().getParameters(), - PsiUtil.resolveGenericsClassInType(functionalInterfaceType).getSubstitutor(), typeParameter)) { + + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); + if (method == null || methodParamsDependOnTypeParams((PsiLambdaExpression)expression, method.getParameterList().getParameters(), + TypeConversionUtil.getSuperClassSubstitutor(method.getContainingClass(), resolveResult.getElement(), resolveResult.getSubstitutor()), typeParameter)) { return getFailedInferenceConstraint(typeParameter); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/DefaultMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/DefaultMethod.java new file mode 100644 index 000000000000..2f886ff034bf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/DefaultMethod.java @@ -0,0 +1,17 @@ +class Test { + public static final BinaryOperator rPlus = (x, y) -> x + y; + interface BinaryOperator extends Combiner { + public T operate(T left, T right); + + @Override + T combine(T t1, T t2) default { + return operate(t1, t2); + } + } + + interface Combiner { + V combine(T t, U u); + } +} + + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaOnVarargPlace.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaOnVarargPlace.java new file mode 100644 index 000000000000..614065c91b0d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaOnVarargPlace.java @@ -0,0 +1,21 @@ +class TestData {} +interface TerminalOp extends IntermediateOp {} +interface IntermediateOp { boolean _(L1 l, M1 m);} + +class Test { + protected U exerciseOps(TestData data, TerminalOp terminal, IntermediateOp... ops) { + return exerciseOps(data, terminal, (u, v) -> u.equals(v)); + } +} + +class Test1 { + protected U exerciseOps(TestData data, TerminalOp terminal, IntermediateOp... ops) { + return exerciseOps(data, terminal, (u, v) -> u.equals(v)); + } +} + +class Test2 { + protected U exerciseOps(TestData data, TerminalOp terminal, IntermediateOp... ops) { + return exerciseOps(data, terminal, (u, v) -> u.equals(v)); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java new file mode 100644 index 000000000000..f4dfd65eed29 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/LambdaRawOrNot.java @@ -0,0 +1,36 @@ +import java.util.*; +class TestData {} +interface TerminalOp extends IntermediateOp {} +interface IntermediateOp { boolean _(L1 l, M1 m);} + + +class Test1 { + protected U exerciseOps(TestData data, TerminalOp terminal, IntermediateOp... ops) { + return exerciseOps(data, (u, v) -> u.equals(v), terminal); + } +} + +class Test2 { + protected U exerciseOps(TestData data, TerminalOp terminal, IntermediateOp... ops) { + return exerciseOps(data, (u, v) -> u.equals(v), terminal); + } +} + +class Test3 { + interface I { + void m(Y y); + } + + static void bar(I i, List l){ + bar(x -> {}, l); + bar(x -> {}, null); + bar((I)x -> {}, null); + bar((T x) -> {}, null); + bar(x -> {}, new ArrayList()); + bar(x -> {}, new ArrayList()); + } + + static { + bar(x->{}, new ArrayList()); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeTypeParam.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeTypeParam.java new file mode 100644 index 000000000000..59c5775578c6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeTypeParam.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +// "Remove redundant types" "false" +class Test3 { + interface I { + void m(Y y); + } + + static void bar(I i, List l){ + bar((T x) -> {}, null); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java index 210ceefe15ca..21f944434442 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaHighlightingTest.java @@ -85,7 +85,17 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } - + public void testDefaultMethod() throws Exception { + doTest(); + } + + public void testLambdaOnVarargPlace() throws Exception { + doTest(); + } + + public void testLambdaRawOrNot() throws Exception { + doTest(); + } public void testNoInferenceResult() throws Exception { doTest(); diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy index 3bad9387ba78..b2a73a5b00cd 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerBlankLinesTest.groovy @@ -25,6 +25,7 @@ import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.S public class JavaRearrangerBlankLinesTest extends AbstractJavaRearrangerTest { void testPreserveRelativeBlankLines() { + commonSettings.BLANK_LINES_AROUND_CLASS = 2 commonSettings.BLANK_LINES_AROUND_FIELD = 1 commonSettings.BLANK_LINES_AROUND_METHOD = 2 commonSettings.BLANK_LINES_AROUND_FIELD_IN_INTERFACE = 2 @@ -33,11 +34,11 @@ public class JavaRearrangerBlankLinesTest extends AbstractJavaRearrangerTest { '''\ class Test { private void method1() {} - + public void method2() {} private int i; - + public int j; public static int k; } @@ -62,13 +63,19 @@ interface MyInterface { void test2(); } + + class Test { public static int k; + public int j; + private int i; - + + public void method2() {} + private void method1() {} }''', [rule(INTERFACE), diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeAndModifierTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeAndModifierTest.groovy index 3a8655521b49..2d2fa4e39634 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeAndModifierTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeAndModifierTest.groovy @@ -24,6 +24,9 @@ import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.* class JavaRearrangerByTypeAndModifierTest extends AbstractJavaRearrangerTest { void testComplex() { + commonSettings.BLANK_LINES_AROUND_METHOD = 0 + commonSettings.BLANK_LINES_AROUND_CLASS = 0 + doTest( '''\ class Test { diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeTest.groovy index 21b6ed68dd22..29a24c4f2773 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerByTypeTest.groovy @@ -15,6 +15,8 @@ */ package com.intellij.psi.codeStyle.arrangement +import org.junit.Before + import static com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType.* /** * @author Denis Zhdanov @@ -22,6 +24,13 @@ import static com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType. */ class JavaRearrangerByTypeTest extends AbstractJavaRearrangerTest { + @Before + void setUp() { + super.setUp() + commonSettings.BLANK_LINES_AROUND_METHOD = 0 + commonSettings.BLANK_LINES_AROUND_CLASS = 0 + } + void testFieldsBeforeMethods() { doTest( '''\ diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java index 50d371e89423..a2620e436be3 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterIndentationTest.java @@ -503,4 +503,17 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { "// This is a line comment" ); } + + public void testMultilineComment() { + // IDEA-90860 + String text = + "\n" + + "/*\n" + + " * comment\n" + + " */\n" + + "\n" + + "class Test {\n" + + "}"; + doTextTest(text, text); + } } diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java index 753c9b725a3b..55835ec3d610 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java @@ -70,6 +70,11 @@ abstract class JavaModuleFixtureBuilderImpl extends Mod @Override public JavaModuleFixtureBuilder addLibrary(String libraryName, String... classPath) { final HashMap map = new HashMap(); + for (String path : classPath) { + if (!new File(path).exists()) { + System.out.println(path + " not exists"); + } + } map.put(OrderRootType.CLASSES, classPath); myLibraries.add(new Lib(libraryName, map)); return this; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java index 86837a3ba2bb..3b92f7e26793 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java @@ -34,7 +34,7 @@ public class ModuleBuildTarget extends BuildTarget { if (this == o) { return true; } - if (o == null || getClass() != o.getClass()) { + if (o == null || !(o instanceof ModuleBuildTarget)) { return false; } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java index 9665284256ed..4a37ee044e27 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java @@ -1,7 +1,8 @@ package org.jetbrains.jps.model.module.impl; +import com.intellij.openapi.util.Ref; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.JpsElementChildRole; import org.jetbrains.jps.model.impl.JpsElementChildRoleBase; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleDependency; @@ -14,6 +15,8 @@ public class JpsModuleDependencyImpl extends JpsDependencyElementBase MODULE_REFERENCE_CHILD_ROLE = JpsElementChildRoleBase.create("module reference"); + private volatile Ref myCachedModule = null; + public JpsModuleDependencyImpl(final JpsModuleReference moduleReference) { super(); myContainer.setChild(MODULE_REFERENCE_CHILD_ROLE, moduleReference); @@ -31,7 +34,12 @@ public class JpsModuleDependencyImpl extends JpsDependencyElementBase moduleRef = myCachedModule; + if (moduleRef == null) { + moduleRef = new Ref(getModuleReference().resolve()); + myCachedModule = moduleRef; + } + return moduleRef.get(); } @NotNull diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java index 724f6b93a770..ffbf941bc350 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java @@ -3,6 +3,8 @@ package org.jetbrains.jps.model.serialization; import com.intellij.openapi.diagnostic.Logger; import org.jdom.Element; import org.jetbrains.jps.model.JpsGlobal; +import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer; +import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; import java.io.File; import java.io.IOException; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java index 05cf9f5e46f5..ef9d3608ef77 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelSerializerExtension.java @@ -10,6 +10,10 @@ import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.serialization.artifact.JpsArtifactPropertiesSerializer; import org.jetbrains.jps.model.serialization.artifact.JpsPackagingElementSerializer; import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer; +import org.jetbrains.jps.model.serialization.library.JpsLibraryPropertiesSerializer; +import org.jetbrains.jps.model.serialization.library.JpsLibraryRootTypeSerializer; +import org.jetbrains.jps.model.serialization.library.JpsSdkPropertiesSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModulePropertiesSerializer; import org.jetbrains.jps.service.JpsServiceManager; import java.util.Collections; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index ded12fcb59af..90d25bf45db4 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -12,6 +12,10 @@ import org.jetbrains.jps.model.library.sdk.JpsSdkType; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.serialization.artifact.JpsArtifactSerializer; import org.jetbrains.jps.model.serialization.facet.JpsFacetSerializer; +import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer; +import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModulePropertiesSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; import java.io.File; import java.io.FileFilter; @@ -162,7 +166,8 @@ public class JpsProjectLoader extends JpsLoaderBase { final String typeId = moduleRoot.getAttributeValue("type"); final JpsModulePropertiesSerializer serializer = getModulePropertiesSerializer(typeId); final JpsModule module = createModule(name, moduleRoot, serializer); - JpsModuleSerializer.loadRootModel(module, JDomSerializationUtil.findComponent(moduleRoot, "NewModuleRootManager"), projectSdkType); + JpsModuleRootModelSerializer + .loadRootModel(module, JDomSerializationUtil.findComponent(moduleRoot, "NewModuleRootManager"), projectSdkType); final String moduleDirPath = file.getParent(); JpsFacetSerializer.loadFacets(module, JDomSerializationUtil.findComponent(moduleRoot, "FacetManager"), FileUtil.toSystemIndependentName(moduleDirPath)); diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsArtifactSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsArtifactSerializer.java index 8464e6cd3659..1705f9599485 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsArtifactSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/artifact/JpsArtifactSerializer.java @@ -11,7 +11,7 @@ import org.jetbrains.jps.model.artifact.*; import org.jetbrains.jps.model.artifact.elements.*; import org.jetbrains.jps.model.library.JpsLibraryReference; import org.jetbrains.jps.model.module.JpsModuleReference; -import org.jetbrains.jps.model.serialization.JpsLibraryTableSerializer; +import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; /** diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java index 502fb11dee82..4aa4a3ccf766 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelSerializerExtension.java @@ -12,7 +12,7 @@ import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleReference; -import org.jetbrains.jps.model.serialization.JpsLibraryRootTypeSerializer; +import org.jetbrains.jps.model.serialization.library.JpsLibraryRootTypeSerializer; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; import org.jetbrains.jps.model.serialization.JpsProjectExtensionSerializer; import org.jetbrains.jps.model.serialization.artifact.JpsPackagingElementSerializer; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryPropertiesSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryPropertiesSerializer.java similarity index 81% rename from jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryPropertiesSerializer.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryPropertiesSerializer.java index 10c5a81b1434..d23ad8d9adea 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryPropertiesSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryPropertiesSerializer.java @@ -1,9 +1,10 @@ -package org.jetbrains.jps.model.serialization; +package org.jetbrains.jps.model.serialization.library; import org.jdom.Element; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.library.JpsLibraryType; +import org.jetbrains.jps.model.serialization.JpsElementPropertiesSerializer; /** * @author nik diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryRootTypeSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryRootTypeSerializer.java similarity index 93% rename from jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryRootTypeSerializer.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryRootTypeSerializer.java index 04de078d4ded..dff4ec0ad728 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryRootTypeSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryRootTypeSerializer.java @@ -1,4 +1,4 @@ -package org.jetbrains.jps.model.serialization; +package org.jetbrains.jps.model.serialization.library; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.library.JpsOrderRootType; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryTableSerializer.java similarity index 98% rename from jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableSerializer.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryTableSerializer.java index d0fe23221e30..50f99e6864ff 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsLibraryTableSerializer.java @@ -1,4 +1,4 @@ -package org.jetbrains.jps.model.serialization; +package org.jetbrains.jps.model.serialization.library; import com.intellij.openapi.util.JDOMUtil; import com.intellij.util.containers.MultiMap; @@ -10,6 +10,7 @@ import org.jetbrains.jps.model.java.JpsJavaLibraryType; import org.jetbrains.jps.model.library.*; import org.jetbrains.jps.model.library.sdk.JpsSdkType; import org.jetbrains.jps.model.module.JpsModuleReference; +import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; import java.util.*; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsSdkPropertiesSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsSdkPropertiesSerializer.java similarity index 83% rename from jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsSdkPropertiesSerializer.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsSdkPropertiesSerializer.java index f3a49ecb95ce..b4d4f25ad271 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsSdkPropertiesSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsSdkPropertiesSerializer.java @@ -1,10 +1,11 @@ -package org.jetbrains.jps.model.serialization; +package org.jetbrains.jps.model.serialization.library; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.library.sdk.JpsSdkType; +import org.jetbrains.jps.model.serialization.JpsElementPropertiesSerializer; /** * @author nik diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsSdkTableSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsSdkTableSerializer.java similarity index 98% rename from jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsSdkTableSerializer.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsSdkTableSerializer.java index 1a3b0ef4de15..8541f904377b 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsSdkTableSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/library/JpsSdkTableSerializer.java @@ -1,4 +1,4 @@ -package org.jetbrains.jps.model.serialization; +package org.jetbrains.jps.model.serialization.library; import com.intellij.openapi.util.JDOMUtil; import org.jdom.Element; @@ -14,6 +14,7 @@ import org.jetbrains.jps.model.library.sdk.JpsSdk; import org.jetbrains.jps.model.library.sdk.JpsSdkType; import org.jetbrains.jps.model.library.sdk.JpsSdkReference; import org.jetbrains.jps.model.module.JpsSdkReferencesTable; +import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; import java.util.ArrayList; import java.util.Arrays; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModulePropertiesSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModulePropertiesSerializer.java similarity index 86% rename from jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModulePropertiesSerializer.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModulePropertiesSerializer.java index 0b7ce824a5fc..a862ad1f8c30 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModulePropertiesSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModulePropertiesSerializer.java @@ -1,10 +1,11 @@ -package org.jetbrains.jps.model.serialization; +package org.jetbrains.jps.model.serialization.module; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.module.JpsModuleType; +import org.jetbrains.jps.model.serialization.JpsElementPropertiesSerializer; /** * @author nik diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java similarity index 97% rename from jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleSerializer.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java index 0aa7dbb5109b..cba1b3a103da 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java @@ -1,4 +1,4 @@ -package org.jetbrains.jps.model.serialization; +package org.jetbrains.jps.model.serialization.module; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -15,6 +15,9 @@ import org.jetbrains.jps.model.library.JpsLibraryReference; import org.jetbrains.jps.model.library.sdk.JpsSdkType; import org.jetbrains.jps.model.library.sdk.JpsSdkReference; import org.jetbrains.jps.model.module.*; +import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; +import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer; +import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; import java.util.ArrayList; import java.util.Collections; @@ -25,7 +28,7 @@ import static com.intellij.openapi.util.JDOMUtil.getChildren; /** * @author nik */ -public class JpsModuleSerializer { +public class JpsModuleRootModelSerializer { public static final String URL_ATTRIBUTE = "url"; public static final String CONTENT_TAG = "content"; public static final String SOURCE_FOLDER_TAG = "sourceFolder"; diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java index 440cc5c8bc0e..10e0fedc0f85 100644 --- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java @@ -5,6 +5,7 @@ import com.intellij.testFramework.PlatformTestUtil; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.serialization.library.JpsSdkTableSerializer; import java.io.File; import java.io.IOException; diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java index 85bcc0cffe2c..a62a6550070c 100644 --- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java @@ -9,6 +9,8 @@ import org.jetbrains.jps.model.java.JpsJavaSdkType; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.sdk.JpsSdkReference; import org.jetbrains.jps.model.module.*; +import org.jetbrains.jps.model.serialization.library.JpsLibraryTableSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; import java.io.File; import java.io.IOException; @@ -91,7 +93,7 @@ public class JpsProjectSerializationTest extends JpsSerializationTestCase { private static void doTestSaveModule(JpsModule module, final String moduleFilePath) { try { Element actual = JDomSerializationUtil.createComponentElement("NewModuleRootManager"); - JpsModuleSerializer.saveRootModel(module, actual); + JpsModuleRootModelSerializer.saveRootModel(module, actual); File imlFile = getFileInSampleProject(moduleFilePath); Element rootElement = loadModuleRootTag(imlFile); Element expected = JDomSerializationUtil.findComponent(rootElement, "NewModuleRootManager"); diff --git a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java index 719460729007..06b104b76155 100644 --- a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java +++ b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java @@ -28,6 +28,7 @@ import com.intellij.psi.stubs.StubBase; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.templateLanguages.OuterLanguageElement; import com.intellij.util.ArrayUtil; +import com.intellij.util.PairProcessor; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -938,6 +939,24 @@ public class PsiTreeUtil { return true; } + public static boolean treeWalkUp(@NotNull final PsiElement entrance, + @Nullable final PsiElement maxScope, + PairProcessor eachScopeAndLastParent) { + PsiElement prevParent = null; + PsiElement scope = entrance; + + while (scope != null) { + if (!eachScopeAndLastParent.process(scope, prevParent)) return false; + + if (scope == maxScope) break; + prevParent = scope; + scope = prevParent.getContext(); + } + + return true; + + } + @NotNull public static PsiElement findPrevParent(@NotNull PsiElement ancestor, @NotNull PsiElement descendant) { PsiElement cur = descendant; diff --git a/platform/core-impl/src/com/intellij/lang/LanguageTokenSeparatorGenerators.java b/platform/core-impl/src/com/intellij/lang/LanguageTokenSeparatorGenerators.java index 843924443d7d..9ca24d61e568 100644 --- a/platform/core-impl/src/com/intellij/lang/LanguageTokenSeparatorGenerators.java +++ b/platform/core-impl/src/com/intellij/lang/LanguageTokenSeparatorGenerators.java @@ -31,6 +31,10 @@ public class LanguageTokenSeparatorGenerators extends LanguageExtension { * @param parent target entry's parent (if available) * @param previous previous entry (if available) * @param target target entry which blank lines number the caller is interested in - * @return number of blank lines to insert before the target entry + * @return number of blank lines to insert before the target entry; + * negative as an indication that no blank lines adjustment is necessary */ int getBlankLines(@NotNull CodeStyleSettings settings, @Nullable E parent, @Nullable E previous, @NotNull E target); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/inspection-black-list.txt b/platform/lang-impl/src/com/intellij/codeInspection/inspection-black-list.txt index 9527d222bb38..61a3085d889d 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/inspection-black-list.txt +++ b/platform/lang-impl/src/com/intellij/codeInspection/inspection-black-list.txt @@ -130,7 +130,6 @@ com.siyeh.ig.errorhandling.TooBroadThrowsInspection com.siyeh.ig.errorhandling.UnusedCatchParameterInspection com.siyeh.ig.finalization.FinalizeCallsSuperFinalizeInspection com.siyeh.ig.finalization.FinalizeInspection -com.siyeh.ig.imports.StaticImportInspection com.siyeh.ig.inheritance.InterfaceNeverImplementedInspection com.siyeh.ig.inheritance.NonProtectedConstructorInAbstractClassInspection com.siyeh.ig.inheritance.RefusedBequestInspection diff --git a/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java b/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java index f057643100e7..6d76ab5db4ce 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/CommonProgramParametersPanel.java @@ -51,7 +51,7 @@ public class CommonProgramParametersPanel extends JPanel implements PanelWithAnc private LabeledComponent myWorkingDirectoryComponent; private TextFieldWithBrowseButton myWorkingDirectoryField; private EnvironmentVariablesComponent myEnvVariablesComponent; - protected JComponent anchor; + protected JComponent myAnchor; private Module myModuleContext = null; private boolean myHaveModuleContext = false; @@ -160,11 +160,11 @@ public class CommonProgramParametersPanel extends JPanel implements PanelWithAnc } public JComponent getAnchor() { - return anchor; + return myAnchor; } public void setAnchor(JComponent anchor) { - this.anchor = anchor; + this.myAnchor = anchor; myProgramParametersComponent.setAnchor(anchor); myWorkingDirectoryComponent.setAnchor(anchor); myEnvVariablesComponent.setAnchor(anchor); diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java index fcbc53849259..252351181385 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java +++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java @@ -280,7 +280,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction { continueSearch = false; } pingEDT.ping(); - //rebuildPopup(usageView, usages, table, popup, presentation, popupPosition); return continueSearch; } } @@ -579,14 +578,14 @@ public class ShowUsagesAction extends AnAction implements PopupAction { }.registerCustomShortcutSet(new CustomShortcutSet(shortcut.getFirstKeyStroke()), table); } - InplaceButton button = createSettingsButton(handler, popupPosition, editor, maxUsages, new Runnable() { + InplaceButton settingsButton = createSettingsButton(handler, popupPosition, editor, maxUsages, new Runnable() { @Override public void run() { popup[0].cancel(); } }); - ActiveComponent iconComp = new ActiveComponent() { + ActiveComponent spinningProgress = new ActiveComponent() { @Override public void setActive(boolean active) { } @@ -596,7 +595,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { return processIcon; } }; - builder.setCommandButton(new CompositeActiveComponent(iconComp, button)); + builder.setCommandButton(new CompositeActiveComponent(spinningProgress, settingsButton)); DefaultActionGroup toolbar = new DefaultActionGroup(); usageView.addFilteringActions(toolbar); @@ -631,7 +630,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { myWidth = (int)(toolBar.getPreferredSize().getWidth() + new JLabel(getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1)).getPreferredSize().getWidth() - + button.getPreferredSize().getWidth()); + + settingsButton.getPreferredSize().getWidth()); myWidth = -1; for (AnAction action : toolbar.getChildren(null)) { action.unregisterCustomShortcutSet(usageView.getComponent()); diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java index 0b4e8a8b4778..7fb70e99858e 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/AbstractFindUsagesDialog.java @@ -117,7 +117,7 @@ public abstract class AbstractFindUsagesDialog extends DialogWrapper { return panel; } - public abstract void configureLabelComponent(final SimpleColoredComponent coloredComponent); + public abstract void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent); @Override protected JComponent createCenterPanel() { diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java index b6ae1a672285..9ff8f5ca02ab 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java @@ -25,6 +25,7 @@ import com.intellij.psi.search.PsiSearchHelper; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; import com.intellij.usageView.UsageViewUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -34,13 +35,15 @@ import javax.swing.*; public class CommonFindUsagesDialog extends AbstractFindUsagesDialog { protected final PsiElement myPsiElement; - public CommonFindUsagesDialog(PsiElement element, - Project project, - FindUsagesOptions findUsagesOptions, + public CommonFindUsagesDialog(@NotNull PsiElement element, + @NotNull Project project, + @NotNull FindUsagesOptions findUsagesOptions, boolean toShowInNewTab, boolean mustOpenInNewTab, - boolean isSingleFile, FindUsagesHandler handler) { - super(project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, isTextSearch(element, isSingleFile, handler), !isSingleFile && !element.getManager().isInProject(element)); + boolean isSingleFile, + FindUsagesHandler handler) { + super(project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, isTextSearch(element, isSingleFile, handler), + !isSingleFile && !element.getManager().isInProject(element)); myPsiElement = element; init(); } @@ -52,7 +55,7 @@ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog { @Override protected boolean isInFileOnly() { return super.isInFileOnly() || - myPsiElement != null && PsiSearchHelper.SERVICE.getInstance(myPsiElement.getProject()).getUseScope(myPsiElement)instanceof LocalSearchScope; + PsiSearchHelper.SERVICE.getInstance(myPsiElement.getProject()).getUseScope(myPsiElement) instanceof LocalSearchScope; } @Override @@ -61,7 +64,7 @@ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog { } @Override - public void configureLabelComponent(final SimpleColoredComponent coloredComponent) { + public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) { coloredComponent.append(StringUtil.capitalize(UsageViewUtil.getType(myPsiElement))); coloredComponent.append(" "); coloredComponent.append(UsageViewUtil.getDescriptiveName(myPsiElement), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java index 8f4874c8c9d7..553339fb593a 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java @@ -193,11 +193,11 @@ public abstract class FindUsagesHandler { return Collections.singleton(element.getText()); } - protected boolean isSearchForTextOccurencesAvailable(PsiElement psiElement, boolean isSingleFile) { + protected boolean isSearchForTextOccurencesAvailable(@NotNull PsiElement psiElement, boolean isSingleFile) { return false; } - public Collection findReferencesToHighlight(PsiElement target, SearchScope searchScope) { + public Collection findReferencesToHighlight(@NotNull PsiElement target, SearchScope searchScope) { return ReferencesSearch.search(target, searchScope, false).findAll(); } } diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java index 41235fc09aca..438ec6351f57 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java @@ -253,7 +253,7 @@ public class FindUsagesManager implements JDOMExternalizable { if (handler == null) return; boolean singleFile = scopeFile != null; - final AbstractFindUsagesDialog dialog = handler.getFindUsagesDialog(singleFile, shouldOpenInNewTab(), mustOpenInNewTab()); + AbstractFindUsagesDialog dialog = handler.getFindUsagesDialog(singleFile, shouldOpenInNewTab(), mustOpenInNewTab()); if (showDialog) { dialog.show(); if (!dialog.isOK()) return; diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java index c5b0afdc3675..14b17a0746a3 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2011 JetBrains s.r.o. * @@ -26,6 +25,7 @@ import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.SearchRequestCollector; import com.intellij.psi.search.SearchScope; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -80,13 +80,13 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable { } public int hashCode() { - int result; - result = (searchScope != null ? searchScope.hashCode() : 0); + int result = searchScope == null ? 0 : searchScope.hashCode(); result = 31 * result + (isSearchForTextOccurrences ? 1 : 0); result = 31 * result + (isUsages ? 1 : 0); return result; } + @NonNls @Override public String toString() { return getClass().getSimpleName() + "{" + diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java index c7ce574ebda3..02c98d83a82c 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesUtil.java @@ -1,4 +1,3 @@ - /* * Copyright 2000-2009 JetBrains s.r.o. * @@ -18,12 +17,13 @@ package com.intellij.find.findUsages; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; public class FindUsagesUtil { private FindUsagesUtil() { } - public static boolean isSearchForTextOccurrencesAvailable(PsiElement element, boolean isSingleFile, FindUsagesHandler handler) { + public static boolean isSearchForTextOccurrencesAvailable(@NotNull PsiElement element, boolean isSingleFile, FindUsagesHandler handler) { return !isSingleFile && handler != null && handler.isSearchForTextOccurencesAvailable(element, isSingleFile); } } diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java index 3a0e76644bd4..ff60d4497a8a 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java @@ -311,7 +311,7 @@ public class FindSettingsImpl extends FindSettings implements PersistentStateCom @Override public void addDirectory(String s) { - if (s == null || s.length() == 0){ + if (s == null || s.isEmpty()){ return; } addStringToList(s, RECENT_DIR_STRINGS, MAX_RECENT_SIZE); @@ -345,7 +345,7 @@ public class FindSettingsImpl extends FindSettings implements PersistentStateCom @Override public void setFileMask(String _fileMask) { FILE_MASK = _fileMask; - if (_fileMask != null && _fileMask.length() > 0) { + if (_fileMask != null && !_fileMask.isEmpty()) { addStringToList(_fileMask, RECENT_FILE_MASKS, MAX_RECENT_SIZE); } } diff --git a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java index 25c05915747e..98168c473599 100644 --- a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java +++ b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java @@ -150,13 +150,13 @@ public class ReplaceInProjectManager { manager.searchAndShowUsages(new UsageTarget[]{new FindInProjectUtil.StringUsageTarget(findModelCopy.getStringToFind())}, usageSearcherFactory, processPresentation, presentation, new UsageViewManager.UsageViewStateListener() { @Override - public void usageViewCreated(UsageView usageView) { + public void usageViewCreated(@NotNull UsageView usageView) { context[0] = new ReplaceContext(usageView, findModelCopy); addReplaceActions(context[0]); } @Override - public void findingUsagesFinished(final UsageView usageView) { + public void findingUsagesFinished(@NotNull final UsageView usageView) { if (context[0] != null && findManager.getFindInProjectModel().isPromptOnReplace()) { SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index d31f878ff814..8afa9699de65 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -393,12 +393,14 @@ class FormatProcessor { if (block.isLeaf() && whiteSpace.containsLineFeeds() && block.containsLineFeeds()) { final TextRange currentBlockRange = shiftRange(block.getTextRange(), shift); - IndentInside lastLineIndent = block.getLastLineIndent(); + IndentInside oldBlockIndent = whiteSpace.getInitialLastLineIndent(); IndentInside whiteSpaceIndent = IndentInside.createIndentOn(IndentInside.getLastLine(newWhiteSpace)); - final int shiftInside = calcShift(lastLineIndent, whiteSpaceIndent, options); + final int shiftInside = calcShift(oldBlockIndent, whiteSpaceIndent, options); - final TextRange newBlockRange = model.shiftIndentInsideRange(currentBlockRange, shiftInside); - shift += newBlockRange.getLength() - block.getLength(); + if (shiftInside != 0) { + final TextRange newBlockRange = model.shiftIndentInsideRange(currentBlockRange, shiftInside); + shift += newBlockRange.getLength() - block.getLength(); + } } return shift; } diff --git a/platform/lang-impl/src/com/intellij/formatting/IndentInside.java b/platform/lang-impl/src/com/intellij/formatting/IndentInside.java index b8c4a0879586..26ff7e0f07a1 100644 --- a/platform/lang-impl/src/com/intellij/formatting/IndentInside.java +++ b/platform/lang-impl/src/com/intellij/formatting/IndentInside.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,22 @@ package com.intellij.formatting; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.util.text.CharArrayUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; -import java.io.LineNumberReader; -import java.io.StringReader; - class IndentInside { public int whiteSpaces = 0; public int tabs = 0; - private static final Logger LOG = Logger.getInstance("#com.intellij.formatting.FormatProcessor"); + + public IndentInside() { + } + + public IndentInside(int whiteSpaces, int tabs) { + this.whiteSpaces = whiteSpaces; + this.tabs = tabs; + } public boolean equals(final Object o) { if (this == o) return true; @@ -55,13 +59,14 @@ class IndentInside { return whiteSpaces + tabs * options.TAB_SIZE; } - static IndentInside getLastLineIndent(final String text) { - String lastLine = getLastLine(text); - if (lastLine == null) return new IndentInside(); + @NotNull + static IndentInside getLastLineIndent(@NotNull final CharSequence text) { + CharSequence lastLine = getLastLine(text); return createIndentOn(lastLine); } - static IndentInside createIndentOn(@Nullable final String lastLine) { + @NotNull + static IndentInside createIndentOn(@Nullable final CharSequence lastLine) { final IndentInside result = new IndentInside(); if (lastLine == null) { return result; @@ -73,19 +78,17 @@ class IndentInside { return result; } - @Nullable static String getLastLine(final String text) { - if (text.endsWith("\n")) return ""; - final LineNumberReader lineNumberReader = new LineNumberReader(new StringReader(text)); - String line; - String result = null; - try { - while ((line = lineNumberReader.readLine()) != null) { - result = line; - } + @NotNull + static CharSequence getLastLine(@NotNull final CharSequence text) { + int i = CharArrayUtil.shiftBackwardUntil(text, text.length() - 1, "\n"); + if (i < 0) { + return text; } - catch (IOException e) { - LOG.assertTrue(false); + else if (i >= text.length() - 1) { + return ""; + } + else { + return text.subSequence(i + 1, text.length()); } - return result; } } diff --git a/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java b/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java index 29776ef7d4a0..4a4e6b1d5891 100644 --- a/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java +++ b/platform/lang-impl/src/com/intellij/formatting/LeafBlockWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ class LeafBlockWrapper extends AbstractBlockWrapper { private LeafBlockWrapper myPreviousBlock; private LeafBlockWrapper myNextBlock; private SpacingImpl mySpaceProperty; - private IndentInside myLastLineIndent; private String myDebugInfo; /** @@ -97,12 +96,6 @@ class LeafBlockWrapper extends AbstractBlockWrapper { final boolean isLeaf = block.isLeaf(); flagsValue |= isLeaf ? LEAF : 0; - if (isLeaf && containsLineFeeds) { - myLastLineIndent = IndentInside.getLastLineIndent(model.getText(textRange).toString()); - } else { - myLastLineIndent = null; - } - myFlags = flagsValue; } @@ -157,7 +150,6 @@ class LeafBlockWrapper extends AbstractBlockWrapper { myPreviousBlock = null; myNextBlock = null; mySpaceProperty = null; - myLastLineIndent = null; } /** @@ -218,10 +210,6 @@ class LeafBlockWrapper extends AbstractBlockWrapper { return (myFlags & LEAF) != 0; } - public IndentInside getLastLineIndent() { - return myLastLineIndent; - } - public boolean contains(final int offset) { return myStart < offset && myEnd > offset; } diff --git a/platform/lang-impl/src/com/intellij/formatting/WhiteSpace.java b/platform/lang-impl/src/com/intellij/formatting/WhiteSpace.java index f00777b7829e..5b6abdeb1443 100644 --- a/platform/lang-impl/src/com/intellij/formatting/WhiteSpace.java +++ b/platform/lang-impl/src/com/intellij/formatting/WhiteSpace.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.formatter.FormattingDocumentModelImpl; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -48,9 +49,11 @@ class WhiteSpace { private final int myStart; private int myEnd; - + private int mySpaces; private int myIndentSpaces; + private int myInitialLastLinesSpaces; + private int myInitialLastLinesTabs; private CharSequence myInitial; private int myFlags; @@ -130,6 +133,9 @@ class WhiteSpace { } else { refreshStateOnEndOffsetDecrease(oldText, newEndOffset, oldEndOffset, options.TAB_SIZE); } + IndentInside indent = IndentInside.getLastLineIndent(myInitial); + myInitialLastLinesSpaces = indent.whiteSpaces; + myInitialLastLinesTabs = indent.tabs; if (getLineFeeds() > 0) myFlags |= CONTAINS_LF_INITIALLY; else myFlags &= ~CONTAINS_LF_INITIALLY; @@ -613,6 +619,11 @@ class WhiteSpace { return result; } + @NotNull + public IndentInside getInitialLastLineIndent() { + return new IndentInside(myInitialLastLinesSpaces, myInitialLastLinesTabs); + } + private static void appendNonWhitespaces(StringBuilder result, CharSequence[] lines, int currentLine) { // It looks like regexp usage is too heavy here. if (currentLine != lines.length && !lines[currentLine].toString().matches("\\s*")) { diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java index e0961cd1c23f..d88f01007bcf 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java @@ -21,8 +21,7 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.fileTemplates.*; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.ActionToolbarPosition; -import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; @@ -34,7 +33,8 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; -import com.intellij.ui.*; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.TabbedPaneWrapper; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.PlatformIcons; @@ -72,6 +72,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con private FileTemplateTab myIncludesList; private FileTemplateTab myCodeTemplatesList; private FileTemplateTab myJ2eeTemplatesList; + private JComponent myToolBar; private TabbedPaneWrapper myTabbedPane; private FileTemplateConfigurable myEditor; private boolean myModified = false; @@ -225,71 +226,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con myTabbedPane = new TabbedPaneWrapper(myUIDisposable); myTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); for (FileTemplateTab tab : myTabs) { - ToolbarDecorator toolbarDecorator; - if (tab.getComponent() instanceof JList) { - toolbarDecorator = ToolbarDecorator.createDecorator((JList)tab.getComponent()); - } - else if (tab.getComponent() instanceof JTree) { - toolbarDecorator = ToolbarDecorator.createDecorator((JTree)tab.getComponent()); - } - else { - continue; - } - - toolbarDecorator.setAddAction(new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - onAdd(); - } - }).setAddActionUpdater(new AnActionButtonUpdater() { - @Override - public boolean isEnabled(AnActionEvent e) { - return !(myCurrentTab == myCodeTemplatesList || myCurrentTab == myJ2eeTemplatesList); - } - }).setRemoveAction(new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - onRemove(); - } - }).setRemoveActionUpdater(new AnActionButtonUpdater() { - @Override - public boolean isEnabled(AnActionEvent e) { - FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); - return selectedItem != null && !isInternalTemplate(selectedItem.getName(), myCurrentTab.getTitle()); - } - }).addExtraAction(new AnActionButton(IdeBundle.message("action.copy.template"), PlatformIcons.COPY_ICON) { - @Override - public void actionPerformed(AnActionEvent e) { - onClone(); - } - - @Override - public void updateButton(AnActionEvent e) { - super.updateButton(e); - if (e.getPresentation().isEnabled()) { - e.getPresentation().setEnabled( - myCurrentTab != myCodeTemplatesList && myCurrentTab != myJ2eeTemplatesList && myCurrentTab.getSelectedTemplate() != null); - } - } - }).addExtraAction(new AnActionButton(IdeBundle.message("action.reset.to.default"), AllIcons.Actions.Reset) { - @Override - public void actionPerformed(AnActionEvent e) { - onReset(); - } - - @Override - public void updateButton(AnActionEvent e) { - super.updateButton(e); - if (e.getPresentation().isEnabled()) { - final FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); - e.getPresentation().setEnabled(selectedItem instanceof BundledFileTemplate && !selectedItem.isDefault()); - } - } - }); - toolbarDecorator.disableUpDownActions().setToolbarPosition(ActionToolbarPosition.BOTTOM); - JPanel panel = toolbarDecorator.createPanel(); - panel.setBorder(null); - myTabbedPane.addTab(tab.getTitle(), panel); + myTabbedPane.addTab(tab.getTitle(), ScrollPaneFactory.createScrollPane(tab.getComponent())); } myTabbedPane.addChangeListener(new ChangeListener() { @@ -298,6 +235,61 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con } }); + DefaultActionGroup group = new DefaultActionGroup(); + AnAction removeAction = new AnAction(IdeBundle.message("action.remove.template"), null, AllIcons.General.Remove) { + public void actionPerformed(AnActionEvent e) { + onRemove(); + } + + public void update(AnActionEvent e) { + super.update(e); + FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); + e.getPresentation().setEnabled(selectedItem != null && !isInternalTemplate(selectedItem.getName(), myCurrentTab.getTitle())); + } + }; + AnAction addAction = new AnAction(IdeBundle.message("action.create.template"), null, AllIcons.General.Add) { + public void actionPerformed(AnActionEvent e) { + onAdd(); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(!(myCurrentTab == myCodeTemplatesList || myCurrentTab == myJ2eeTemplatesList)); + } + }; + AnAction cloneAction = new AnAction(IdeBundle.message("action.copy.template"), null, PlatformIcons.COPY_ICON) { + public void actionPerformed(AnActionEvent e) { + onClone(); + } + + public void update(AnActionEvent e) { + super.update(e); + e.getPresentation().setEnabled(myCurrentTab != myCodeTemplatesList + && myCurrentTab != myJ2eeTemplatesList + && myCurrentTab.getSelectedTemplate() != null); + } + }; + AnAction resetAction = new AnAction(IdeBundle.message("action.reset.to.default"), null, AllIcons.Actions.Reset) { + public void actionPerformed(AnActionEvent e) { + onReset(); + } + + public void update(AnActionEvent e) { + super.update(e); + final FileTemplate selectedItem = myCurrentTab.getSelectedTemplate(); + e.getPresentation().setEnabled(selectedItem instanceof BundledFileTemplate && !selectedItem.isDefault()); + } + }; + group.add(addAction); + group.add(removeAction); + group.add(cloneAction); + group.add(resetAction); + addAction.registerCustomShortcutSet(CommonShortcuts.INSERT, myCurrentTab.getComponent()); + removeAction.registerCustomShortcutSet(CommonShortcuts.DELETE, + myCurrentTab.getComponent()); + + myToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent(); + myEditor = new FileTemplateConfigurable(); myEditor.addChangeListener(new ChangeListener() { @@ -309,6 +301,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con myMainPanel = new JPanel(new BorderLayout()); Splitter splitter = new Splitter(); JPanel leftPanel = new JPanel(new BorderLayout()); + leftPanel.add(myToolBar, BorderLayout.NORTH); leftPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER); splitter.setFirstComponent(leftPanel); myEditorComponent = myEditor.createComponent(); @@ -408,7 +401,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con } private static boolean isInternalTemplateName(final String templateName) { - for (InternalTemplateBean bean : Extensions.getExtensions(InternalTemplateBean.EP_NAME)) { + for(InternalTemplateBean bean: Extensions.getExtensions(InternalTemplateBean.EP_NAME)) { if (Comparing.strEqual(templateName, bean.name)) { return true; } @@ -418,13 +411,13 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con private void initLists() { final FileTemplateManager templateManager = FileTemplateManager.getInstance(); - + final FileTemplate[] internalTemplates = templateManager.getInternalTemplates(); myInternalTemplateNames.clear(); for (FileTemplate internalTemplate : internalTemplates) { myInternalTemplateNames.add(((FileTemplateBase)internalTemplate).getQualifiedName()); } - + myTemplatesList.init(ArrayUtil.mergeArrays(internalTemplates, templateManager.getAllTemplates())); myIncludesList.init(templateManager.getAllPatterns()); if (myCodeTemplatesList != null) { @@ -469,7 +462,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con } allNames.add(currName); } - + if (itemWithError != null) { final boolean _errorInName = errorInName; myTabbedPane.setSelectedIndex(Arrays.asList(myTabs).indexOf(list)); @@ -503,14 +496,14 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con myModified = true; myEditor.apply(); } - + for (FileTemplateTab list : myTabs) { checkCanApply(list); } final FileTemplateManager templatesManager = FileTemplateManager.getInstance(); // Apply templates - + final List templates = new ArrayList(); final List internalTemplates = new ArrayList(); for (FileTemplate template : myTemplatesList.getTemplates()) { @@ -521,7 +514,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con templates.add(template); } } - + templatesManager.setTemplates(FileTemplateManager.DEFAULT_TEMPLATES_CATEGORY, templates); templatesManager.setTemplates(FileTemplateManager.INTERNAL_TEMPLATES_CATEGORY, internalTemplates); templatesManager.setTemplates(FileTemplateManager.INCLUDES_TEMPLATES_CATEGORY, Arrays.asList(myIncludesList.getTemplates())); @@ -584,6 +577,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con myUIDisposable = null; } myTabbedPane = null; + myToolBar = null; myTabs = null; myCurrentTab = null; myTemplatesList = null; diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java index ad0d55604562..829076a479ba 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java @@ -33,7 +33,6 @@ import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettin import com.intellij.util.containers.Stack; import com.intellij.util.text.CharArrayUtil; import gnu.trove.TIntArrayList; -import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -163,14 +162,14 @@ public class ArrangementEngine { // -------------------------- // arrange 'Entry1 Entry2' - List entries = new ArrayList(); + List> entries = new ArrayList>(); Stack stack = new Stack(); - entries.addAll(context.entries); - stack.push(new StackEntry(0, context.entries.size())); + entries.addAll(context.wrappers); + stack.push(new StackEntry(0, context.wrappers.size())); while (!stack.isEmpty()) { StackEntry stackEntry = stack.peek(); if (stackEntry.current >= stackEntry.end) { - List subEntries = (List)entries.subList(stackEntry.start, stackEntry.end); + List> subEntries = entries.subList(stackEntry.start, stackEntry.end); if (subEntries.size() > 1) { doArrange(subEntries, context); } @@ -178,8 +177,8 @@ public class ArrangementEngine { stack.pop(); } else { - ArrangementEntry entry = entries.get(stackEntry.current++); - Collection children = entry.getChildren(); + ArrangementEntryWrapper wrapper = entries.get(stackEntry.current++); + List> children = wrapper.getChildren(); if (!children.isEmpty()) { entries.addAll(children); stack.push(new StackEntry(stackEntry.end, children.size())); @@ -189,17 +188,17 @@ public class ArrangementEngine { } @SuppressWarnings("unchecked") - private static void doArrange(@NotNull List entries, + private static void doArrange(@NotNull List> entries, @NotNull Context context) { - List arranged = new ArrayList(); - Set unprocessed = new LinkedHashSet(entries); + List> arranged = new ArrayList>(); + Set> unprocessed = new LinkedHashSet>(entries); for (ArrangementRule rule : context.rules) { - for (E entry : entries) { - if (entry.canBeMatched() && unprocessed.contains(entry) && rule.getMatcher().isMatched(entry)) { - arranged.add(entry); - unprocessed.remove(entry); + for (ArrangementEntryWrapper wrapper : entries) { + if (wrapper.getEntry().canBeMatched() && unprocessed.contains(wrapper) && rule.getMatcher().isMatched(wrapper.getEntry())) { + arranged.add(wrapper); + unprocessed.remove(wrapper); } } } @@ -208,33 +207,31 @@ public class ArrangementEngine { context.prepare(arranged); // We apply changes from the last position to the first position in order not to bother with offsets shifts. for (int i = arranged.size() - 1; i >= 0; i--) { - E arrangedEntry = arranged.get(i); - E initialEntry = entries.get(i); - context.replace(initialEntry, arrangedEntry, (E)arrangedEntry.getParent(), i > 0 ? arranged.get(i - 1) : null); + ArrangementEntryWrapper arrangedWrapper = arranged.get(i); + ArrangementEntryWrapper initialWrapper = entries.get(i); + context.replace(arrangedWrapper, initialWrapper, i > 0 ? arranged.get(i - 1) : null); } } private static class Context { - @NotNull public final Rearranger rearranger; - @NotNull public final Collection entries; - @NotNull public final Document document; - @NotNull public final List rules; - @NotNull public final CodeStyleSettings mySettings; + @NotNull public final Rearranger rearranger; + @NotNull public final Collection> wrappers; + @NotNull public final Document document; + @NotNull public final List rules; + @NotNull public final CodeStyleSettings mySettings; - /** Holds information on how many symbols was added to the initial entry text during the processing. */ - @NotNull private final TObjectIntHashMap myExtraSizes = new TObjectIntHashMap(); @NotNull private String myParentText; private int myParentShift; private Context(@NotNull Rearranger rearranger, - @NotNull Collection entries, + @NotNull Collection> wrappers, @NotNull Document document, @NotNull List rules, @NotNull CodeStyleSettings settings) { this.rearranger = rearranger; - this.entries = entries; + this.wrappers = wrappers; this.document = document; this.rules = rules; mySettings = settings; @@ -248,24 +245,31 @@ public class ArrangementEngine { @NotNull CodeStyleSettings settings) { Collection entries = rearranger.parse(root, document, ranges); - return new Context(rearranger, entries, document, rules, settings); + Collection> wrappers = new ArrayList>(); + ArrangementEntryWrapper previous = null; + for (T entry : entries) { + ArrangementEntryWrapper wrapper = new ArrangementEntryWrapper(entry); + if (previous != null) { + previous.setNext(wrapper); + wrapper.setPrevious(previous); + } + wrappers.add(wrapper); + previous = wrapper; + } + return new Context(rearranger, wrappers, document, rules, settings); } - public void prepare(@NotNull List arrangedEntries) { + public void prepare(@NotNull List> arrangedEntries) { if (arrangedEntries.isEmpty()) { return; } - E parent = arrangedEntries.get(0); + ArrangementEntryWrapper parent = arrangedEntries.get(0).getParent(); if (parent == null) { myParentText = document.getText(); myParentShift = 0; } else { - int endOffset = parent.getEndOffset(); - if (myExtraSizes.containsKey(parent)) { - endOffset += myExtraSizes.get(parent); - } - myParentText = document.getCharsSequence().subSequence(parent.getStartOffset(), endOffset).toString(); + myParentText = document.getCharsSequence().subSequence(parent.getStartOffset(), parent.getEndOffset()).toString(); myParentShift = parent.getStartOffset(); } } @@ -273,17 +277,19 @@ public class ArrangementEngine { /** * Replaces given 'old entry' by the given 'new entry'. * - * @param oldEntry entry which range should be replaced by the given 'new entry' - * @param newEntry entry which text should replace given 'old entry' range - * @param parent parent entry for the given entries - * @param previous previous entry for the 'new entry' (if any) + * @param newWrapper wrapper for an entry which text should replace given 'old entry' range + * @param oldWrapper wrapper for an entry which range should be replaced by the given 'new entry' + * @param previous wrapper which will be previous for the entry referenced via the given 'new wrapper' */ @SuppressWarnings("AssignmentToForLoopParameter") - public void replace(@NotNull E oldEntry, @NotNull E newEntry, @Nullable E parent, @Nullable E previous) { + public void replace(@NotNull ArrangementEntryWrapper newWrapper, + @NotNull ArrangementEntryWrapper oldWrapper, + @Nullable ArrangementEntryWrapper previous) + { // Calculate blank lines before the arrangement. int blankLinesBefore = 0; TIntArrayList lineFeedOffsets = new TIntArrayList(); - int oldStartLine = document.getLineNumber(oldEntry.getStartOffset()); + int oldStartLine = document.getLineNumber(oldWrapper.getStartOffset()); if (oldStartLine > 0) { int lastLineFeed = document.getLineStartOffset(oldStartLine) - 1; lineFeedOffsets.add(lastLineFeed); @@ -299,50 +305,52 @@ public class ArrangementEngine { } } - int desiredBlankLinesNumber = rearranger.getBlankLines(mySettings, parent, previous, newEntry); - if (desiredBlankLinesNumber == blankLinesBefore && newEntry.equals(oldEntry)) { + ArrangementEntryWrapper parentWrapper = oldWrapper.getParent(); + int desiredBlankLinesNumber = rearranger.getBlankLines(mySettings, + parentWrapper == null ? null : parentWrapper.getEntry(), + previous == null ? null : previous.getEntry(), + newWrapper.getEntry()); + if (desiredBlankLinesNumber == blankLinesBefore && newWrapper.equals(oldWrapper)) { return; } - String newEntryText = myParentText.substring(newEntry.getStartOffset() - myParentShift, newEntry.getEndOffset() - myParentShift); + String newEntryText = myParentText.substring(newWrapper.getStartOffset() - myParentShift, newWrapper.getEndOffset() - myParentShift); int lineFeedsDiff = desiredBlankLinesNumber - blankLinesBefore; - if (lineFeedsDiff == 0) { - document.replaceString(oldEntry.getStartOffset(), oldEntry.getEndOffset(), newEntryText); + if (lineFeedsDiff == 0 || desiredBlankLinesNumber < 0) { + document.replaceString(oldWrapper.getStartOffset(), oldWrapper.getEndOffset(), newEntryText); return; } - int oldEndOffset = oldEntry.getEndOffset(); - if (myExtraSizes.containsKey(oldEntry)) { - oldEndOffset += myExtraSizes.get(oldEntry); - } if (lineFeedsDiff > 0) { + // Insert necessary number of blank lines. StringBuilder buffer = new StringBuilder(StringUtil.repeat("\n", lineFeedsDiff)); buffer.append(newEntryText); - document.replaceString(oldEntry.getStartOffset(), oldEndOffset, buffer); - for (ArrangementEntry entry = newEntry; entry != null; entry = entry.getParent()) { - if (myExtraSizes.containsKey(entry)) { - myExtraSizes.put(entry, myExtraSizes.get(entry) + lineFeedsDiff); - } - else { - myExtraSizes.put(entry, lineFeedsDiff); - } - } - } - else if (desiredBlankLinesNumber == blankLinesBefore) { - document.replaceString(oldEntry.getStartOffset(), oldEndOffset, newEntryText); + document.replaceString(oldWrapper.getStartOffset(), oldWrapper.getEndOffset(), buffer); } else { // Cut exceeding blank lines. - int blankLinesToCut = blankLinesBefore - desiredBlankLinesNumber; - int replacementStartOffset = lineFeedOffsets.get(lineFeedOffsets.size() - blankLinesToCut); - document.replaceString(replacementStartOffset, oldEndOffset, newEntryText); + int replacementStartOffset = lineFeedOffsets.get(lineFeedOffsets.size() + lineFeedsDiff); + document.replaceString(replacementStartOffset, oldWrapper.getEndOffset(), newEntryText); } - for (ArrangementEntry entry = newEntry; entry != null; entry = entry.getParent()) { - if (myExtraSizes.containsKey(entry)) { - myExtraSizes.put(entry, myExtraSizes.get(entry) + lineFeedsDiff); - } - else { - myExtraSizes.put(entry, lineFeedsDiff); + + // Update wrapper ranges. + ArrangementEntryWrapper parent = oldWrapper.getParent(); + if (parent == null) { + return; + } + + Deque> parents = new ArrayDeque>(); + do { + parents.add(parent); + parent.setEndOffset(parent.getEndOffset() + lineFeedsDiff); + parent = parent.getParent(); + } while (parent != null); + + + while (!parents.isEmpty()) { + + for (ArrangementEntryWrapper wrapper = parents.removeLast().getNext(); wrapper != null; wrapper = wrapper.getNext()) { + wrapper.applyShift(lineFeedsDiff); } } } diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java new file mode 100644 index 000000000000..53239189beeb --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEntryWrapper.java @@ -0,0 +1,146 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.codeStyle.arrangement.engine; + +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.arrangement.ArrangementEntry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Auxiliary data structure used {@link ArrangementEngine#arrange(PsiFile, Collection) arrangement}. + *

+ * The general idea is to provide the following: + *

+ * 
    + *
  • 'parent-child' and 'sibling' relations between the {@link ArrangementEntry entries};
  • + *
  • ability to reflect actual entry range (after its arrangement and/or blank lines addition/removal);
  • + *
+ *
+ *

+ * Not thread-safe. + * + * @author Denis Zhdanov + * @since 8/31/12 12:06 PM + */ +public class ArrangementEntryWrapper { + + @NotNull private final List> myChildren = new ArrayList>(); + @NotNull private final E myEntry; + + @Nullable private ArrangementEntryWrapper myParent; + @Nullable private ArrangementEntryWrapper myPrevious; + @Nullable private ArrangementEntryWrapper myNext; + + private int myStartOffset; + private int myEndOffset; + + @SuppressWarnings("unchecked") + public ArrangementEntryWrapper(@NotNull E entry) { + myEntry = entry; + myStartOffset = entry.getStartOffset(); + myEndOffset = entry.getEndOffset(); + for (ArrangementEntry child : entry.getChildren()) { + ArrangementEntryWrapper childWrapper = new ArrangementEntryWrapper((E)child); + childWrapper.setParent(this); + myChildren.add(childWrapper); + } + } + + @NotNull + public E getEntry() { + return myEntry; + } + + public int getStartOffset() { + return myStartOffset; + } + + public int getEndOffset() { + return myEndOffset; + } + + public void setEndOffset(int endOffset) { + myEndOffset = endOffset; + } + + @Nullable + public ArrangementEntryWrapper getParent() { + return myParent; + } + + public void setParent(@Nullable ArrangementEntryWrapper parent) { + myParent = parent; + } + + @Nullable + public ArrangementEntryWrapper getPrevious() { + return myPrevious; + } + + public void setPrevious(@Nullable ArrangementEntryWrapper previous) { + myPrevious = previous; + } + + @Nullable + public ArrangementEntryWrapper getNext() { + return myNext; + } + + public void setNext(@Nullable ArrangementEntryWrapper next) { + myNext = next; + } + + @NotNull + public List> getChildren() { + return myChildren; + } + + public void applyShift(int shift) { + myStartOffset += shift; + myEndOffset += shift; + for (ArrangementEntryWrapper child : myChildren) { + child.applyShift(shift); + } + } + + @Override + public int hashCode() { + return myEntry.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ArrangementEntryWrapper wrapper = (ArrangementEntryWrapper)o; + return myEntry.equals(wrapper.myEntry); + } + + @Override + public String toString() { + return myEntry.toString(); + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java b/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java index 33a699768da9..33e79334f6f7 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java @@ -75,7 +75,7 @@ public class LoadingDecorator { final Font font = text.getFont(); text.setFont(font.deriveFont(font.getStyle(), font.getSize() + 8)); - text.setForeground(Color.black); + //text.setForeground(Color.black); final int gap = new JLabel().getIconTextGap(); final NonOpaquePanel result = new NonOpaquePanel(new FlowLayout(FlowLayout.CENTER, gap * 3, 0)); diff --git a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java index 6d4b415b21c3..60769666531f 100644 --- a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java +++ b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java @@ -19,6 +19,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.util.IconUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nullable; @@ -164,6 +165,11 @@ public class CommonActionsPanel extends JPanel { e.getPresentation().setEnabled(false); return; } + final SpeedSearchSupply supply = SpeedSearchSupply.getSupply(contextComponent); + if (supply != null && supply.isPopupActive()) { + e.getPresentation().setEnabled(false); + return; + } removeButton.update(e); } }.registerCustomShortcutSet(CustomShortcutSet.fromString("DELETE", "BACK_SPACE"), removeButton.getContextComponent()); diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java index edae80b1eb62..0d5ad9ab02a0 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/ActionMacroManager.java @@ -96,21 +96,20 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named myActionManager = actionManagerEx; myActionManager.addAnActionListener(new AnActionListener() { public void beforeActionPerformed(AnAction action, DataContext dataContext, final AnActionEvent event) { - if (myIsRecording) { - String id = myActionManager.getId(action); - //noinspection HardCodedStringLiteral - if (id != null && !"StartStopMacroRecording".equals(id)) { - myRecordingMacro.appendAction(id); - String shortcut = null; - if (event.getInputEvent() instanceof KeyEvent) { - shortcut = KeymapUtil.getKeystrokeText(KeyStroke.getKeyStrokeForEvent((KeyEvent)event.getInputEvent())); - } - notifyUser(id + (shortcut != null ? " (" + shortcut + ")" : ""), false); - } - - if (id != null) { - myLastActionInputEvent.add(event.getInputEvent()); + String id = myActionManager.getId(action); + if (id == null) return; + //noinspection HardCodedStringLiteral + if ("StartStopMacroRecording".equals(id)) { + myLastActionInputEvent.add(event.getInputEvent()); + } + else if (myIsRecording) { + myRecordingMacro.appendAction(id); + String shortcut = null; + if (event.getInputEvent() instanceof KeyEvent) { + shortcut = KeymapUtil.getKeystrokeText(KeyStroke.getKeyStrokeForEvent((KeyEvent)event.getInputEvent())); } + notifyUser(id + (shortcut != null ? " (" + shortcut + ")" : ""), false); + myLastActionInputEvent.add(event.getInputEvent()); } } diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/MacrosGroup.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/MacrosGroup.java index 73c86574fe58..fe11f19a0967 100644 --- a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/MacrosGroup.java +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/MacrosGroup.java @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -33,16 +34,18 @@ import java.util.ArrayList; * To change this template use Options | File Templates. */ public class MacrosGroup extends ActionGroup { + @NotNull public AnAction[] getChildren(@Nullable AnActionEvent e) { ArrayList actions = new ArrayList(); final ActionManagerEx actionManager = ((ActionManagerEx) ActionManager.getInstance()); String[] ids = actionManager.getActionIds(ActionMacro.MACRO_ACTION_PREFIX); - for (int i = 0; i < ids.length; i++) { - String id = ids[i]; + for (String id : ids) { actions.add(actionManager.getAction(id)); } return actions.toArray(new AnAction[actions.size()]); } + + } diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/PlaySavedMacros.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/PlaySavedMacros.java new file mode 100644 index 000000000000..9e4057e658cd --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/PlaySavedMacros.java @@ -0,0 +1,18 @@ +package com.intellij.ide.actionMacro.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.ui.popup.JBPopupFactory; + +/** + * User: Evgeny.Zakrevsky + * Date: 8/14/12 + */ +public class PlaySavedMacros extends AnAction { + @Override + public void actionPerformed(final AnActionEvent e) { + JBPopupFactory.getInstance() + .createActionGroupPopup("Play Saved Macros", new MacrosGroup(), e.getDataContext(), JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false) + .showCenteredInCurrentWindow(e.getProject()); + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java index 50cbe3fb511c..ad6b174055e8 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java @@ -86,9 +86,9 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { pluginsModel = new AvailablePluginsTableModel(); pluginTable = new PluginTable(pluginsModel); pluginTable.getTableHeader().setReorderingAllowed(false); - pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DOWNLOADS, 60); - pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DATE, 60); - pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_RATE, 70); + pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DOWNLOADS, 70); + pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DATE, 50); + pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_RATE, 60); return ScrollPaneFactory.createScrollPane(pluginTable); } diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java index 157d1ca7a42f..36008a7b9eca 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java @@ -173,7 +173,7 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable }); final TableColumn logColumn = getColumnModel().getColumn(LOG_COLUMN); - logColumn.setMaxWidth(new JComboBox().getPreferredSize().width); + logColumn.setMaxWidth(logColumn.getPreferredWidth()); getEmptyText().setText("No notifications configured"); } diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java index 1a6aac5d6fdf..92239a9fd20c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -55,7 +55,6 @@ import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.MouseEvent; import java.util.ArrayList; -import java.util.ConcurrentModificationException; import java.util.LinkedList; import java.util.List; @@ -63,17 +62,10 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionToolbarImpl"); private static List ourToolbars = new LinkedList(); - private static Throwable ourLastModification = null; public static void updateAllToolbarsImmediately() { - try { - ourLastModification = null; - for (ActionToolbarImpl toolbar : ourToolbars) { - toolbar.updateActionsImmediately(); - } - } - catch (ConcurrentModificationException e) { - LOG.error(ourLastModification == null? e : ourLastModification); + for (ActionToolbarImpl toolbar : new ArrayList(ourToolbars)) { + toolbar.updateActionsImmediately(); } } @@ -178,7 +170,6 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { @Override public void addNotify() { super.addNotify(); - ourLastModification = new ConcurrentModificationException(); ourToolbars.add(this); myActionManager.addTimerListener(500, myWeakTimerListener); myActionManager.addTransparentTimerListener(500, myWeakTimerListener); @@ -199,7 +190,6 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { @Override public void removeNotify() { super.removeNotify(); - ourLastModification = new ConcurrentModificationException(); ourToolbars.remove(this); myActionManager.removeTimerListener(myWeakTimerListener); myActionManager.removeTransparentTimerListener(myWeakTimerListener); @@ -484,7 +474,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { for (final Rectangle r : bounds) { if (r.height < maxHeight) { - r.y = r.y + (maxHeight - r.height) / 2; + r.y += (maxHeight - r.height) / 2; } } @@ -555,7 +545,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { // Lay components out int xOffset = insets.left; int yOffset = insets.top; - // Calculate max size of a row. It's not possible to make more then 3 row toolbar + // Calculate max size of a row. It's not possible to make more than 3 row toolbar final int maxRowWidth = Math.max(sizeToFit.width, componentCount * maxWidth / 3); for (int i = 0; i < componentCount; i++) { if (xOffset + maxWidth > maxRowWidth) { // place component at new row @@ -1185,14 +1175,12 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { ArrayList result = new ArrayList(); ArrayList secondary = new ArrayList(); - if (myActionGroup != null) { - AnAction[] kids = myActionGroup.getChildren(null); - for (AnAction each : kids) { - if (myActionGroup.isPrimary(each)) { - result.add(each); - } else { - secondary.add(each); - } + AnAction[] kids = myActionGroup.getChildren(null); + for (AnAction each : kids) { + if (myActionGroup.isPrimary(each)) { + result.add(each); + } else { + secondary.add(each); } } result.add(new Separator()); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java index 2aa06fac95b9..1bd8085e438d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java @@ -33,6 +33,7 @@ import com.intellij.openapi.vfs.impl.http.RemoteFileInfo; import com.intellij.openapi.vfs.impl.http.RemoteFileState; import com.intellij.util.EventDispatcher; import com.intellij.util.net.HTTPProxySettingsDialog; +import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NonNls; @@ -152,17 +153,25 @@ public class RemoteFilePanel implements PropertyChangeListener { } public void selectNotify() { - myProgressUpdatesQueue.showNotify(); - if (myFileEditor != null) { - myFileEditor.selectNotify(); - } + UIUtil.invokeLaterIfNeeded(new Runnable() { + public void run() { + myProgressUpdatesQueue.showNotify(); + if (myFileEditor != null) { + myFileEditor.selectNotify(); + } + } + }); } public void deselectNotify() { - myProgressUpdatesQueue.hideNotify(); - if (myFileEditor != null) { - myFileEditor.deselectNotify(); - } + UIUtil.invokeLaterIfNeeded(new Runnable() { + public void run() { + myProgressUpdatesQueue.hideNotify(); + if (myFileEditor != null) { + myFileEditor.deselectNotify(); + } + } + }); } public void dispose() { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index a8c31f4db77c..bfb5bd98b779 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -1500,7 +1500,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } ToolWindowAnchor getToolWindowAnchor(final String id) { - ApplicationManager.getApplication().assertIsDispatchThread(); checkId(id); return getInfo(id).getAnchor(); } diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index a6e457b6e768..3c1213959fac 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -687,13 +687,16 @@ action.GenerateJavadoc.text=Generate Java_Doc... action.GenerateJavadoc.description=Run the JavaDoc tool group.Macros.text=_Macros group.Macros.description=View, Change, Record, Play Macros -group.StanardMacroActions.text=Standard Macro Actions +group.StandardMacroActions.text=Standard Macro Actions action.PlaybackLastMacro.text=Pla_y Back Last Macro action.PlaybackLastMacro.description=Play Back last used macro action.StartStopMacroRecording.text=Start/Stop Macro _Recording action.StartStopMacroRecording.description=Start/Stop recording of a new macro action.EditMacros.text=_Edit Macros action.EditMacros.description=Configure existing macros +action.PlaySavedMacrosAction.text=Play Saved Macros... +action.PlaySavedMacrosAction.description=Play Saved Macros +group.MacrosGroup.text=Macro Actions action.ValidateXml.text=_Validate action.ValidateXml.description=Validate the current XML file action.GenerateDTD.text=Generate DTD from _XML File @@ -1192,7 +1195,6 @@ group.EditorPopupMenu.Run.text=Compile/Run Actions group.ProjectViewCompileGroup.text=Compile/Debug Actions group.ProjectViewAnalysisGroup.text=Analysis Actions action.PerformanceReport.text=Submit Performance Report -group.MacrosGroup.text=Macro Actions group.PairFileActions.text=Actions on Pairs of Files group.RefactoringMenu1.text=Refactoring Actions (1) group.RefactoringMenu2.text=Refactoring Actions (2) @@ -1244,8 +1246,6 @@ group.AnalyzeJavaMenu.text=Analyze Java Menu group.AnalyzeJavaMenu.description=Analyze Java Menu action.InvalidateCaches.text=Invalidate Caches... action.InvalidateCaches.description=Force rebuild of all caches and indices on next startup -group.PlaySavedMacroActions.text=Play Saved Macros -group.PlaySavedMacroActions.description=Play Saved Macros group.ToolsBasicGroup.text=Tools Basic Group group.ToolsBasicGroup.description=Tools Basic Group group.ToolbarNewElement.text=Toolbar New Element Group diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml index 6c55c58c08b8..b713cd608aa2 100644 --- a/platform/platform-resources/src/idea/Keymap_Default.xml +++ b/platform/platform-resources/src/idea/Keymap_Default.xml @@ -85,9 +85,6 @@ - - - diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 8f1ae1602124..adb792aaea16 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -203,13 +203,14 @@ - + + - + diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java index 0023ebcdd983..984b9f1a1fb0 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentEntryImpl.java @@ -33,7 +33,7 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; import java.util.*; @@ -43,10 +43,10 @@ import java.util.*; public class ContentEntryImpl extends RootModelComponentBase implements ContentEntry, ClonableContentEntry, Comparable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleContentEntryImpl"); @NotNull private final VirtualFilePointer myRoot; - @NonNls public static final String ELEMENT_NAME = JpsModuleSerializer.CONTENT_TAG; + @NonNls public static final String ELEMENT_NAME = JpsModuleRootModelSerializer.CONTENT_TAG; private final Set mySourceFolders = new LinkedHashSet(); private final Set myExcludeFolders = new TreeSet(ContentFolderComparator.INSTANCE); - @NonNls public static final String URL_ATTRIBUTE = JpsModuleSerializer.URL_ATTRIBUTE; + @NonNls public static final String URL_ATTRIBUTE = JpsModuleRootModelSerializer.URL_ATTRIBUTE; ContentEntryImpl(@NotNull VirtualFile file, @NotNull RootModelImpl m) { this(file.getUrl(), m); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java index 09be6b06c03f..2ab6749846a5 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java @@ -27,13 +27,13 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; /** * @author dsl */ public abstract class ContentFolderBaseImpl extends RootModelComponentBase implements ContentFolder, Comparable { - @NonNls public static final String URL_ATTRIBUTE = JpsModuleSerializer.URL_ATTRIBUTE; + @NonNls public static final String URL_ATTRIBUTE = JpsModuleRootModelSerializer.URL_ATTRIBUTE; private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleContentFolderBaseImpl"); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java index caf7426c05ce..b463bb23233a 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ExcludeFolderImpl.java @@ -25,7 +25,7 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; /** * @author dsl @@ -33,7 +33,7 @@ import org.jetbrains.jps.model.serialization.JpsModuleSerializer; public class ExcludeFolderImpl extends ContentFolderBaseImpl implements ClonableContentFolder, UserDefinedExcludeFolder { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleExcludeFolderImpl"); - @NonNls public static final String ELEMENT_NAME = JpsModuleSerializer.EXCLUDE_FOLDER_TAG; + @NonNls public static final String ELEMENT_NAME = JpsModuleRootModelSerializer.EXCLUDE_FOLDER_TAG; ExcludeFolderImpl(@NotNull VirtualFile file, @NotNull ContentEntryImpl contentEntry) { super(file, contentEntry); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java index c593128ecde3..691e73d8e6f8 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/InheritedJdkOrderEntryImpl.java @@ -26,13 +26,13 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import org.jdom.Element; import org.jetbrains.annotations.NonNls; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; /** * @author dsl */ public class InheritedJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implements InheritedJdkOrderEntry, ClonableOrderEntry, WritableOrderEntry { - @NonNls public static final String ENTRY_TYPE = JpsModuleSerializer.INHERITED_JDK_TYPE; + @NonNls public static final String ENTRY_TYPE = JpsModuleRootModelSerializer.INHERITED_JDK_TYPE; private final MyJdkTableListener myJdkTableListener = new MyJdkTableListener(); private final MyProjectJdkListener myListener = new MyProjectJdkListener(); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java index b06d1c0ea667..f53ebf1e5895 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/LibraryOrderEntryImpl.java @@ -30,7 +30,7 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; import org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension; /** @@ -42,9 +42,9 @@ class LibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements Library @Nullable private String myLibraryName; // is non-null if myLibrary == null @Nullable private String myLibraryLevel; // is non-null if myLibraryLevel == null private boolean myExported; - @NonNls static final String ENTRY_TYPE = JpsModuleSerializer.LIBRARY_TYPE; - @NonNls private static final String NAME_ATTR = JpsModuleSerializer.NAME_ATTRIBUTE; - @NonNls private static final String LEVEL_ATTR = JpsModuleSerializer.LEVEL_ATTRIBUTE; + @NonNls static final String ENTRY_TYPE = JpsModuleRootModelSerializer.LIBRARY_TYPE; + @NonNls private static final String NAME_ATTR = JpsModuleRootModelSerializer.NAME_ATTRIBUTE; + @NonNls private static final String LEVEL_ATTR = JpsModuleRootModelSerializer.LEVEL_ATTRIBUTE; private final MyOrderEntryLibraryTableListener myLibraryListener = new MyOrderEntryLibraryTableListener(); @NonNls private static final String EXPORTED_ATTR = JpsJavaModelSerializerExtension.EXPORTED_ATTRIBUTE; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java index 4a18cb57001c..1d496f32a12d 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleJdkOrderEntryImpl.java @@ -30,7 +30,7 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; /** * @author dsl @@ -39,9 +39,9 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement ClonableOrderEntry, ModuleJdkOrderEntry, ProjectJdkTable.Listener { - @NonNls public static final String ENTRY_TYPE = JpsModuleSerializer.JDK_TYPE; - @NonNls public static final String JDK_NAME_ATTR = JpsModuleSerializer.JDK_NAME_ATTRIBUTE; - @NonNls public static final String JDK_TYPE_ATTR = JpsModuleSerializer.JDK_TYPE_ATTRIBUTE; + @NonNls public static final String ENTRY_TYPE = JpsModuleRootModelSerializer.JDK_TYPE; + @NonNls public static final String JDK_NAME_ATTR = JpsModuleRootModelSerializer.JDK_NAME_ATTRIBUTE; + @NonNls public static final String JDK_TYPE_ATTR = JpsModuleRootModelSerializer.JDK_TYPE_ATTRIBUTE; @Nullable private Sdk myJdk; private String myJdkName; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java index 8409613ed336..b69dd56b79c0 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleLibraryOrderEntryImpl.java @@ -30,7 +30,7 @@ import com.intellij.util.PathUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; import org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension; /** @@ -40,7 +40,7 @@ import org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtensio public class ModuleLibraryOrderEntryImpl extends LibraryOrderEntryBaseImpl implements LibraryOrderEntry, ClonableOrderEntry, WritableOrderEntry { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.LibraryOrderEntryImpl"); private final Library myLibrary; - @NonNls public static final String ENTRY_TYPE = JpsModuleSerializer.MODULE_LIBRARY_TYPE; + @NonNls public static final String ENTRY_TYPE = JpsModuleRootModelSerializer.MODULE_LIBRARY_TYPE; private boolean myExported; @NonNls public static final String EXPORTED_ATTR = JpsJavaModelSerializerExtension.EXPORTED_ATTRIBUTE; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java index 12408c276a2f..5cf2009578fc 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEntryImpl.java @@ -29,15 +29,15 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; import org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension; /** * @author dsl */ public class ModuleOrderEntryImpl extends OrderEntryBaseImpl implements ModuleOrderEntry, WritableOrderEntry, ClonableOrderEntry { - @NonNls public static final String ENTRY_TYPE = JpsModuleSerializer.MODULE_TYPE; - @NonNls public static final String MODULE_NAME_ATTR = JpsModuleSerializer.MODULE_NAME_ATTRIBUTE; + @NonNls public static final String ENTRY_TYPE = JpsModuleRootModelSerializer.MODULE_TYPE; + @NonNls public static final String MODULE_NAME_ATTR = JpsModuleRootModelSerializer.MODULE_NAME_ATTRIBUTE; @NonNls private static final String EXPORTED_ATTR = JpsJavaModelSerializerExtension.EXPORTED_ATTRIBUTE; private final ModulePointer myModulePointer; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java index 209151542680..efa433d3c220 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleSourceOrderEntryImpl.java @@ -27,7 +27,7 @@ import com.intellij.util.ArrayUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; import java.util.ArrayList; @@ -35,7 +35,7 @@ import java.util.ArrayList; * @author dsl */ public class ModuleSourceOrderEntryImpl extends OrderEntryBaseImpl implements ModuleSourceOrderEntry, WritableOrderEntry, ClonableOrderEntry { - @NonNls static final String ENTRY_TYPE = JpsModuleSerializer.SOURCE_FOLDER_TYPE; + @NonNls static final String ENTRY_TYPE = JpsModuleRootModelSerializer.SOURCE_FOLDER_TYPE; @NonNls private static final String ATTRIBUTE_FOR_TESTS = "forTests"; ModuleSourceOrderEntryImpl(RootModelImpl rootModel) { diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEntryFactory.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEntryFactory.java index dec60af43a0b..1e71cf158c11 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEntryFactory.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEntryFactory.java @@ -21,15 +21,15 @@ import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.util.InvalidDataException; import org.jdom.Element; import org.jetbrains.annotations.NonNls; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; /** * @author dsl */ public class OrderEntryFactory { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.OrderEntryFactory"); - @NonNls public static final String ORDER_ENTRY_ELEMENT_NAME = JpsModuleSerializer.ORDER_ENTRY_TAG; - @NonNls public static final String ORDER_ENTRY_TYPE_ATTR = JpsModuleSerializer.TYPE_ATTRIBUTE; + @NonNls public static final String ORDER_ENTRY_ELEMENT_NAME = JpsModuleRootModelSerializer.ORDER_ENTRY_TAG; + @NonNls public static final String ORDER_ENTRY_TYPE_ATTR = JpsModuleRootModelSerializer.TYPE_ATTRIBUTE; static OrderEntry createOrderEntryByElement(Element element, RootModelImpl rootModel, ProjectRootManagerImpl projectRootManager) throws InvalidDataException { LOG.assertTrue(ORDER_ENTRY_ELEMENT_NAME.equals(element.getName())); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java index bc17b4e67c5c..a2dbb746e766 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/SourceFolderImpl.java @@ -25,7 +25,7 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.serialization.JpsModuleSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer; /** * @author dsl @@ -33,8 +33,8 @@ import org.jetbrains.jps.model.serialization.JpsModuleSerializer; public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFolder, ClonableContentFolder { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.SimpleSourceFolderImpl"); private final boolean myIsTestSource; - @NonNls public static final String ELEMENT_NAME = JpsModuleSerializer.SOURCE_FOLDER_TAG; - @NonNls public static final String TEST_SOURCE_ATTR = JpsModuleSerializer.IS_TEST_SOURCE_ATTRIBUTE; + @NonNls public static final String ELEMENT_NAME = JpsModuleRootModelSerializer.SOURCE_FOLDER_TAG; + @NonNls public static final String TEST_SOURCE_ATTR = JpsModuleRootModelSerializer.IS_TEST_SOURCE_ATTRIBUTE; private String myPackagePrefix; static final String DEFAULT_PACKAGE_PREFIX = ""; @@ -60,7 +60,7 @@ public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFol final String testSource = element.getAttributeValue(TEST_SOURCE_ATTR); if (testSource == null) throw new InvalidDataException(); myIsTestSource = Boolean.valueOf(testSource).booleanValue(); - final String packagePrefix = element.getAttributeValue(JpsModuleSerializer.PACKAGE_PREFIX_ATTRIBUTE); + final String packagePrefix = element.getAttributeValue(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE); if (packagePrefix != null) { myPackagePrefix = packagePrefix; } @@ -94,7 +94,7 @@ public class SourceFolderImpl extends ContentFolderBaseImpl implements SourceFol writeFolder(element, ELEMENT_NAME); element.setAttribute(TEST_SOURCE_ATTR, Boolean.toString(myIsTestSource)); if (!DEFAULT_PACKAGE_PREFIX.equals(myPackagePrefix)) { - element.setAttribute(JpsModuleSerializer.PACKAGE_PREFIX_ATTRIBUTE, myPackagePrefix); + element.setAttribute(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE, myPackagePrefix); } } diff --git a/platform/usageView/src/com/intellij/usages/UsageViewManager.java b/platform/usageView/src/com/intellij/usages/UsageViewManager.java index d0760ae753e4..be70edebfe09 100644 --- a/platform/usageView/src/com/intellij/usages/UsageViewManager.java +++ b/platform/usageView/src/com/intellij/usages/UsageViewManager.java @@ -18,7 +18,6 @@ package com.intellij.usages; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Factory; @@ -46,27 +45,27 @@ public abstract class UsageViewManager { @Nullable ("in case no usages found or usage view not shown for one usage") public abstract UsageView searchAndShowUsages(@NotNull UsageTarget[] searchFor, - @NotNull Factory searcherFactory, - boolean showPanelIfOnlyOneUsage, - boolean showNotFoundMessage, - @NotNull UsageViewPresentation presentation, - UsageViewStateListener listener); + @NotNull Factory searcherFactory, + boolean showPanelIfOnlyOneUsage, + boolean showNotFoundMessage, + @NotNull UsageViewPresentation presentation, + @Nullable UsageViewStateListener listener); public interface UsageViewStateListener { - void usageViewCreated(UsageView usageView); - void findingUsagesFinished(final UsageView usageView); + void usageViewCreated(@NotNull UsageView usageView); + void findingUsagesFinished(@NotNull UsageView usageView); } public abstract void searchAndShowUsages(@NotNull UsageTarget[] searchFor, - @NotNull Factory searcherFactory, - @NotNull FindUsagesProcessPresentation processPresentation, - @NotNull UsageViewPresentation presentation, - UsageViewStateListener listener); + @NotNull Factory searcherFactory, + @NotNull FindUsagesProcessPresentation processPresentation, + @NotNull UsageViewPresentation presentation, + @Nullable UsageViewStateListener listener); @Nullable public abstract UsageView getSelectedUsageView(); - public static boolean isSelfUsage(final Usage usage, final UsageTarget[] searchForTarget) { + public static boolean isSelfUsage(@NotNull final Usage usage, @NotNull final UsageTarget[] searchForTarget) { if (!(usage instanceof PsiElementUsage)) return false; return ApplicationManager.getApplication().runReadAction(new Computable() { @Override @@ -86,7 +85,7 @@ public abstract class UsageViewManager { }); } - public static boolean isSelfUsage(PsiElement element, PsiElement psiElement) { + private static boolean isSelfUsage(@NotNull PsiElement element, PsiElement psiElement) { return element.getParent() == psiElement; // self usage might be configurable } } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java index b0030c38e186..76eb85231743 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -15,14 +15,17 @@ */ package com.intellij.usages.impl; +import com.intellij.find.FindManager; import com.intellij.find.SearchInBackgroundOption; import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -40,6 +43,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.ui.HyperlinkAdapter; import com.intellij.ui.content.Content; import com.intellij.usageView.UsageViewBundle; import com.intellij.usages.*; @@ -49,11 +53,12 @@ import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; import com.intellij.util.ui.RangeBlinker; import com.intellij.util.ui.UIUtil; -import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; @@ -70,14 +75,16 @@ public class UsageViewManagerImpl extends UsageViewManager { private final Project myProject; private static final Key USAGE_VIEW_KEY = Key.create("USAGE_VIEW"); - - public UsageViewManagerImpl(Project project) { + public UsageViewManagerImpl(@NotNull Project project) { myProject = project; } @Override @NotNull - public UsageView createUsageView(@NotNull UsageTarget[] targets, @NotNull Usage[] usages, @NotNull UsageViewPresentation presentation, Factory usageSearcherFactory) { + public UsageView createUsageView(@NotNull UsageTarget[] targets, + @NotNull Usage[] usages, + @NotNull UsageViewPresentation presentation, + Factory usageSearcherFactory) { UsageViewImpl usageView = new UsageViewImpl(myProject, presentation, targets, usageSearcherFactory); appendUsages(usages, usageView); usageView.setSearchInProgress(false); @@ -86,7 +93,10 @@ public class UsageViewManagerImpl extends UsageViewManager { @Override @NotNull - public UsageView showUsages(@NotNull UsageTarget[] searchedFor, @NotNull Usage[] foundUsages, @NotNull UsageViewPresentation presentation, Factory factory) { + public UsageView showUsages(@NotNull UsageTarget[] searchedFor, + @NotNull Usage[] foundUsages, + @NotNull UsageViewPresentation presentation, + Factory factory) { UsageView usageView = createUsageView(searchedFor, foundUsages, presentation, factory); addContent((UsageViewImpl)usageView, presentation); showToolWindow(true); @@ -99,7 +109,7 @@ public class UsageViewManagerImpl extends UsageViewManager { return showUsages(searchedFor, foundUsages, presentation, null); } - private void addContent(UsageViewImpl usageView, UsageViewPresentation presentation) { + private void addContent(@NotNull UsageViewImpl usageView, @NotNull UsageViewPresentation presentation) { Content content = com.intellij.usageView.UsageViewManager.getInstance(myProject).addContent( presentation.getTabText(), presentation.getTabName(), @@ -117,8 +127,9 @@ public class UsageViewManagerImpl extends UsageViewManager { public UsageView searchAndShowUsages(@NotNull final UsageTarget[] searchFor, @NotNull final Factory searcherFactory, final boolean showPanelIfOnlyOneUsage, - final boolean showNotFoundMessage, @NotNull final UsageViewPresentation presentation, - final UsageViewStateListener listener) { + final boolean showNotFoundMessage, + @NotNull final UsageViewPresentation presentation, + @Nullable final UsageViewStateListener listener) { final AtomicReference usageView = new AtomicReference(); final FindUsagesProcessPresentation processPresentation = new FindUsagesProcessPresentation(); @@ -152,8 +163,7 @@ public class UsageViewManagerImpl extends UsageViewManager { @NotNull Factory searcherFactory, @NotNull FindUsagesProcessPresentation processPresentation, @NotNull UsageViewPresentation presentation, - UsageViewStateListener listener - ) { + @Nullable UsageViewStateListener listener) { final AtomicReference usageView = new AtomicReference(); final SearchForUsagesRunnable runnable = new SearchForUsagesRunnable(usageView, presentation, searchFor, searcherFactory, processPresentation, listener); final Factory progressIndicatorFactory = processPresentation.getProgressIndicatorFactory(); @@ -192,7 +202,8 @@ public class UsageViewManagerImpl extends UsageViewManager { return null; } - public static String getProgressTitle(UsageViewPresentation presentation) { + @NotNull + public static String getProgressTitle(@NotNull UsageViewPresentation presentation) { final String scopeText = presentation.getScopeText(); if (scopeText == null) { return UsageViewBundle.message("progress.searching.for", StringUtil.capitalize(presentation.getUsagesString())); @@ -208,7 +219,7 @@ public class UsageViewManagerImpl extends UsageViewManager { } } - private static void appendUsages(@NotNull final Usage[] foundUsages, final UsageViewImpl usageView) { + private static void appendUsages(@NotNull final Usage[] foundUsages, @NotNull final UsageViewImpl usageView) { ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { @@ -221,7 +232,7 @@ public class UsageViewManagerImpl extends UsageViewManager { public void showTooManyUsagesWarning(final ProgressIndicator indicator, - final CountDownLatch waitWhileUserClick, + @NotNull final CountDownLatch waitWhileUserClick, final int usageCount, final UsageViewImpl usageView) { UIUtil.invokeLaterIfNeeded(new Runnable() { @@ -250,12 +261,12 @@ public class UsageViewManagerImpl extends UsageViewManager { private final UsageViewStateListener myListener; private volatile boolean mySearchHasBeenCancelled; - private SearchForUsagesRunnable(@NotNull final AtomicReference usageView, - @NotNull final UsageViewPresentation presentation, - @NotNull final UsageTarget[] searchFor, - @NotNull final Factory searcherFactory, + private SearchForUsagesRunnable(@NotNull AtomicReference usageView, + @NotNull UsageViewPresentation presentation, + @NotNull UsageTarget[] searchFor, + @NotNull Factory searcherFactory, @NotNull FindUsagesProcessPresentation processPresentation, - final UsageViewStateListener listener) { + @Nullable UsageViewStateListener listener) { myUsageViewRef = usageView; myPresentation = presentation; mySearchFor = searchFor; @@ -286,12 +297,12 @@ public class UsageViewManagerImpl extends UsageViewManager { return null; } - private void openView(final UsageViewImpl usageView) { + private void openView(@NotNull final UsageViewImpl usageView) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { addContent(usageView, myPresentation); - if (myListener!=null) { + if (myListener != null) { myListener.usageViewCreated(usageView); } showToolWindow(false); @@ -301,11 +312,9 @@ public class UsageViewManagerImpl extends UsageViewManager { @Override public void run() { - //long start = System.currentTimeMillis(); AtomicBoolean findUsagesStartedShown = new AtomicBoolean(); searchUsages(findUsagesStartedShown); endSearchForUsages(findUsagesStartedShown); - //System.out.println("Usage search took " + (System.currentTimeMillis() - start)); } private void searchUsages(@NotNull final AtomicBoolean findStartedBalloonShown) { @@ -401,8 +410,8 @@ public class UsageViewManagerImpl extends UsageViewManager { if (notFoundActions == null || notFoundActions.isEmpty()) { ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.FIND, MessageType.INFO, - XmlStringUtil.escapeString(message), - AllIcons.Actions.Find, null); + ""+message+".
" + createOptionsHtml() + "", + AllIcons.Actions.Find, createGotToOptionsListener(mySearchFor)); findStartedBalloonShown.set(false); } else { @@ -434,6 +443,9 @@ public class UsageViewManagerImpl extends UsageViewManager { usage.navigate(true); flashUsageScriptaculously(usage); } + ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.FIND, MessageType.INFO, + "Only one usage found.
" + createOptionsHtml() + "", + AllIcons.Actions.Find, createGotToOptionsListener(mySearchFor)); } }, ModalityState.NON_MODAL, myProject.getDisposed()); } @@ -473,7 +485,27 @@ public class UsageViewManagerImpl extends UsageViewManager { } } - private static void flashUsageScriptaculously(final Usage usage) { + @NotNull + private HyperlinkListener createGotToOptionsListener(@NotNull final UsageTarget[] targets) { + return new HyperlinkAdapter() { + @Override + protected void hyperlinkActivated(HyperlinkEvent e) { + FindManager.getInstance(myProject).showSettingsAndFindUsages(targets); + } + }; + } + + @NotNull + private static String createOptionsHtml() { + String shortcutText = ""; + KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(); + if (shortcut != null) { + shortcutText = " (" + KeymapUtil.getShortcutText(shortcut) + ")"; + } + return "
Find Options..." + shortcutText; + } + + private static void flashUsageScriptaculously(@NotNull final Usage usage) { if (!(usage instanceof UsageInfo2UsageAdapter)) { return; } @@ -490,5 +522,4 @@ public class UsageViewManagerImpl extends UsageViewManager { rangeBlinker.resetMarkers(segments); rangeBlinker.startBlinking(); } - } diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index b063d0f8bee6..2b65e19a769d 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -353,7 +353,7 @@ string.concatenation.ignore.system.err.option=Ignore for 'System.err.print' argu string.concatenation.ignore.assert.option=Ignore for assert statement arguments string.concatenation.ignore.exceptions.option=Ignore for throwable arguments string.concatenation.ignore.constant.initializers.option=Ignore for initializers of constants -ignore.in.test.code=Ignore in test code +ignore.in.test.code=Ignore in &test code ignore.in.annotations=Ignore in annotations string.equalsignorecase.call.display.name=Call to 'String.equalsIgnoreCase()' string.equalsignorecase.call.problem.descriptor=String.#ref() using internationalized strings #loc diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsBetweenInconvertibleTypesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsBetweenInconvertibleTypesInspection.java index 334812bf1a13..7a5731e5b11b 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsBetweenInconvertibleTypesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsBetweenInconvertibleTypesInspection.java @@ -81,8 +81,11 @@ public class EqualsBetweenInconvertibleTypesInspection if (comparisonType == null) { return; } - if (TypeConversionUtil.areTypesConvertible(TypeConversionUtil.erasure(comparedType), - TypeConversionUtil.erasure(comparisonType))) { + final PsiType comparedTypeErasure = TypeConversionUtil.erasure(comparedType); + final PsiType comparisonTypeErasure = TypeConversionUtil.erasure(comparisonType); + if (comparedTypeErasure == null || + comparisonTypeErasure == null || + TypeConversionUtil.areTypesConvertible(comparedTypeErasure, comparisonTypeErasure)) { return; } registerMethodCallError(expression, comparedType, comparisonType); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java index d0ba3d983ce5..6d2fe1ba3c48 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,31 +16,36 @@ package com.siyeh.ig.imports; import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.OrderedSet; +import com.intellij.util.ui.CheckBox; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.StringUtils; +import com.siyeh.ig.psiutils.TestUtils; +import com.siyeh.ig.ui.UiUtils; import org.jetbrains.annotations.NotNull; -import javax.swing.JComponent; -import java.util.ArrayList; -import java.util.HashMap; +import javax.swing.*; +import java.awt.*; +import java.util.*; import java.util.List; -import java.util.Map; public class StaticImportInspection extends BaseInspection { - @SuppressWarnings({"PublicField"}) - public boolean ignoreSingleFieldImports = false; - @SuppressWarnings({"PublicField"}) - public boolean ignoreSingeMethodImports = false; + @SuppressWarnings({"PublicField"}) public boolean ignoreSingleFieldImports = false; + + @SuppressWarnings({"PublicField"}) public boolean ignoreSingeMethodImports = false; + + @SuppressWarnings("PublicField") public boolean ignoreInTestCode = false; + + @SuppressWarnings("PublicField") public OrderedSet allowedClasses = new OrderedSet(); @Override @NotNull @@ -57,20 +62,32 @@ public class StaticImportInspection extends BaseInspection { @Override public JComponent createOptionsPanel() { - final MultipleCheckboxOptionsPanel panel = - new MultipleCheckboxOptionsPanel(this); - panel.addCheckbox(InspectionGadgetsBundle.message( - "ignore.single.field.static.imports.option"), - "ignoreSingleFieldImports"); - panel.addCheckbox(InspectionGadgetsBundle.message( - "ignore.single.method.static.imports.option"), - "ignoreSingeMethodImports"); - return panel; - } + final JComponent panel = new JPanel(new GridBagLayout()); + final GridBagConstraints constraints = new GridBagConstraints(); + constraints.gridx = 0; + constraints.gridy = 0; + constraints.weightx = 1.0; + constraints.weighty = 1.0; + constraints.fill = GridBagConstraints.BOTH; + final JPanel chooserList = + UiUtils.createTreeClassChooserList(allowedClasses, "Statically importable Classes", "Choose statically importable class"); + panel.add(chooserList, constraints); - @Override - public BaseInspectionVisitor buildVisitor() { - return new StaticImportVisitor(); + constraints.gridy = 1; + constraints.weighty = 0.0; + final CheckBox checkBox1 = + new CheckBox(InspectionGadgetsBundle.message("ignore.single.field.static.imports.option"), this, "ignoreSingleFieldImports"); + panel.add(checkBox1, constraints); + + constraints.gridy = 2; + final CheckBox checkBox2 = + new CheckBox(InspectionGadgetsBundle.message("ignore.single.method.static.imports.option"), this, "ignoreSingeMethodImports"); + panel.add(checkBox2, constraints); + + constraints.gridy = 3; + final CheckBox checkBox3 = new CheckBox(InspectionGadgetsBundle.message("ignore.in.test.code"), this, "ignoreInTestCode"); + panel.add(checkBox3, constraints); + return panel; } @Override @@ -80,38 +97,29 @@ public class StaticImportInspection extends BaseInspection { private static class StaticImportFix extends InspectionGadgetsFix { + @Override @NotNull public String getName() { - return InspectionGadgetsBundle.message( - "static.import.replace.quickfix"); + return InspectionGadgetsBundle.message("static.import.replace.quickfix"); } @Override - public void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { - final PsiImportStaticStatement importStatement = - (PsiImportStaticStatement)descriptor.getPsiElement(); - final PsiJavaCodeReferenceElement importReference = - importStatement.getImportReference(); + public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { + final PsiImportStaticStatement importStatement = (PsiImportStaticStatement)descriptor.getPsiElement(); + final PsiJavaCodeReferenceElement importReference = importStatement.getImportReference(); if (importReference == null) { return; } - final JavaResolveResult[] importTargets = - importReference.multiResolve(false); + final JavaResolveResult[] importTargets = importReference.multiResolve(false); if (importTargets.length == 0) { return; } final boolean onDemand = importStatement.isOnDemand(); - final StaticImportReferenceCollector referenceCollector = - new StaticImportReferenceCollector(importTargets, - onDemand); - final PsiJavaFile file = - (PsiJavaFile)importStatement.getContainingFile(); + final StaticImportReferenceCollector referenceCollector = new StaticImportReferenceCollector(importTargets, onDemand); + final PsiJavaFile file = (PsiJavaFile)importStatement.getContainingFile(); file.accept(referenceCollector); - final List references = - referenceCollector.getReferences(); - final Map - referenceTargetMap = new HashMap(); + final List references = referenceCollector.getReferences(); + final Map referenceTargetMap = new HashMap(); for (PsiJavaCodeReferenceElement reference : references) { final PsiElement target = reference.resolve(); if (target instanceof PsiMember) { @@ -120,18 +128,15 @@ public class StaticImportInspection extends BaseInspection { } } importStatement.delete(); - for (Map.Entry entry : - referenceTargetMap.entrySet()) { + for (Map.Entry entry : referenceTargetMap.entrySet()) { removeReference(entry.getKey(), entry.getValue()); } } - private static void removeReference( - PsiJavaCodeReferenceElement reference, PsiMember target) { + private static void removeReference(PsiJavaCodeReferenceElement reference, PsiMember target) { final PsiManager manager = reference.getManager(); final Project project = manager.getProject(); - final JavaPsiFacade psiFacade = - JavaPsiFacade.getInstance(project); + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiElementFactory factory = psiFacade.getElementFactory(); final PsiClass aClass = target.getContainingClass(); final String qualifiedName = aClass.getQualifiedName(); @@ -139,9 +144,7 @@ public class StaticImportInspection extends BaseInspection { final String referenceText = qualifiedName + '.' + text; if (reference instanceof PsiReferenceExpression) { try { - final PsiExpression newReference = - factory.createExpressionFromText( - referenceText, reference); + final PsiExpression newReference = factory.createExpressionFromText(referenceText, reference); reference.replace(newReference); } catch (IncorrectOperationException e) { @@ -150,8 +153,7 @@ public class StaticImportInspection extends BaseInspection { } else { final PsiJavaCodeReferenceElement referenceElement = - factory.createReferenceElementByFQClassName( - referenceText, reference.getResolveScope()); + factory.createReferenceElementByFQClassName(referenceText, reference.getResolveScope()); try { reference.replace(referenceElement); } @@ -161,24 +163,19 @@ public class StaticImportInspection extends BaseInspection { } } - static class StaticImportReferenceCollector - extends JavaRecursiveElementVisitor { + static class StaticImportReferenceCollector extends JavaRecursiveElementVisitor { private final JavaResolveResult[] importTargets; private final boolean onDemand; - private final List references = - new ArrayList(); + private final List references = new ArrayList(); - StaticImportReferenceCollector( - @NotNull JavaResolveResult[] importTargets, - boolean onDemand) { + StaticImportReferenceCollector(@NotNull JavaResolveResult[] importTargets, boolean onDemand) { this.importTargets = importTargets; this.onDemand = onDemand; } @Override - public void visitReferenceElement( - PsiJavaCodeReferenceElement reference) { + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); if (isFullyQualifiedReference(reference)) { return; @@ -196,15 +193,12 @@ public class StaticImportInspection extends BaseInspection { checkStaticImportReference(reference); } - private void checkStaticImportReference( - PsiJavaCodeReferenceElement reference) { + private void checkStaticImportReference(PsiJavaCodeReferenceElement reference) { if (reference.isQualified()) { return; } final PsiElement target = reference.resolve(); - if (!(target instanceof PsiMethod) && - !(target instanceof PsiClass) && - !(target instanceof PsiField)) { + if (!(target instanceof PsiMethod) && !(target instanceof PsiClass) && !(target instanceof PsiField)) { return; } final PsiMember member = (PsiMember)target; @@ -217,11 +211,8 @@ public class StaticImportInspection extends BaseInspection { } else if (targetElement instanceof PsiClass) { if (onDemand) { - final PsiClass containingClass = - member.getContainingClass(); - if (InheritanceUtil.isInheritorOrSelf( - (PsiClass)targetElement, containingClass, - true)) { + final PsiClass containingClass = member.getContainingClass(); + if (InheritanceUtil.isInheritorOrSelf((PsiClass)targetElement, containingClass, true)) { addReference(reference); } } @@ -242,8 +233,7 @@ public class StaticImportInspection extends BaseInspection { return references; } - public static boolean isFullyQualifiedReference( - PsiJavaCodeReferenceElement reference) { + public static boolean isFullyQualifiedReference(PsiJavaCodeReferenceElement reference) { if (!reference.isQualified()) { return false; } @@ -253,9 +243,8 @@ public class StaticImportInspection extends BaseInspection { directParent instanceof PsiVariable) { return false; } - final PsiElement parent = PsiTreeUtil.getParentOfType(reference, - PsiImportStatementBase.class, PsiPackageStatement.class, - JavaCodeFragment.class); + final PsiElement parent = + PsiTreeUtil.getParentOfType(reference, PsiImportStatementBase.class, PsiPackageStatement.class, JavaCodeFragment.class); if (parent != null) { return false; } @@ -275,19 +264,21 @@ public class StaticImportInspection extends BaseInspection { } } + @Override + public BaseInspectionVisitor buildVisitor() { + return new StaticImportVisitor(); + } + private class StaticImportVisitor extends BaseInspectionVisitor { @Override public void visitClass(@NotNull PsiClass aClass) { - // no call to super, so it doesn't drill down - if (!(aClass.getParent() instanceof PsiJavaFile)) { + final PsiElement parent = aClass.getParent(); + if (!(parent instanceof PsiJavaFile)) { return; } - if (JspPsiUtil.isInJspFile(aClass.getContainingFile())) { - return; - } - final PsiJavaFile file = (PsiJavaFile)aClass.getParent(); - if (file == null) { + final PsiJavaFile file = (PsiJavaFile)parent; + if (JspPsiUtil.isInJspFile(file)) { return; } if (!file.getClasses()[0].equals(aClass)) { @@ -297,8 +288,10 @@ public class StaticImportInspection extends BaseInspection { if (importList == null) { return; } - final PsiImportStaticStatement[] importStatements = - importList.getImportStaticStatements(); + if (ignoreInTestCode && TestUtils.isTest(aClass)) { + return; + } + final PsiImportStaticStatement[] importStatements = importList.getImportStaticStatements(); for (PsiImportStaticStatement importStatement : importStatements) { if (shouldReportImportStatement(importStatement)) { registerError(importStatement); @@ -306,24 +299,46 @@ public class StaticImportInspection extends BaseInspection { } } - private boolean shouldReportImportStatement( - PsiImportStatementBase importStatement) { - if (importStatement.isOnDemand()) { - return true; - } - final PsiReference importReference = - importStatement.getImportReference(); + private boolean shouldReportImportStatement(PsiImportStaticStatement importStatement) { + final PsiJavaCodeReferenceElement importReference = importStatement.getImportReference(); if (importReference == null) { return false; } + PsiClass targetClass = importStatement.resolveTargetClass(); + boolean checked = false; + while (targetClass != null) { + final String qualifiedName = targetClass.getQualifiedName(); + if (allowedClasses.contains(qualifiedName)) { + return false; + } + if (checked) { + break; + } + targetClass = targetClass.getContainingClass(); + checked = true; + } + if (importStatement.isOnDemand()) { + return true; + } if (ignoreSingleFieldImports || ignoreSingeMethodImports) { - final PsiElement target = importReference.resolve(); - if (target instanceof PsiField) { + boolean field = false; + boolean method = false; + // in the presence of method overloading the plain resolve() method returns null + final JavaResolveResult[] results = importReference.multiResolve(false); + for (JavaResolveResult result : results) { + final PsiElement element = result.getElement(); + if (element instanceof PsiField) { + field = true; + } else if (element instanceof PsiMethod) { + method = true; + } + } + if (field && !method) { if (ignoreSingleFieldImports) { return false; } } - else { + else if (method && !field) { if (ignoreSingeMethodImports) { return false; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import/Simple.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import/Simple.java new file mode 100644 index 000000000000..afeb17a2ef65 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import/Simple.java @@ -0,0 +1,12 @@ +package com.siyeh.igtest.imports.static_import; + +import static java.lang.Math.sin; +import static java.util.Map.Entry; + +class Simple { + + void f00() { + sin(1.0); + Entry entry; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import/expected.xml new file mode 100644 index 000000000000..48b2420e6605 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import/expected.xml @@ -0,0 +1,9 @@ + + + + Simple.java + 3 + Static import + Static import <code>import static java.lang.Math.*;</code> #loc + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import_method_allowed/Simple.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import_method_allowed/Simple.java new file mode 100644 index 000000000000..2735ece87277 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import_method_allowed/Simple.java @@ -0,0 +1,10 @@ +package com.siyeh.igtest.imports.static_import_method_allowed; + +import static java.lang.Math.abs; + +class Simple { + + void f0o() { + abs(1.0); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import_method_allowed/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import_method_allowed/expected.xml new file mode 100644 index 000000000000..e8f00e82629f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/imports/static_import_method_allowed/expected.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/StaticImportInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/StaticImportInspectionTest.java new file mode 100644 index 000000000000..91b66792d02c --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/imports/StaticImportInspectionTest.java @@ -0,0 +1,18 @@ +package com.siyeh.ig.imports; + +import com.siyeh.ig.IGInspectionTestCase; + +public class StaticImportInspectionTest extends IGInspectionTestCase { + + public void test() throws Exception { + final StaticImportInspection tool = new StaticImportInspection(); + tool.allowedClasses.add("java.util.Map"); + doTest("com/siyeh/igtest/imports/static_import", tool); + } + + public void testMethodAllowed() { + final StaticImportInspection tool = new StaticImportInspection(); + tool.ignoreSingeMethodImports = true; + doTest("com/siyeh/igtest/imports/static_import_method_allowed", tool); + } +} \ No newline at end of file diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java index a1a2eae0c561..0cf75632b609 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java @@ -27,7 +27,7 @@ import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.JpsSimpleElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; -import org.jetbrains.jps.model.serialization.JpsSdkPropertiesSerializer; +import org.jetbrains.jps.model.serialization.library.JpsSdkPropertiesSerializer; import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer; import java.util.Arrays; diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java index d96622392322..213323fd480e 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidAptCompiler.java @@ -131,6 +131,7 @@ public class AndroidAptCompiler implements SourceGeneratingCompiler { // we use copyDir instead of moveDirWithContent here, because tmp directory may be located on other disk and // moveDirWithContent doesn't work for such case FileUtil.copyDir(tmpOutputDir, genRootDir); + AndroidCompileUtil.markDirty(outputRootDirectory, true); } results.add(aptItem); } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java index 20a79be60a6c..36142482cfb7 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidBuildConfigGeneratingCompiler.java @@ -113,7 +113,7 @@ public class AndroidBuildConfigGeneratingCompiler implements SourceGeneratingCom } if (result.size() > 0) { - outputRootDirectory.refresh(false, true); + AndroidCompileUtil.markDirtyAndRefresh(outputRootDirectory, true); } return result.toArray(new GenerationItem[result.size()]); } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java index 79c21de7a9ca..f11134d4e9a0 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidCompileUtil.java @@ -42,6 +42,7 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactProperties; import com.intellij.packaging.impl.compiler.ArtifactCompileScope; @@ -887,4 +888,22 @@ public class AndroidCompileUtil { public static void reportException(@NotNull CompileContext context, @NotNull String messagePrefix, @NotNull Exception e) { context.addMessage(CompilerMessageCategory.ERROR, messagePrefix + e.getClass().getSimpleName() + ": " + e.getMessage(), null, -1, -1); } + + public static void markDirtyAndRefresh(VirtualFile f, boolean recursively) { + markDirty(f, recursively); + f.refresh(false, recursively); + } + + public static void markDirty(VirtualFile f, boolean recursively) { + if (f instanceof NewVirtualFile) { + final NewVirtualFile newF = (NewVirtualFile)f; + + if (recursively) { + newF.markDirtyRecursively(); + } + else { + newF.markDirty(); + } + } + } } \ No newline at end of file diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidExternalApklibExtractingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidExternalApklibExtractingCompiler.java index dbaa2e9cda46..31a11780f8cb 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidExternalApklibExtractingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidExternalApklibExtractingCompiler.java @@ -108,7 +108,7 @@ public class AndroidExternalApklibExtractingCompiler implements SourceGenerating final VirtualFile vSrcRoot = LocalFileSystem.getInstance().findFileByIoFile(srcRoot); if (vSrcRoot != null) { - vSrcRoot.getParent().refresh(false, true); + AndroidCompileUtil.markDirtyAndRefresh(vSrcRoot, true); AndroidUtils.collectFiles(vSrcRoot, visited, generatedVFiles); } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java index 072bce300872..045ed5492c9f 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidIdlCompiler.java @@ -233,7 +233,7 @@ public class AndroidIdlCompiler implements SourceGeneratingCompiler { } if (toRefresh) { - outputRootDirectory.refresh(false, true); + AndroidCompileUtil.markDirtyAndRefresh(outputRootDirectory, true); } return results.toArray(new GenerationItem[results.size()]); } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java index ac9d297ef759..6b5fec166335 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidIncludingCompiler.java @@ -187,7 +187,7 @@ public class AndroidIncludingCompiler implements SourceGeneratingCompiler { } if (toRefresh) { - outputRootDirectory.refresh(false, true); + AndroidCompileUtil.markDirtyAndRefresh(outputRootDirectory, true); } return result.toArray(new GenerationItem[result.size()]); } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java index a31f6172d142..3dd46f20a332 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidMavenResourcesCompiler.java @@ -15,7 +15,6 @@ */ package org.jetbrains.android.compiler; -import com.intellij.compiler.impl.CompilerUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.*; import com.intellij.openapi.compiler.ex.CompileContextEx; @@ -77,10 +76,10 @@ public class AndroidMavenResourcesCompiler implements SourceGeneratingCompiler { for (GenerationItem item : generationItems) { File generatedFile = ((MyGenerationItem)item).myGeneratedFile; if (generatedFile != null) { - CompilerUtil.refreshIOFile(generatedFile); - VirtualFile generatedVFile = LocalFileSystem.getInstance().findFileByIoFile(generatedFile); - if (generatedVFile != null) { - generatedVFiles.add(generatedVFile); + final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(generatedFile); + if (vFile != null) { + AndroidCompileUtil.markDirtyAndRefresh(vFile, false); + generatedVFiles.add(vFile); } } } diff --git a/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java b/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java index b554fa8de67f..77a8c43d8f34 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java +++ b/plugins/android/src/org/jetbrains/android/compiler/AndroidRenderscriptCompiler.java @@ -197,6 +197,7 @@ public class AndroidRenderscriptCompiler implements SourceGeneratingCompiler { .execute(genItem.mySdkLocation, genItem.myAndroidTarget, sourceFile.getPath(), genRootPath, depFolderOsPath, genItem.myRawDirPath)); + AndroidCompileUtil.markDirty(outputRootDirectory, true); ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { diff --git a/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/impl/JpsDevKitModelSerializerExtension.java b/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/impl/JpsDevKitModelSerializerExtension.java index 5fde08b32ede..0dd76f7f2491 100644 --- a/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/impl/JpsDevKitModelSerializerExtension.java +++ b/plugins/devkit/jps-plugin/src/org/jetbrains/jps/devkit/model/impl/JpsDevKitModelSerializerExtension.java @@ -26,8 +26,8 @@ import org.jetbrains.jps.devkit.model.JpsPluginModuleType; import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.JpsSimpleElement; import org.jetbrains.jps.model.serialization.*; -import org.jetbrains.jps.model.serialization.JpsModulePropertiesSerializer; -import org.jetbrains.jps.model.serialization.JpsSdkPropertiesSerializer; +import org.jetbrains.jps.model.serialization.module.JpsModulePropertiesSerializer; +import org.jetbrains.jps.model.serialization.library.JpsSdkPropertiesSerializer; import java.util.Arrays; import java.util.List; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java index 27017bd04095..e2204e3f9047 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/ArgumentInstruction.java @@ -16,8 +16,8 @@ package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; @@ -30,8 +30,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.MixinTypeInstruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction; -import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; -import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import static org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil.createSignature; @@ -48,41 +46,100 @@ public class ArgumentInstruction extends InstructionImpl implements MixinTypeIns @Nullable public PsiType inferMixinType() { PsiElement element = getElement(); - LOG.assertTrue(element instanceof GrReferenceExpression); + GrCall call = findCall(element); + GrExpression[] arguments = call.getExpressionArguments(); + boolean hasNamed = call.getNamedArguments().length > 0; + GroovyResolveResult[] variants = getCallVariantsWithoutUsingArgumentTypes(call, arguments); + if (variants.length == 0) return null; + + int index = ArrayUtil.indexOf(arguments, element) + (hasNamed ? 1 : 0); + return findParameterTypeIfSameInAllOverloads(hasNamed, variants, index); + } + + @Nullable + private static PsiType findParameterTypeIfSameInAllOverloads(boolean hasNamed, GroovyResolveResult[] variants, int index) { + PsiType result = findParameterTypeUnambiguously(index, hasNamed, variants[0]); + if (result == null) return null; + + for (int i = 1; i < variants.length; i++) { + GroovyResolveResult variant = variants[i]; + if (!result.equals(findParameterTypeUnambiguously(index, hasNamed, variant))) { + return null; + } + } + return result; + } + + private static GroovyResolveResult[] getCallVariantsWithoutUsingArgumentTypes(GrCall call, GrExpression[] arguments) { + // we should be careful so that resolve doesn't use the type of the arguments at all, + // as we're right now calculating at least one of them + GrExpression firstArg = arguments.length == 0 ? null : arguments[0]; + return call.getCallVariants(firstArg); + } + + private static GrCall findCall(PsiElement element) { PsiElement parent = element.getParent().getParent(); LOG.assertTrue(parent instanceof GrCall, "elemText: " + element.getText() + "\nParent = " + (element.getParent() == null ? "null" : element.getParent().getClass()) + "\nPParent" + (parent == null ? "null" : parent.getClass())); - GrCall call = (GrCall)parent; - - int index = ArrayUtil.indexOf(call.getExpressionArguments(), element); - if (call.getNamedArguments().length > 0) index++; - - GroovyResolveResult[] variants = call.getCallVariants((GrReferenceExpression)element); - - PsiType result = null; - for (GroovyResolveResult variant : variants) { - GrClosureSignature signature = createSignature(variant); - if (signature == null) continue; - - if (GrClosureSignatureUtil.mapParametersToArguments(signature, call) != null && !haveNullParameters(call)) { - return null; - } - GrClosureParameter[] parameters = signature.getParameters(); - if (index >= parameters.length) continue; - - result = TypesUtil.getLeastUpperBoundNullable(result, parameters[index].getType(), element.getManager()); - } - return result; + return (GrCall)parent; } - private static boolean haveNullParameters(GrCall call) { - for (GrExpression argument : call.getExpressionArguments()) { - if (argument.getType() == null) return true; + @Nullable + private static PsiType findParameterTypeUnambiguously(int index, boolean hasNamed, GroovyResolveResult variant) { + GrClosureSignature signature = createSignature(variant); + if (signature == null || signature.getParameterCount() <= index) return null; + + GrClosureParameter[] parameters = signature.getParameters(); + if (hasNamed && !InheritanceUtil.isInheritor(parameters[0].getType(), CommonClassNames.JAVA_UTIL_MAP)) return null; + + for (int i = 0; i <= index; i++) { + if (parameters[i].isOptional()) { + return null; + } } - return false; + + PsiType result = parameters[index].getType(); + return result == null || dependsOnTypeParameters(result) ? null : result; + } + + private static Boolean dependsOnTypeParameters(PsiType result) { + return result.accept(new PsiTypeVisitor() { + @Nullable + @Override + public Boolean visitClassType(PsiClassType classType) { + if (classType.resolve() instanceof PsiTypeParameter) { + return true; + } + for (PsiType type : classType.getParameters()) { + if (type.accept(this)) { + return true; + } + } + return false; + } + + @Nullable + @Override + public Boolean visitArrayType(PsiArrayType arrayType) { + return arrayType.getComponentType().accept(this); + } + + @Nullable + @Override + public Boolean visitWildcardType(PsiWildcardType wildcardType) { + PsiType bound = wildcardType.getBound(); + return bound != null && bound.accept(this); + } + + @Nullable + @Override + public Boolean visitType(PsiType type) { + return false; + } + }); } @Override @@ -97,6 +154,7 @@ public class ArgumentInstruction extends InstructionImpl implements MixinTypeIns } public String getVariableName() { + //noinspection ConstantConditions return ((GrReferenceExpression)getElement()).getReferenceName(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java index f464607d90e3..395096870023 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java @@ -35,7 +35,7 @@ public class InstructionImpl implements Instruction { private final LinkedHashSet mySuccessors = new LinkedHashSet(1); private LinkedHashSet myNegations; - PsiElement myPsiElement; + protected final PsiElement myPsiElement; private int myNumber = -1; @Nullable diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAType.java index 6f041bead9b2..e625314ffe14 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAType.java @@ -115,7 +115,7 @@ public class DFAType { } @Nullable - public PsiType getType() { + public PsiType getResultType() { if (mixins.size() == 0) return primary; List types = new ArrayList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/TypeInferenceHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/TypeInferenceHelper.java index 795ba9ebd61d..fe29c6ad3927 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/TypeInferenceHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/TypeInferenceHelper.java @@ -43,10 +43,7 @@ import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefin import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsSemilattice; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; /** * @author ven @@ -72,9 +69,9 @@ public class TypeInferenceHelper { return getInitializerType(refExpr); } - final DFAType type = getInferredType(refExpr.getReferenceName(), instruction, flow, scope); + final DFAType type = getInferredType(refExpr.getReferenceName(), instruction, flow, scope, new HashSet()); if (type == null) return null; - return type.getType(); + return type.getResultType(); } }); @@ -89,8 +86,8 @@ public class TypeInferenceHelper { Instruction instruction = findInstructionAt(place, flow); if (instruction == null) return null; - final DFAType type = getInferredType(variableName, instruction, flow, scope); - return type != null ? type.getType() : null; + final DFAType type = getInferredType(variableName, instruction, flow, scope, new HashSet()); + return type != null ? type.getResultType() : null; } public static boolean isTooComplexTooAnalyze(GrControlFlowOwner scope) { @@ -135,7 +132,7 @@ public class TypeInferenceHelper { } @Nullable - private static DFAType getInferredType(@NotNull String varName, @NotNull Instruction instruction, @NotNull Instruction[] flow, @NotNull GrControlFlowOwner scope) { + private static DFAType getInferredType(@NotNull String varName, @NotNull Instruction instruction, @NotNull Instruction[] flow, @NotNull GrControlFlowOwner scope, Set trace) { final Pair> pair = getDefUseMaps(scope); List dfaResult = pair.second; @@ -149,7 +146,7 @@ public class TypeInferenceHelper { DFAType result = null; for (int defIndex : varDefs) { - DFAType defType = getDefinitionType(flow[defIndex], flow, scope); + DFAType defType = getDefinitionType(flow[defIndex], flow, scope, trace); if (defType != null) { defType = defType.negate(instruction); @@ -198,7 +195,7 @@ public class TypeInferenceHelper { } @Nullable - private static DFAType getDefinitionType(Instruction instruction, Instruction[] flow, GrControlFlowOwner scope) { + private static DFAType getDefinitionType(Instruction instruction, Instruction[] flow, GrControlFlowOwner scope, Set trace) { if (instruction instanceof ReadWriteVariableInstruction && ((ReadWriteVariableInstruction) instruction).isWrite()) { final PsiElement element = instruction.getElement(); if (element != null) { @@ -206,34 +203,37 @@ public class TypeInferenceHelper { } } if (instruction instanceof MixinTypeInstruction) { - return mixinType((MixinTypeInstruction)instruction, flow, scope); + return mixinType((MixinTypeInstruction)instruction, flow, scope, trace); } return null; } @Nullable - private static DFAType mixinType(final MixinTypeInstruction instruction, final Instruction[] flow, final GrControlFlowOwner scope) { - return RecursionManager.doPreventingRecursion(instruction, false, new NullableComputable() { - @Override - @Nullable - public DFAType compute() { - String varName = instruction.getVariableName(); - if (varName == null) return null; - ReadWriteVariableInstruction originalInstr = instruction.getInstructionToMixin(flow); - if (originalInstr == null) { - LOG.error(scope.getContainingFile().getName() + ":" + scope.getText()); - } + private static DFAType mixinType(final MixinTypeInstruction instruction, final Instruction[] flow, final GrControlFlowOwner scope, Set trace) { + if (!trace.add(instruction)) { + return null; + } - DFAType original = getInferredType(varName, originalInstr, flow, scope); - final PsiType mixin = instruction.inferMixinType(); - if (mixin == null) return original; - if (original == null) { - original = DFAType.create(null); - } - original.addMixin(mixin, instruction.getConditionInstruction()); - return original; - } - }); + String varName = instruction.getVariableName(); + if (varName == null) { + return null; + } + ReadWriteVariableInstruction originalInstr = instruction.getInstructionToMixin(flow); + if (originalInstr == null) { + LOG.error(scope.getContainingFile().getName() + ":" + scope.getText()); + } + + DFAType original = getInferredType(varName, originalInstr, flow, scope, trace); + final PsiType mixin = instruction.inferMixinType(); + if (mixin == null) { + return original; + } + if (original == null) { + original = DFAType.create(null); + } + original.addMixin(mixin, instruction.getConditionInstruction()); + trace.remove(instruction); + return original; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java index 33d7802427ed..0c60f342dd1c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java @@ -49,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticPara import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable; import org.jetbrains.plugins.groovy.lang.resolve.MethodTypeInferencer; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; -import org.jetbrains.plugins.groovy.lang.resolve.processors.PropertyResolverProcessor; import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil; @@ -127,10 +126,6 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock } private boolean processOwner(PsiScopeProcessor processor, ResolveState state) { - if (processor instanceof PropertyResolverProcessor && OWNER_NAME.equals(((PropertyResolverProcessor)processor).getName())) { - processor.handleEvent(ResolveUtil.DECLARATION_SCOPE_PASSED, this); - } - String nameHint = ResolveUtil.getNameHint(processor); if (nameHint == null || nameHint.equals(OWNER_NAME)) { if (!processor.execute(getOwner(), state)) return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java index 19bcfba3d217..704a375d308f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java @@ -156,8 +156,6 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase i if (!ResolveUtil.processElement(processor, parameter, state)) return false; } - processor.handleEvent(ResolveUtil.DECLARATION_SCOPE_PASSED, this); - return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DeclarationCacheKey.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DeclarationCacheKey.java new file mode 100644 index 000000000000..41d88d1e975d --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DeclarationCacheKey.java @@ -0,0 +1,200 @@ +/* + * 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.plugins.groovy.lang.resolve; + +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.ResolveState; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.PairProcessor; +import com.intellij.util.containers.CollectionFactory; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint; +import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.concurrent.ConcurrentMap; + +/** +* @author peter +*/ +class DeclarationCacheKey { + private static final CachedValueProvider>> VALUE_PROVIDER = + new CachedValueProvider>>() { + @Nullable + @Override + public Result>> compute() { + ConcurrentMap> map = ContainerUtil.newConcurrentMap(); + return Result.create(map, PsiModificationTracker.MODIFICATION_COUNT); + } + }; + @Nullable private final String name; + @NotNull private final EnumSet kinds; + private final boolean nonCode; + + DeclarationCacheKey(@Nullable String name, ClassHint hint, boolean nonCode) { + this.name = name; + this.kinds = getResolveKinds(hint); + this.nonCode = nonCode; + } + + private static EnumSet getResolveKinds(ClassHint hint) { + EnumSet set = EnumSet.noneOf(ClassHint.ResolveKind.class); + for (ClassHint.ResolveKind kind : ClassHint.ResolveKind.values()) { + if (hint.shouldProcess(kind)) { + set.add(kind); + } + } + return set; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof DeclarationCacheKey)) { + return false; + } + + DeclarationCacheKey key = (DeclarationCacheKey)o; + + if (nonCode != key.nonCode) { + return false; + } + if (!kinds.equals(key.kinds)) { + return false; + } + if (name != null ? !name.equals(key.name) : key.name != null) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + kinds.hashCode(); + result = 31 * result + (nonCode ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "DeclarationCacheKey{" + + "name='" + name + '\'' + + ", kinds=" + kinds + + ", nonCode=" + nonCode + + '}'; + } + + private List collectDeclarations(final GroovyPsiElement place) { + final ArrayList result = new ArrayList(); + PsiTreeUtil.treeWalkUp(place, null, new PairProcessor() { + @Override + public boolean process(PsiElement scope, PsiElement lastParent) { + result.add(collectScopeDeclarations(scope, lastParent, place)); + return true; + } + }); + return result; + } + + private DeclarationHolder collectScopeDeclarations(PsiElement scope, PsiElement lastParent, GroovyPsiElement place) { + MyCollectProcessor plainCollector = new MyCollectProcessor(scope); + MyCollectProcessor nonCodeCollector = new MyCollectProcessor(scope); + ResolveUtil.doProcessDeclarations(place, lastParent, scope, plainCollector, nonCode ? nonCodeCollector : null); + return new DeclarationHolder(scope, plainCollector.declarations, nonCodeCollector.declarations); + } + + private List getAllDeclarations(GroovyPsiElement place) { + ConcurrentMap> cache = + CachedValuesManager.getManager(place.getProject()).getCachedValue(place, VALUE_PROVIDER); + List declarations = cache.get(this); + if (declarations == null) { + cache.putIfAbsent(this, declarations = collectDeclarations(place)); + } + return declarations; + } + + boolean processCachedDeclarations(GroovyPsiElement place, PsiScopeProcessor processor) { + for (DeclarationHolder holder : getAllDeclarations(place)) { + if (!holder.processCachedDeclarations(processor)) { + return false; + } + } + return true; + } + + private static class DeclarationHolder { + final PsiElement scope; + final List> plainDeclarations; + final List> nonCodeDeclarations; + + private DeclarationHolder(PsiElement scope, + List> plainDeclarations, + List> nonCodeDeclarations) { + this.scope = scope; + this.plainDeclarations = plainDeclarations; + this.nonCodeDeclarations = nonCodeDeclarations; + } + + boolean processCachedDeclarations(PsiScopeProcessor processor) { + PsiScopeProcessor realProcessor = ResolveUtil.substituteProcessor(processor, scope); + for (Pair pair : plainDeclarations) { + if (!realProcessor.execute(pair.first, pair.second)) { + return false; + } + } + for (Pair pair : nonCodeDeclarations) { + if (!processor.execute(pair.first, pair.second)) { + return false; + } + } + + ResolveUtil.issueLevelChangeEvents(processor, scope); + return true; + } + + } + + private class MyCollectProcessor extends ResolverProcessor { + final List> declarations = CollectionFactory.arrayList(); + + public MyCollectProcessor(PsiElement scope) { + super(DeclarationCacheKey.this.name, DeclarationCacheKey.this.kinds, scope, PsiType.EMPTY_ARRAY); + } + + @Override + public boolean execute(@NotNull PsiElement element, ResolveState state) { + declarations.add(Pair.create(element, state)); + return true; + } + } +} + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index 4c2c1bb2f680..8f1cc512f2a1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -25,6 +25,7 @@ import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.NameHint; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.*; +import com.intellij.util.PairProcessor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; @@ -55,6 +55,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousC import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; @@ -86,62 +87,82 @@ public class ResolveUtil { * * @param place - place to start tree walk up * @param processor - * @param processNonCodeMethods - this parameter tells us if we need non code members. But non code members are started to process only after we walk up any code block or script + * @param processNonCodeMethods - this parameter tells us if we need non code members * @return */ - public static boolean treeWalkUp(@NotNull GroovyPsiElement place, PsiScopeProcessor processor, boolean processNonCodeMethods) { - PsiElement lastParent = null; - PsiElement run = place; + public static boolean treeWalkUp(@NotNull final GroovyPsiElement place, final PsiScopeProcessor processor, boolean processNonCodeMethods) { + ClassHint hint = processor.getHint(ClassHint.KEY); + if (hint != null) { + return new DeclarationCacheKey(getNameHint(processor), hint, processNonCodeMethods).processCachedDeclarations(place, processor); + } - final Project project = place.getProject(); - PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); - - boolean doProcessNonCodeMembers = false; - boolean isJavaResolver = false; - while (run != null) { - - //hack for walking up in java code - //java's processDeclarations don't check names so we should do it manually - if (!isJavaResolver && run.getLanguage() != GroovyFileType.GROOVY_LANGUAGE) { - isJavaResolver = true; - if (processor.getHint(NameHint.KEY) != null) { - processor = new JavaResolverProcessor(processor); + final PsiScopeProcessor nonCodeProcessor = processNonCodeMethods ? processor : null; + return PsiTreeUtil.treeWalkUp(place, null, new PairProcessor() { + @Override + public boolean process(PsiElement scope, PsiElement lastParent) { + if (!doProcessDeclarations(place, lastParent, scope, substituteProcessor(processor, scope), nonCodeProcessor)) { + return false; } + issueLevelChangeEvents(processor, scope); + return true; } + }); + } - if (!run.processDeclarations(processor, ResolveState.initial(), lastParent, place)) return false; - if (processNonCodeMethods) { - if (!doProcessNonCodeMembers) { - if (run instanceof GrCodeBlock) doProcessNonCodeMembers = true; - else if (run instanceof GrStatement && run.getContext() instanceof GroovyFile) doProcessNonCodeMembers = true; - } - if (doProcessNonCodeMembers) { - if (run instanceof GrTypeDefinition) { - if (!processNonCodeMembers(factory.createType(((GrTypeDefinition)run)), processor, place, ResolveState.initial())) return false; - } - else if ((run instanceof GroovyFileBase) && ((GroovyFileBase)run).isScript()) { - final PsiClass psiClass = ((GroovyFileBase)run).getScriptClass(); - if (psiClass != null) { - if (!processNonCodeMembers(factory.createType(psiClass), processor, place, ResolveState.initial())) return false; - } - } - else if (run instanceof GrClosableBlock) { - PsiClass superClass = getLiteralSuperClass((GrClosableBlock)run); - if (superClass != null && !superClass.processDeclarations(processor, ResolveState.initial(), null, place)) return false; + static boolean doProcessDeclarations(GroovyPsiElement place, + PsiElement lastParent, + PsiElement scope, + @NotNull PsiScopeProcessor plainProcessor, @Nullable PsiScopeProcessor nonCodeProcessor) { + if (!scope.processDeclarations(plainProcessor, ResolveState.initial(), lastParent, place)) return false; + if (nonCodeProcessor != null && !processScopeNonCodeMethods(place, nonCodeProcessor, scope)) return false; + return true; + } - if (!GdkMethodUtil.categoryIteration((GrClosableBlock)run, processor, ResolveState.initial())) return false; - if (!GdkMethodUtil.withIteration((GrClosableBlock)run, processor)) return false; - } - } - } - lastParent = run; - run = run.getContext(); - processor.handleEvent(JavaScopeProcessorEvent.CHANGE_LEVEL, null); + static void issueLevelChangeEvents(PsiScopeProcessor processor, PsiElement run) { + processor.handleEvent(JavaScopeProcessorEvent.CHANGE_LEVEL, null); + if (run instanceof GrClosableBlock && GrClosableBlock.OWNER_NAME.equals(getNameHint(processor))) { + processor.handleEvent(DECLARATION_SCOPE_PASSED, run); + } + if (run instanceof GrMethod) { + processor.handleEvent(DECLARATION_SCOPE_PASSED, run); + } + } + + static PsiScopeProcessor substituteProcessor(PsiScopeProcessor processor, PsiElement scope) { + //hack for walking up in java code + //java's processDeclarations don't check names so we should do it manually + if (scope.getLanguage() != GroovyFileType.GROOVY_LANGUAGE && processor.getHint(NameHint.KEY) != null) { + return new JavaResolverProcessor(processor); + } + return processor; + } + + static boolean processScopeNonCodeMethods(GroovyPsiElement place, PsiScopeProcessor processor, PsiElement scope) { + if (scope instanceof GrTypeDefinition) { + return processNonCodeMembers(createPsiType((GrTypeDefinition)scope), processor, place, ResolveState.initial()); + } + + if (scope instanceof GroovyFileBase && ((GroovyFileBase)scope).isScript()) { + final PsiClass psiClass = ((GroovyFileBase)scope).getScriptClass(); + return psiClass == null || processNonCodeMembers(createPsiType(psiClass), processor, place, ResolveState.initial()); + } + + if (scope instanceof GrClosableBlock) { + PsiClass superClass = getLiteralSuperClass((GrClosableBlock)scope); + if (superClass != null && !superClass.processDeclarations(processor, ResolveState.initial(), null, place)) return false; + + if (!GdkMethodUtil.categoryIteration((GrClosableBlock)scope, processor, ResolveState.initial())) return false; + if (!GdkMethodUtil.withIteration((GrClosableBlock)scope, processor)) return false; } return true; } + private static PsiClassType createPsiType(PsiClass psiClass) { + PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject()); + return factory.createType(psiClass); + } + public static boolean processChildren(PsiElement element, PsiScopeProcessor processor, ResolveState state, diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java index 388ed8909225..0f1ab6b11e11 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.resolve.noncode; import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightFieldBuilder; +import com.intellij.psi.scope.DelegatingScopeProcessor; import com.intellij.psi.scope.ElementClassHint; import com.intellij.psi.scope.NameHint; import com.intellij.psi.scope.PsiScopeProcessor; @@ -51,13 +52,12 @@ public class GrCollectionTypeMembersProvider extends NonCodeMembersContributor { ResolveUtil.processAllDeclarations(collectionType, fieldSearcher, state, place); } - private static class FieldSearcher implements PsiScopeProcessor, ClassHint, ElementClassHint { + private static class FieldSearcher extends DelegatingScopeProcessor implements ClassHint, ElementClassHint { final PsiClass collectionClass; - final PsiScopeProcessor processor; public FieldSearcher(PsiScopeProcessor processor, PsiClass collectionClass) { + super(processor); this.collectionClass = collectionClass; - this.processor = processor; } @Override @@ -73,23 +73,18 @@ public class GrCollectionTypeMembersProvider extends NonCodeMembersContributor { } LightFieldBuilder lightField = new LightFieldBuilder(((PsiField)element).getName(), typeText, element).setContainingClass( collectionClass); - return processor.execute(lightField, state); + return super.execute(lightField, state); } return true; } @Override public T getHint(@NotNull Key hintKey) { - if (hintKey == NameHint.KEY) return processor.getHint(hintKey); + if (hintKey == NameHint.KEY) return super.getHint(hintKey); if (hintKey == ClassHint.KEY || hintKey == ElementClassHint.KEY) return (T)this; return null; } - @Override - public void handleEvent(Event event, Object associated) { - processor.handleEvent(event, associated); - } - @Override public boolean shouldProcess(ResolveKind resolveKind) { return resolveKind == ResolveKind.PROPERTY; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/JavaResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/JavaResolverProcessor.java index c864f934f140..43a187ff4280 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/JavaResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/JavaResolverProcessor.java @@ -15,27 +15,24 @@ */ package org.jetbrains.plugins.groovy.lang.resolve.processors; -import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.ResolveState; +import com.intellij.psi.scope.DelegatingScopeProcessor; import com.intellij.psi.scope.NameHint; import com.intellij.psi.scope.PsiScopeProcessor; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Checks names of processed element because our Groovy processors don't do it * * @author Max Medvedev */ -public class JavaResolverProcessor implements PsiScopeProcessor { - private final PsiScopeProcessor myDelegate; +public class JavaResolverProcessor extends DelegatingScopeProcessor { private final NameHint myHint; - public JavaResolverProcessor(PsiScopeProcessor delegate) { - myDelegate = delegate; + super(delegate); myHint = delegate.getHint(NameHint.KEY); } @@ -50,16 +47,7 @@ public class JavaResolverProcessor implements PsiScopeProcessor { } - return myDelegate.execute(element, state); + return super.execute(element, state); } - @Override - public T getHint(@NotNull Key hintKey) { - return myDelegate.getHint(hintKey); - } - - @Override - public void handleEvent(Event event, @Nullable Object associated) { - myDelegate.handleEvent(event, associated); - } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStressPerformanceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStressPerformanceTest.groovy index dc93a7d3a83f..8ff6a9911833 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStressPerformanceTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStressPerformanceTest.groovy @@ -163,18 +163,46 @@ class Foo implements Bar { measureHighlighting(text, 200) } - public void "test using SSA variables in a for loop"() { + public void "test using non-reassigned for loop parameters"() { RecursionManager.assertOnRecursionPrevention(testRootDisposable) def text = """ -def foo(List list) { for (file in list) { ${ -" println bar(file)\n" * 10 +" println bar(file)\n" * 20 } } } def bar(File file) { file.path } """ - measureHighlighting(text, 300) + measureHighlighting(text, 2000) + } + + public void "test using SSA variables in a for loop"() { + //todo RecursionManager.assertOnRecursionPrevention(testRootDisposable) + def text = """ +def foo(List list, SomeClass sc) { + List result + for (s in list) { +${ +''' + bar(s, result) + bar2(s, result, sc) + bar3(foo:s, bar:result, sc) + sc.someMethod(s) +''' * 2 + } + } +} +def bar(String s, List result) { result << s } +def bar2(String s, List result) { result << s } +def bar2(int s, List result, SomeClass sc) { result << s as String } +def bar3(Map args, List result, SomeClass sc) { result << s as String } + +class SomeClass { + void someMethod(String s) {} +} +""" + measureHighlighting(text, 1500) } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java index 52ac4eddc555..e51c66e3c6e4 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java @@ -38,7 +38,7 @@ public class GotoTaskAction extends GotoActionBase { public static final CreateNewTaskAction CREATE_NEW_TASK_ACTION = new CreateNewTaskAction(); public GotoTaskAction() { - getTemplatePresentation().setText("Goto Task..."); + getTemplatePresentation().setText("Open Task..."); } @Override @@ -169,7 +169,7 @@ public class GotoTaskAction extends GotoActionBase { return TaskUtil.getTrimmedSummary(((TaskPsiElement)element).getTask()); } else if (element == CREATE_NEW_TASK_ACTION) { - return "Create New Task \"" + CREATE_NEW_TASK_ACTION.getActionText() + "\"..."; + return CREATE_NEW_TASK_ACTION.getActionText(); } return null; } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java index e34d1c745248..c411c50eb19d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java @@ -58,7 +58,7 @@ public class WorkingContextManager { private static final String CONTEXT_ZIP_POSTFIX = ".contexts.zip"; private static final Comparator ENTRY_COMPARATOR = new Comparator() { public int compare(JBZipEntry o1, JBZipEntry o2) { - return (int)(o2.getTime() - o1.getTime()); + return Long.signum(o2.getTime() - o1.getTime()); } }; diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskCheckinHandlerFactory.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskCheckinHandlerFactory.java index 77f4cf7f3115..b1499df1e6c1 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskCheckinHandlerFactory.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskCheckinHandlerFactory.java @@ -59,7 +59,9 @@ public class TaskCheckinHandlerFactory extends CheckinHandlerFactory { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - WorkingContextManager.getInstance(project).saveContext(localTask); + if (!project.isDisposed()) { + WorkingContextManager.getInstance(project).saveContext(localTask); + } } }); } diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java index a8cc8f08e972..83c9236a9c3f 100644 --- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java +++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/XPathEvalAction.java @@ -321,11 +321,11 @@ public class XPathEvalAction extends XPathAction { processPresentation, presentation, new UsageViewManager.UsageViewStateListener() { - public void usageViewCreated(UsageView usageView) { + public void usageViewCreated(@NotNull UsageView usageView) { usageView.addButtonToLowerPane(editAction, "&Edit Expression"); } - public void findingUsagesFinished(UsageView usageView) { + public void findingUsagesFinished(@NotNull UsageView usageView) { } }); } diff --git a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java index cf7e5fbea943..ab3886139303 100644 --- a/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java +++ b/plugins/xpath/xpath-view/src/org/intellij/plugins/xpathView/search/FindByXPathAction.java @@ -34,6 +34,7 @@ import org.intellij.plugins.xpathView.support.XPathSupport; import org.intellij.plugins.xpathView.ui.InputExpressionDialog; import org.jaxen.JaxenException; import org.jaxen.XPathSyntaxException; +import org.jetbrains.annotations.NotNull; import java.util.Collections; @@ -106,11 +107,11 @@ public class FindByXPathAction extends AnAction { } }; final UsageViewManager.UsageViewStateListener stateListener = new UsageViewManager.UsageViewStateListener() { - public void usageViewCreated(UsageView usageView) { + public void usageViewCreated(@NotNull UsageView usageView) { usageView.addButtonToLowerPane(new MyEditExpressionAction(project, module), "&Edit Expression"); } - public void findingUsagesFinished(UsageView usageView) { + public void findingUsagesFinished(@NotNull UsageView usageView) { } }; UsageViewManager.getInstance(project).searchAndShowUsages( diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java index 6b0bd810c682..45b65260a5cc 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java @@ -148,7 +148,9 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { XmlDoctype xmlDoctype = (XmlDoctype)element; final String dtdUri = XmlUtil.getDtdUri(xmlDoctype); if (dtdUri != null) { - final XmlFile xmlFile = XmlUtil.findNamespace(XmlUtil.getContainingFile(element), dtdUri); + XmlFile file = XmlUtil.getContainingFile(element); + if (file == null) return true; + final XmlFile xmlFile = XmlUtil.findNamespace(file, dtdUri); if (xmlFile != null) { if (xmlFile != targetElement) { deps.add(xmlFile); diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTextImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTextImpl.java index 795fbcf0f23f..05d1446a8154 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTextImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTextImpl.java @@ -97,7 +97,9 @@ public class XmlTextImpl extends XmlElementImpl implements XmlText, PsiLanguageI child = cdata.getFirstChildNode(); } else if (elementType == XmlTokenType.XML_CHAR_ENTITY_REF) { - buffer.append(XmlUtil.getCharFromEntityRef(child.getText())); + String text = child.getText(); + LOG.assertTrue(text != null, child); + buffer.append(XmlUtil.getCharFromEntityRef(text)); } else if (elementType == XmlTokenType.XML_WHITE_SPACE || elementType == XmlTokenType.XML_DATA_CHARACTERS || elementType == XmlTokenType .XML_ATTRIBUTE_VALUE_TOKEN) { diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java index 5e455aecfc57..e6689ce9cf7b 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java @@ -18,6 +18,7 @@ package org.intellij.plugins.relaxNG.model.descriptors; import com.intellij.codeInsight.daemon.Validator; import com.intellij.javaee.ExternalResourceManager; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.ModificationTracker; @@ -245,6 +246,9 @@ public class RngNsDescriptor implements XmlNSDescriptorEx, Validator { public Object[] getDependences() { if (myPattern != null) { + if (DumbService.isDumb(myElement.getProject())) { + return new Object[] { ModificationTracker.EVER_CHANGED, ExternalResourceManager.getInstance()}; + } final Object[] a = { myElement, ExternalResourceManager.getInstance() }; final PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(); RelaxIncludeIndex.processForwardDependencies(myFile, processor); @@ -253,9 +257,8 @@ public class RngNsDescriptor implements XmlNSDescriptorEx, Validator { } else { return a; } - } else { - return new Object[]{ ModificationTracker.EVER_CHANGED }; } + return new Object[]{ ModificationTracker.EVER_CHANGED }; } public synchronized void init(PsiElement element) {