diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 88d14aa13d77..c2ce494ab957 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -58,7 +58,7 @@ public class ConstructorInsertHandler implements InsertHandler= 0 && plEnd >= 0) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantElseAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantElseAction.java deleted file mode 100644 index 28db235e1e1b..000000000000 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantElseAction.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInsight.daemon.impl.quickfix; - -import com.intellij.codeInsight.FileModificationService; -import com.intellij.codeInsight.daemon.QuickFixBundle; -import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.controlFlow.*; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.BitUtil; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @author ven - */ -public class RemoveRedundantElseAction extends PsiElementBaseIntentionAction { - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.RemoveRedundantElseAction"); - - @Override - @NotNull - public String getText() { - return QuickFixBundle.message("remove.redundant.else.fix"); - } - - @Override - @NotNull - public String getFamilyName() { - return QuickFixBundle.message("remove.redundant.else.fix"); - } - - @Override - public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - if (element instanceof PsiKeyword && - element.getParent() instanceof PsiIfStatement && - PsiKeyword.ELSE.equals(element.getText())) { - PsiIfStatement ifStatement = (PsiIfStatement)element.getParent(); - if (ifStatement.getElseBranch() == null) return false; - PsiStatement thenBranch = ifStatement.getThenBranch(); - if (thenBranch == null) return false; - PsiElement block = PsiTreeUtil.getParentOfType(ifStatement, PsiCodeBlock.class); - if (block != null) { - while (cantCompleteNormally(thenBranch, block)) { - thenBranch = getPrevThenBranch(thenBranch); - if (thenBranch == null) return true; - } - return false; - } - } - return false; - } - - @Nullable - private static PsiStatement getPrevThenBranch(@NotNull PsiElement thenBranch) { - final PsiElement ifStatement = thenBranch.getParent(); - final PsiElement parent = ifStatement.getParent(); - if (parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getElseBranch() == ifStatement) { - return ((PsiIfStatement)parent).getThenBranch(); - } - return null; - } - - private static boolean cantCompleteNormally(@NotNull PsiStatement thenBranch, PsiElement block) { - try { - ControlFlow controlFlow = ControlFlowFactory.getInstance(thenBranch.getProject()).getControlFlow(block, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance()); - int startOffset = controlFlow.getStartOffset(thenBranch); - int endOffset = controlFlow.getEndOffset(thenBranch); - return startOffset != -1 && endOffset != -1 && !BitUtil.isSet(ControlFlowUtil.getCompletionReasons(controlFlow, startOffset, endOffset), ControlFlowUtil.NORMAL_COMPLETION_REASON); - } - catch (AnalysisCanceledException e) { - return false; - } - } - - @Override - public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException { - if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return; - PsiIfStatement ifStatement = (PsiIfStatement)element.getParent(); - LOG.assertTrue(ifStatement != null && ifStatement.getElseBranch() != null); - PsiStatement elseBranch = ifStatement.getElseBranch(); - if (elseBranch instanceof PsiBlockStatement) { - PsiElement[] statements = ((PsiBlockStatement)elseBranch).getCodeBlock().getStatements(); - if (statements.length > 0) { - ifStatement.getParent().addRangeAfter(statements[0], statements[statements.length-1], ifStatement); - } - } else { - ifStatement.getParent().addAfter(elseBranch, ifStatement); - } - ifStatement.getElseBranch().delete(); - } -} diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaParameterTypeIntention.java b/java/java-impl/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java similarity index 73% rename from java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaParameterTypeIntention.java rename to java/java-impl/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java index 38eacc30395a..4e2445fbaee9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaParameterTypeIntention.java +++ b/java/java-impl/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,44 +13,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInsight.daemon.quickFix; +package com.intellij.codeInspection.lambda; -import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction; +import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemsHolder; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.psi.infos.MethodCandidateInfo; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; -import com.intellij.util.Function; -import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; /** * User: anna */ -public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntentionAction { - public static final Logger LOG = Logger.getInstance("#" + RedundantLambdaParameterTypeIntention.class.getName()); +public class RedundantLambdaParameterTypeInspection extends BaseJavaBatchLocalInspectionTool { + public static final Logger LOG = Logger.getInstance("#" + RedundantLambdaParameterTypeInspection.class.getName()); @NotNull @Override - public String getFamilyName() { - return "Remove redundant types"; + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new JavaElementVisitor() { + @Override + public void visitParameterList(PsiParameterList parameterList) { + super.visitParameterList(parameterList); + if (isApplicable(parameterList)) { + holder.registerProblem(parameterList, "Remove redundant types", new LambdaParametersFix()); + } + } + }; } - @NotNull - @Override - public String getText() { - return getFamilyName(); - } - - @Override - public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - final PsiParameterList parameterList = PsiTreeUtil.getParentOfType(element, PsiParameterList.class); - if (parameterList == null) return false; + private static boolean isApplicable(@NotNull PsiParameterList parameterList) { final PsiElement parent = parameterList.getParent(); if (!(parent instanceof PsiLambdaExpression)) return false; final PsiLambdaExpression expression = (PsiLambdaExpression)parent; @@ -73,9 +72,9 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti final PsiTypeParameter[] typeParameters = method.getTypeParameters(); final PsiExpression[] arguments = ((PsiExpressionList)lambdaParent).getExpressions(); - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(parameterList.getProject()); arguments[idx] = javaPsiFacade.getElementFactory().createExpressionFromText( - "(" + StringUtil.join(expression.getParameterList().getParameters(), parameter -> parameter.getName(), ", ") + ") -> {}", expression); + "(" + StringUtil.join(expression.getParameterList().getParameters(), PsiParameter::getName, ", ") + ") -> {}", expression); final PsiParameter[] methodParams = method.getParameterList().getParameters(); final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper() .inferTypeArguments(typeParameters, methodParams, arguments, ((MethodCandidateInfo)resolveResult).getSiteSubstitutor(), @@ -85,8 +84,7 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti final PsiType psiType = substitutor.substitute(parameter); if (psiType == null || dependsOnTypeParams(psiType, expression, parameter)) return false; } - - + final PsiType paramType; if (idx < methodParams.length) { paramType = methodParams[idx].getType(); @@ -107,12 +105,6 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti return false; } - @Override - public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException { - final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); - removeTypes(lambdaExpression); - } - private static void removeTypes(PsiLambdaExpression lambdaExpression) { if (lambdaExpression != null) { final PsiParameter[] parameters = lambdaExpression.getParameterList().getParameters(); @@ -121,7 +113,7 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti text = parameters[0].getName(); } else { - text = "(" + StringUtil.join(parameters, parameter -> parameter.getName(), ", ") + ")"; + text = "(" + StringUtil.join(parameters, PsiParameter::getName, ", ") + ")"; } final PsiLambdaExpression expression = (PsiLambdaExpression)JavaPsiFacade.getElementFactory(lambdaExpression.getProject()) .createExpressionFromText(text + "->{}", lambdaExpression); @@ -135,4 +127,29 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti return LambdaUtil.depends(type, new LambdaUtil.TypeParamsChecker(expr, PsiUtil .resolveGenericsClassInType(LambdaUtil.getFunctionalInterfaceType(expr, false)).getElement()), param2Check); } + + private static class LambdaParametersFix implements LocalQuickFix { + @Nls + @NotNull + @Override + public String getName() { + return getFamilyName(); + } + + @Nls + @NotNull + @Override + public String getFamilyName() { + return "Remove redundant types"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + final PsiElement parent = element.getParent(); + if (parent instanceof PsiLambdaExpression) { + removeTypes((PsiLambdaExpression)parent); + } + } + } } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/HierarchyServiceImpl.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/HierarchyServiceImpl.java index 31fa42faa53a..654729f0d1ba 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/HierarchyServiceImpl.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/HierarchyServiceImpl.java @@ -19,13 +19,11 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; -import com.intellij.psi.search.DelegatingGlobalSearchScope; -import com.intellij.psi.search.EverythingGlobalScope; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.stubsHierarchy.HierarchyService; import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValueProvider; @@ -33,17 +31,18 @@ import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.CachedValueBase; import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.util.indexing.FileBasedIndexImpl; import org.jetbrains.annotations.NotNull; +import java.util.BitSet; + public class HierarchyServiceImpl extends HierarchyService { private static final SingleClassHierarchy EMPTY_HIERARCHY = new SingleClassHierarchy(Symbol.ClassSymbol.EMPTY_ARRAY); private final Project myProject; - private final ProjectFileIndex myFileIndex; private final CachedValue myHierarchy; public HierarchyServiceImpl(Project project) { myProject = project; - myFileIndex = ProjectFileIndex.SERVICE.getInstance(project); myHierarchy = CachedValuesManager.getManager(project).createCachedValue( () -> CachedValueProvider.Result.create(buildHierarchy(), PsiModificationTracker.MODIFICATION_COUNT), false); @@ -69,38 +68,56 @@ public class HierarchyServiceImpl extends HierarchyService { private SingleClassHierarchy buildHierarchy() { Symbols symbols = new Symbols(); StubEnter stubEnter = new StubEnter(symbols); + IdSets idSets = IdSets.getIdSets(myProject); - loadUnits(false, symbols.myNameEnvironment, stubEnter); + loadUnits(idSets.libraryFiles, StubHierarchyIndex.BINARY_FILES, symbols.myNameEnvironment, stubEnter); stubEnter.connect1(); - loadUnits(true, symbols.myNameEnvironment, stubEnter); + loadUnits(idSets.sourceFiles, StubHierarchyIndex.SOURCE_FILES, symbols.myNameEnvironment, stubEnter); stubEnter.connect2(); return symbols.createHierarchy(); } - private void loadUnits(boolean sourceMode, NameEnvironment names, StubEnter stubEnter) { - GlobalSearchScope scope = new DelegatingGlobalSearchScope(new EverythingGlobalScope(myProject)) { - @Override - public boolean contains(@NotNull VirtualFile file) { - return sourceMode ? myFileIndex.isInSourceContent(file) : myFileIndex.isInLibraryClasses(file); - } - }; + private void loadUnits(BitSet files, int indexKey, NameEnvironment names, StubEnter stubEnter) { ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); - FileBasedIndex index = FileBasedIndex.getInstance(); - for (String packageName : index.getAllKeys(StubHierarchyIndex.INDEX_ID, myProject)) { - QualifiedName pkg = StringUtil.isEmpty(packageName) ? null : names.fromString(packageName, true); - index.processValues(StubHierarchyIndex.INDEX_ID, packageName, null, new FileBasedIndex.ValueProcessor() { - int count = 0; - @Override - public boolean process(VirtualFile file, IndexTree.Unit unit) { - if (indicator != null && ++count % 128 == 0) indicator.checkCanceled(); - stubEnter.unitEnter(Translator.internNames(names, unit, ((VirtualFileWithId)file).getId(), pkg)); - return true; + FileBasedIndexImpl index = (FileBasedIndexImpl)FileBasedIndex.getInstance(); + index.processAllValues(StubHierarchyIndex.INDEX_ID, indexKey, myProject, new FileBasedIndexImpl.IdValueProcessor() { + int count = 0; + @Override + public boolean process(int fileId, IndexTree.Unit unit) { + if (indicator != null && ++count % 128 == 0) indicator.checkCanceled(); + if (files.get(fileId)) { + QualifiedName pkg = StringUtil.isEmpty(unit.myPackageId) ? null : names.fromString(unit.myPackageId, true); + stubEnter.unitEnter(Translator.internNames(names, unit, fileId, pkg)); } - }, scope); - } + return true; + } + }); } + private static class IdSets { + final BitSet sourceFiles = new BitSet(); + final BitSet libraryFiles = new BitSet(); + + static IdSets getIdSets(@NotNull Project project) { + return CachedValuesManager.getManager(project).getCachedValue(project, () -> { + IdSets answer = new IdSets(); + ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project); + FileBasedIndex.getInstance().iterateIndexableFiles(file -> { + if (!file.isDirectory() && file instanceof VirtualFileWithId) { + if (index.isInSourceContent(file)) { + answer.sourceFiles.set(((VirtualFileWithId) file).getId()); + } + else if (index.isInLibraryClasses(file)) { + answer.libraryFiles.set(((VirtualFileWithId) file).getId()); + } + } + return true; + }, project, ProgressIndicatorProvider.getGlobalProgressIndicator()); + return CachedValueProvider.Result.create(answer, ProjectRootManager.getInstance(project), VirtualFileManager.VFS_STRUCTURE_MODIFICATIONS); + }); + } + } } diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/JavaStubIndexer.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/JavaStubIndexer.java index 550c33b9c74e..616ea7213f3c 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/JavaStubIndexer.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/JavaStubIndexer.java @@ -18,7 +18,6 @@ package com.intellij.psi.stubsHierarchy.impl; import com.intellij.ide.highlighter.JavaClassFileType; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiNameHelper; @@ -39,7 +38,10 @@ import com.intellij.util.indexing.FileContent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; public class JavaStubIndexer extends StubHierarchyIndexer { @@ -61,7 +63,7 @@ public class JavaStubIndexer extends StubHierarchyIndexer { @Nullable @Override - public List> indexFile(@NotNull FileContent content) { + public Unit indexFile(@NotNull FileContent content) { Stub stubTree = StubTreeBuilder.buildStubTree(content); if (!(stubTree instanceof PsiJavaFileStub)) return null; @@ -87,7 +89,7 @@ public class JavaStubIndexer extends StubHierarchyIndexer { ClassDecl[] classes = classList.isEmpty() ? ClassDecl.EMPTY_ARRAY : classList.toArray(new ClassDecl[classList.size()]); Import[] imports = importList.isEmpty() ? Import.EMPTY_ARRAY : importList.toArray(new Import[importList.size()]); byte type = javaFileStub.isCompiled() ? IndexTree.BYTECODE : IndexTree.JAVA; - return Collections.singletonList(Pair.create(javaFileStub.getPackageName(), new Unit(type, imports, classes))); + return new Unit(javaFileStub.getPackageName(), type, imports, classes); } @Nullable diff --git a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java index 2550e2fb528a..269bf9fa1f1a 100644 --- a/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java +++ b/java/java-impl/src/com/intellij/psi/stubsHierarchy/impl/StubHierarchyIndex.java @@ -18,47 +18,42 @@ package com.intellij.psi.stubsHierarchy.impl; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; import com.intellij.psi.impl.java.stubs.index.JavaUnitDescriptor; import com.intellij.psi.stubsHierarchy.StubHierarchyIndexer; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; -import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.EnumeratorIntegerDescriptor; import com.intellij.util.io.KeyDescriptor; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; /** * @author peter */ -public class StubHierarchyIndex extends FileBasedIndexExtension implements PsiDependentIndex { - static final ID INDEX_ID = ID.create("jvm.hierarchy"); +public class StubHierarchyIndex extends FileBasedIndexExtension implements PsiDependentIndex { + public static final int BINARY_FILES = 0; + public static final int SOURCE_FILES = 1; + static final ID INDEX_ID = ID.create("jvm.hierarchy"); private static final StubHierarchyIndexer[] ourIndexers = StubHierarchyIndexer.EP_NAME.getExtensions(); @NotNull @Override - public ID getName() { + public ID getName() { return INDEX_ID; } @NotNull @Override - public DataIndexer getIndexer() { + public DataIndexer getIndexer() { return inputData -> { for (StubHierarchyIndexer indexer : ourIndexers) { - List> pairs = indexer.handlesFile(inputData.getFile()) ? indexer.indexFile(inputData) : null; - if (pairs != null && !pairs.isEmpty()) { - Map answer = new HashMap<>(); - for (Pair entry : pairs) { - if (entry.second.myDecls.length > 0) { - answer.put(StringUtil.notNullize(entry.first), entry.second); - } - } - return answer; + IndexTree.Unit unit = indexer.handlesFile(inputData.getFile()) ? indexer.indexFile(inputData) : null; + if (unit != null && unit.myDecls.length > 0) { + return Collections.singletonMap(inputData.getFile().getFileType().isBinary() ? BINARY_FILES : SOURCE_FILES, unit); } } return Collections.emptyMap(); @@ -67,8 +62,8 @@ public class StubHierarchyIndex extends FileBasedIndexExtension getKeyDescriptor() { - return EnumeratorStringDescriptor.INSTANCE; + public KeyDescriptor getKeyDescriptor() { + return EnumeratorIntegerDescriptor.INSTANCE; } @NotNull @@ -79,7 +74,7 @@ public class StubHierarchyIndex extends FileBasedIndexExtension { @Override public void save(@NotNull DataOutput out, IndexTree.Unit value) throws IOException { + out.writeUTF(value.myPackageId); out.writeByte(value.myUnitType); if (value.myUnitType != IndexTree.BYTECODE) { DataInputOutputUtil.writeINT(out, value.imports.length); @@ -75,6 +76,7 @@ public class JavaUnitDescriptor implements DataExternalizer { @Override public IndexTree.Unit read(@NotNull DataInput in) throws IOException { + String pid = in.readUTF(); byte type = in.readByte(); IndexTree.Import[] imports = IndexTree.Import.EMPTY_ARRAY; if (type != IndexTree.BYTECODE) { @@ -87,7 +89,7 @@ public class JavaUnitDescriptor implements DataExternalizer { for (int i = 0; i < classes.length; i++) { classes[i] = readClassDecl(in); } - return new IndexTree.Unit(type, imports, classes); + return new IndexTree.Unit(pid, type, imports, classes); } private IndexTree.ClassDecl readClassDecl(DataInput in) throws IOException { diff --git a/java/java-indexing-impl/src/com/intellij/psi/stubsHierarchy/StubHierarchyIndexer.java b/java/java-indexing-impl/src/com/intellij/psi/stubsHierarchy/StubHierarchyIndexer.java index ce9d16602224..4e0e8ac260fc 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/stubsHierarchy/StubHierarchyIndexer.java +++ b/java/java-indexing-impl/src/com/intellij/psi/stubsHierarchy/StubHierarchyIndexer.java @@ -16,15 +16,12 @@ package com.intellij.psi.stubsHierarchy; import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; import com.intellij.util.indexing.FileContent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; - /** * @author peter */ @@ -37,7 +34,7 @@ public abstract class StubHierarchyIndexer { * @return a list of pairs for a specified file content */ @Nullable - public abstract List> indexFile(@NotNull FileContent content); + public abstract IndexTree.Unit indexFile(@NotNull FileContent content); public abstract boolean handlesFile(@NotNull VirtualFile file); diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiSuperMethodUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiSuperMethodUtil.java index 2148bd45b3cb..641cb6e7ee88 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiSuperMethodUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiSuperMethodUtil.java @@ -15,11 +15,15 @@ */ package com.intellij.psi.util; +import com.intellij.openapi.roots.FileIndexFacade; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.containers.HashSet; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.LinkedHashSet; import java.util.List; @@ -111,6 +115,7 @@ public class PsiSuperMethodUtil { public static Map> collectOverrideEquivalents(@NotNull PsiClass aClass) { final Map> overrideEquivalent = new THashMap>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); + final GlobalSearchScope resolveScope = aClass.getResolveScope(); PsiClass[] supers = aClass.getSupers(); for (int i = 0; i < supers.length; i++) { PsiClass superClass = supers[i]; @@ -122,10 +127,12 @@ public class PsiSuperMethodUtil { if (subType) continue; final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY); for (HierarchicalMethodSignature hms : superClass.getVisibleSignatures()) { - final PsiMethod method = hms.getMethod(); + PsiMethod method = hms.getMethod(); if (MethodSignatureUtil.findMethodBySignature(aClass, method.getSignature(superClassSubstitutor), false) != null) continue; - final PsiClass containingClass = method.getContainingClass(); + final PsiClass containingClass = mapClass(method.getContainingClass(), resolveScope); if (containingClass == null) continue; + method = containingClass.findMethodBySignature(method, false); + if (method == null) continue; final PsiSubstitutor containingClassSubstitutor = TypeConversionUtil.getClassSubstitutor(containingClass, aClass, PsiSubstitutor.EMPTY); if (containingClassSubstitutor == null) continue; final PsiSubstitutor finalSubstitutor = @@ -141,4 +148,30 @@ public class PsiSuperMethodUtil { } return overrideEquivalent; } + + @Nullable + public static PsiClass mapClass(PsiClass psiClass, final GlobalSearchScope resolveScope) { + if (psiClass == null) return null; + String qualifiedName = psiClass.getQualifiedName(); + if (qualifiedName == null) { + return psiClass; + } + + PsiFile file = psiClass.getContainingFile(); + if (file == null || !file.getViewProvider().isPhysical()) { + return psiClass; + } + + final VirtualFile vFile = file.getVirtualFile(); + if (vFile == null) { + return psiClass; + } + + final FileIndexFacade index = FileIndexFacade.getInstance(file.getProject()); + if (!index.isInSource(vFile) && !index.isInLibrarySource(vFile) && !index.isInLibraryClasses(vFile)) { + return psiClass; + } + + return JavaPsiFacade.getInstance(psiClass.getProject()).findClass(qualifiedName, resolveScope); + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java b/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java index f6521658c6dc..d9fcf6bc3c50 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java @@ -15,11 +15,10 @@ */ package com.intellij.psi.impl; -import com.intellij.openapi.roots.FileIndexFacade; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiSuperMethodUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -56,7 +55,7 @@ class TypeCorrector extends PsiTypeMapper { final PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics(); final PsiClass psiClass = classResolveResult.getElement(); if (psiClass != null && classResolveResult.getSubstitutor() == PsiSubstitutor.EMPTY) { - final PsiClass mappedClass = mapClass(psiClass); + final PsiClass mappedClass = PsiSuperMethodUtil.mapClass(psiClass, myResolveScope); if (mappedClass == null || mappedClass == psiClass) return (T) classType; } } @@ -79,7 +78,7 @@ class TypeCorrector extends PsiTypeMapper { PsiUtilCore.ensureValid(psiClass); - final PsiClass mappedClass = mapClass(psiClass); + final PsiClass mappedClass = PsiSuperMethodUtil.mapClass(psiClass, myResolveScope); if (mappedClass == null) return classType; PsiClassType mappedType = new PsiCorrectedClassType(classType.getLanguageLevel(), @@ -89,31 +88,6 @@ class TypeCorrector extends PsiTypeMapper { return mappedType; } - @Nullable - private PsiClass mapClass(@NotNull PsiClass psiClass) { - String qualifiedName = psiClass.getQualifiedName(); - if (qualifiedName == null) { - return psiClass; - } - - PsiFile file = psiClass.getContainingFile(); - if (file == null || !file.getViewProvider().isPhysical()) { - return psiClass; - } - - final VirtualFile vFile = file.getVirtualFile(); - if (vFile == null) { - return psiClass; - } - - final FileIndexFacade index = FileIndexFacade.getInstance(file.getProject()); - if (!index.isInSource(vFile) && !index.isInLibrarySource(vFile) && !index.isInLibraryClasses(vFile)) { - return psiClass; - } - - return JavaPsiFacade.getInstance(psiClass.getProject()).findClass(qualifiedName, myResolveScope); - } - @NotNull private PsiSubstitutor mapSubstitutor(PsiClass originalClass, PsiClass mappedClass, PsiSubstitutor substitutor) { PsiTypeParameter[] typeParameters = mappedClass.getTypeParameters(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java index faf27c3a2d7b..fdf452e9af91 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/hierarchy/IndexTree.java @@ -17,6 +17,9 @@ package com.intellij.psi.impl.java.stubs.hierarchy; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; @@ -37,11 +40,13 @@ public class IndexTree { public static final byte GROOVY = 2; public static class Unit { + @NotNull public final String myPackageId; public final byte myUnitType; public final Import[] imports; public final ClassDecl[] myDecls; - public Unit(byte unitType, Import[] imports, ClassDecl[] decls) { + public Unit(@Nullable String packageId, byte unitType, Import[] imports, ClassDecl[] decls) { + this.myPackageId = StringUtil.notNullize(packageId); this.myUnitType = unitType; this.imports = imports; this.myDecls = decls; @@ -54,6 +59,8 @@ public class IndexTree { Unit unit = (Unit)o; + if (myUnitType != unit.myUnitType) return false; + if (!myPackageId.equals(unit.myPackageId)) return false; if (!Arrays.equals(imports, unit.imports)) return false; if (!Arrays.equals(myDecls, unit.myDecls)) return false; @@ -62,7 +69,14 @@ public class IndexTree { @Override public int hashCode() { - return Arrays.hashCode(myDecls); + int hash = myUnitType * 31 + myPackageId.hashCode(); + for (ClassDecl decl : myDecls) { + String name = decl.myName; + if (name != null) { + return hash * 31 + name.hashCode(); + } + } + return hash; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java index 50b49e3b29b1..18ed26bd5e43 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java @@ -237,9 +237,7 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements PsiType ret, JavaResolveResult result, LanguageLevel languageLevel) { - PsiSubstitutor substitutor = result instanceof MethodCandidateInfo && !PsiPolyExpressionUtil.isMethodCallTypeDependsOnInference(call, method) - ? ((MethodCandidateInfo)result).getSiteSubstitutor() - : result.getSubstitutor(); + PsiSubstitutor substitutor = result.getSubstitutor(); PsiType substitutedReturnType = substitutor.substitute(ret); if (substitutedReturnType == null) { return TypeConversionUtil.erasure(ret); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/after1.java deleted file mode 100644 index d0d55761f11b..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/after1.java +++ /dev/null @@ -1,13 +0,0 @@ -// "Remove redundant 'else'" "true" -class a { - void foo() { - int a = 0; - int b = 0; - if (a != b) { - return; - } - a = b; - a++; - } -} - diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/before1.java deleted file mode 100644 index ea4609835464..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/before1.java +++ /dev/null @@ -1,14 +0,0 @@ -// "Remove redundant 'else'" "true" -class a { - void foo() { - int a = 0; - int b = 0; - if (a != b) { - return; - } else { - a = b; - } - a++; - } -} - diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/beforeCanThrowException.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/beforeCanThrowException.java deleted file mode 100644 index 8fd59ef094f3..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/beforeCanThrowException.java +++ /dev/null @@ -1,15 +0,0 @@ -// "Remove redundant 'else'" "false" -import java.io.IOException; -class a { - void foo(boolean condition) throws IOException{ - if (condition) { - tMethod(); - } - else { - System.out.println("else"); - } - } - - void tMethod() throws IOException {} -} - diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/beforeIfElseChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/beforeIfElseChain.java deleted file mode 100644 index f702178d781f..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse/beforeIfElseChain.java +++ /dev/null @@ -1,17 +0,0 @@ -// "Remove redundant 'else'" "false" -class a { - void foo() { - int a = 0; - int b = 0; - if (a != b) { - a = 10; - } else if (a + 1 == b) { - return; - } - else { - a = b; - } - a++; - } -} - diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java7/p/I.java b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/I.java new file mode 100644 index 000000000000..30e62b5249e6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/I.java @@ -0,0 +1,4 @@ +package p; +interface I { + default void foo(); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java7/p/UnrelatedDefaultsFromDifferentJdkVersions.java b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/UnrelatedDefaultsFromDifferentJdkVersions.java new file mode 100644 index 000000000000..52e05186d644 --- /dev/null +++ b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/UnrelatedDefaultsFromDifferentJdkVersions.java @@ -0,0 +1,3 @@ +package p; + +public abstract class A implements I {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java8/p/I.java b/java/java-tests/testData/codeInsight/multipleJdks/java8/p/I.java new file mode 100644 index 000000000000..30e62b5249e6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/multipleJdks/java8/p/I.java @@ -0,0 +1,4 @@ +package p; +interface I { + default void foo(); +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java8/p/UnrelatedDefaultsFromDifferentJdkVersions.java b/java/java-tests/testData/codeInsight/multipleJdks/java8/p/UnrelatedDefaultsFromDifferentJdkVersions.java new file mode 100644 index 000000000000..ab93746c9c7d --- /dev/null +++ b/java/java-tests/testData/codeInsight/multipleJdks/java8/p/UnrelatedDefaultsFromDifferentJdkVersions.java @@ -0,0 +1,8 @@ +package p; + +class EmptyValueIterator extends A implements ValueIterator { + +} + +interface ValueIterator extends I {} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAssignment.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/Assignment.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAssignment.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/Assignment.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAssignmentNoParams.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/AssignmentNoParams.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAssignmentNoParams.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/AssignmentNoParams.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAssignmentNoTypes.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/AssignmentNoTypes.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAssignmentNoTypes.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/AssignmentNoTypes.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterAssignment.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/Assignment_after.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterAssignment.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/Assignment_after.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAtVarargPlace.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/AtVarargPlace.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeAtVarargPlace.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/AtVarargPlace.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeCallNoTypeArgs.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallNoTypeArgs.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeCallNoTypeArgs.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallNoTypeArgs.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeCallNoTypeArgs1.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallNoTypeArgs1.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeCallNoTypeArgs1.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallNoTypeArgs1.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeCallWithTypeArgs.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallWithTypeArgs.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeCallWithTypeArgs.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallWithTypeArgs.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterCallWithTypeArgs.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallWithTypeArgs_after.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterCallWithTypeArgs.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/CallWithTypeArgs_after.java diff --git a/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InChain.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InChain.java new file mode 100644 index 000000000000..7262e3bbca40 --- /dev/null +++ b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InChain.java @@ -0,0 +1,7 @@ +import java.util.stream.Stream; + +class InChain { + public static void main(String[] args) { + Stream.of("a").map((String s) -> s + "1").forEach(System.out::println); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InChain_after.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InChain_after.java new file mode 100644 index 000000000000..857e423db1eb --- /dev/null +++ b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InChain_after.java @@ -0,0 +1,7 @@ +import java.util.stream.Stream; + +class InChain { + public static void main(String[] args) { + Stream.of("a").map(s -> s + "1").forEach(System.out::println); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeInferredFromOtherArgs.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InferredFromOtherArgs.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeInferredFromOtherArgs.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/InferredFromOtherArgs.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterInferredFromOtherArgs.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/InferredFromOtherArgs_after.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterInferredFromOtherArgs.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/InferredFromOtherArgs_after.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeNoSelfTypeParam.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/NoSelfTypeParam.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeNoSelfTypeParam.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/NoSelfTypeParam.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterNoSelfTypeParam.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/NoSelfTypeParam_after.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/afterNoSelfTypeParam.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/NoSelfTypeParam_after.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeTypeParam.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/TypeParam.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType/beforeTypeParam.java rename to java/java-tests/testData/codeInspection/redundantLambdaParameterType/TypeParam.java diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java index 874522ec38f7..4c6c21761f55 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.pom.java.LanguageLevel; @@ -26,7 +25,6 @@ import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.*; -import com.intellij.util.Consumer; public class MultipleJdksHighlightingTest extends UsefulTestCase { @@ -197,6 +195,16 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase { myFixture.checkHighlighting(); } + public void testUnrelatedDefaultsFromDifferentJdkVersions() throws Exception { + ModuleRootModificationUtil.addDependency(myJava8Module, myJava7Module); + myFixture.copyFileToProject("java7/p/I.java"); + myFixture.copyFileToProject("java8/p/I.java"); + + final String testName = getTestName(false); + myFixture.configureByFiles("java8/p/" + testName + ".java", "java7/p/" + testName + ".java"); + myFixture.checkHighlighting(); + } + private void doTestWithoutLibrary() { final String name = getTestName(false); myFixture.configureByFiles("java7/p/" + name + ".java", "java8/p/" + name + ".java"); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaParameterTypeIntentionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaParameterTypeIntentionTest.java deleted file mode 100644 index 4f85962f0a62..000000000000 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RedundantLambdaParameterTypeIntentionTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInsight.daemon.quickFix; - -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; - -public class RedundantLambdaParameterTypeIntentionTest extends LightQuickFixParameterizedTestCase { - public void test() throws Exception { doAllTests(); } - - @Override - protected String getBasePath() { - return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType"; - } - - @Override - protected Sdk getProjectJDK() { - return IdeaTestUtil.getMockJdk18(); - } -} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantElseActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantElseActionTest.java deleted file mode 100644 index 0a33ada748f8..000000000000 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantElseActionTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInsight.daemon.quickFix; - -/** - * User: anna - * Date: Aug 30, 2010 - */ -public class RemoveRedundantElseActionTest extends LightQuickFixParameterizedTestCase { - - public void test() throws Exception { doAllTests(); } - - @Override - protected String getBasePath() { - return "/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse"; - } - -} - diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/RedundantLambdaParameterTypeInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantLambdaParameterTypeInspectionTest.java new file mode 100644 index 000000000000..3e610fcbcf04 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInspection/RedundantLambdaParameterTypeInspectionTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2000-2016 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:public void testwww() {}.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.codeInspection; + +import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.lambda.RedundantLambdaParameterTypeInspection; +import com.intellij.idea.Bombed; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; + +import java.util.Calendar; +import java.util.List; + +public class RedundantLambdaParameterTypeInspectionTest extends LightCodeInsightFixtureTestCase { + private RedundantLambdaParameterTypeInspection myInspection = new RedundantLambdaParameterTypeInspection(); + private String myIntentionName = "Remove redundant types"; + + @Override + protected String getBasePath() { + return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInspection/redundantLambdaParameterType"; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + ModuleRootModificationUtil.setModuleSdk(myModule, IdeaTestUtil.getMockJdk18()); + myFixture.enableInspections(myInspection); + } + + @Override + protected void tearDown() throws Exception { + try { + myFixture.disableInspections(myInspection); + } + finally { + super.tearDown(); + } + } + + public void testAssignment() { + doTest(); + } + + public void testAssignmentNoParams() { + assertIntentionNotAvailable(); + } + + public void testAssignmentNoTypes() { + assertIntentionNotAvailable(); + } + + public void testAtVarargPlace() { + assertIntentionNotAvailable(); + } + + public void testCallNoTypeArgs() { + assertIntentionNotAvailable(); + } + + public void testCallNoTypeArgs1() { + assertIntentionNotAvailable(); + } + + public void testCallWithTypeArgs() { + doTest(); + } + + public void testInferredFromOtherArgs() { + doTest(); + } + + public void testNoSelfTypeParam() { + doTest(); + } + + public void testTypeParam() { + assertIntentionNotAvailable(); + } + + @Bombed(month = Calendar.AUGUST, day = 1, user = "Pavel Dolgov") + public void testInChain() { + doTest(); + } + + private void doTest() { + myFixture.configureByFiles(getTestName(false) + ".java"); + final IntentionAction singleIntention = myFixture.findSingleIntention(myIntentionName); + myFixture.launchAction(singleIntention); + myFixture.checkResultByFile(getTestName(false) + ".java", getTestName(false) + "_after.java", true); + } + + private void assertIntentionNotAvailable() { + myFixture.configureByFiles(getTestName(false) + ".java"); + final List intentionActions = myFixture.filterAvailableIntentions(myIntentionName); + assertEmpty(myIntentionName + " is not expected", intentionActions); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java index 37ea37f6c233..b9d84f386d96 100644 --- a/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/impl/smartPointers/SmartPsiElementPointersTest.java @@ -58,10 +58,7 @@ import org.junit.Assert; import java.io.IOException; import java.lang.ref.SoftReference; -import java.util.Collections; -import java.util.List; -import java.util.Random; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @PlatformTestCase.WrapInCommand @@ -915,4 +912,20 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase { assertEquals(psiClass.getNameIdentifier().getTextRange(), TextRange.create(range)); } + public void testManySmartPointersCreationDeletionPerformance() throws Exception { + String text = StringUtil.repeatSymbol(' ', 100000); + PsiFile file = createFile("a.txt", text); + + PlatformTestUtil.startPerformanceTest("", 2000, () -> { + List pointers = new ArrayList<>(); + for (int i = 0; i < text.length() - 1; i++) { + pointers.add(getPointerManager().createSmartPsiFileRangePointer(file, new TextRange(i, i + 1))); + } + Collections.shuffle(pointers); + for (SmartPsiFileRange pointer : pointers) { + getPointerManager().removePointer(pointer); + } + }).cpuBound().assertTiming(); + } + } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java index d18fb3ed192c..28a99999203e 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java @@ -29,7 +29,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.PsiDocumentManagerBase; import com.intellij.psi.util.PsiUtilCore; import com.intellij.reference.SoftReference; -import com.intellij.util.ArrayUtil; +import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -68,7 +68,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager { FilePointersList pointers = reference.file.getUserData(reference.key); if (pointers != null) { - pointers.remove(reference); + pointers.removeReference(reference); } } } @@ -160,12 +160,13 @@ public class SmartPointerManagerImpl extends SmartPointerManager { SmartPointerElementInfo info = pointer.getElementInfo(); if (!(info instanceof SelfElementInfo)) return; + PointerReference reference = new PointerReference(pointer, containingFile, POINTERS_KEY); while (true) { FilePointersList pointers = getPointers(containingFile); if (pointers == null) { pointers = containingFile.putUserDataIfAbsent(POINTERS_KEY, new FilePointersList()); } - if (pointers.add(new PointerReference(pointer, containingFile, ourQueue, POINTERS_KEY))) { + if (pointers.add(reference)) { if (((SelfElementInfo)info).hasRange()) { pointers.markerCache.rangeChanged(); } @@ -193,8 +194,10 @@ public class SmartPointerManagerImpl extends SmartPointerManager { if (containingFile == null) return; VirtualFile vFile = containingFile.getViewProvider().getVirtualFile(); FilePointersList pointers = getPointers(vFile); - if (pointers == null) return; - pointers.remove(pointer); + PointerReference reference = ((SmartPsiElementPointerImpl)pointer).pointerReference; + if (pointers != null && reference != null) { + pointers.removeReference(reference); + } } } @@ -264,17 +267,18 @@ public class SmartPointerManagerImpl extends SmartPointerManager { return myPsiDocManager; } - private static class PointerReference extends WeakReference { + static class PointerReference extends WeakReference { @NotNull private final VirtualFile file; @NotNull private final Key key; + private int index = -2; private PointerReference(@NotNull SmartPsiElementPointerImpl pointer, @NotNull VirtualFile containingFile, - @NotNull ReferenceQueue queue, @NotNull Key key) { - super(pointer, queue); + super(pointer, ourQueue); file = containingFile; this.key = key; + pointer.pointerReference = this; } } @@ -292,104 +296,98 @@ public class SmartPointerManagerImpl extends SmartPointerManager { } if (nextAvailableIndex >= references.length || nextAvailableIndex > size*2) { // overflow or too many dead refs - int newCapacity = nextAvailableIndex >= references.length ? references.length * 3/2 +1 : size * 3/2+1; - PointerReference[] newReferences = new PointerReference[newCapacity]; + int newCapacity = (nextAvailableIndex >= references.length ? references.length : size) * 3 / 2 + 1; + final PointerReference[] newReferences = new PointerReference[newCapacity]; - int o = 0; - for (PointerReference oldRef : references) { - if (SoftReference.dereference(oldRef) != null) { - newReferences[o++] = oldRef; + final int[] o = {0}; + processAlivePointers(new Processor() { + @Override + public boolean process(SmartPsiElementPointerImpl pointer) { + storePointerReference(newReferences, o[0]++, pointer.pointerReference); + return true; } - } + }); references = newReferences; - size = nextAvailableIndex = o; + size = nextAvailableIndex = o[0]; } - references[nextAvailableIndex++] = reference; + assert references[nextAvailableIndex] == null : references[nextAvailableIndex]; + storePointerReference(references, nextAvailableIndex++, reference); size++; mySorted = false; return true; } - private synchronized void remove(@NotNull PointerReference reference) { - int index = ArrayUtil.indexOf(references, reference, 0, nextAvailableIndex); - if (index != -1) { - removeReference(reference, index); - } - } + private synchronized void removeReference(@NotNull PointerReference reference) { + int index = reference.index; + if (index < 0) return; - private synchronized void remove(@NotNull SmartPsiElementPointer smartPointer) { - for (int i = 0; i < nextAvailableIndex; i++) { - PointerReference reference = references[i]; - if (reference != null && reference.get() == smartPointer) { - removeReference(reference, i); - return; - } - } - } - - private void removeReference(@NotNull PointerReference reference, int index) { + assert references[index] == reference : "At " + index + " expected " + reference + ", found " + references[index]; + references[index].index = -1; references[index] = null; if (--size == 0) { reference.file.replace(reference.key, this, null); } } - boolean processAlivePointers(@NotNull Processor processor) { + synchronized boolean processAlivePointers(@NotNull Processor processor) { for (int i = 0; i < nextAvailableIndex; i++) { - SmartPsiElementPointerImpl pointer = SoftReference.dereference(references[i]); - if (pointer != null && !processor.process(pointer)) { + PointerReference ref = references[i]; + if (ref == null) continue; + + SmartPsiElementPointerImpl pointer = ref.get(); + if (pointer == null) { + removeReference(ref); + continue; + } + + if (!processor.process(pointer)) { return false; } } return true; } - synchronized List getSortedInfos() { + private void ensureSorted() { if (!mySorted) { - List hardRefs = ContainerUtil.newArrayListWithCapacity(size); - for (int i = 0; i < nextAvailableIndex; i++) { - PointerReference reference = references[i]; - if (reference == null) continue; + List pointers = new ArrayList(); + processAlivePointers(new CommonProcessors.CollectProcessor(pointers)); + assert size == pointers.size(); - SmartPsiElementPointerImpl pointer = reference.get(); - if (pointer != null) { - hardRefs.add(pointer); - } - else { - removeReference(reference, i); - if (size == 0) { - return Collections.emptyList(); - } - } - } - assert size == hardRefs.size(); - - Arrays.sort(references, 0, nextAvailableIndex, new Comparator() { + Collections.sort(pointers, new Comparator() { @Override - public int compare(PointerReference o1, PointerReference o2) { - SmartPsiElementPointerImpl p1 = SoftReference.dereference(o1); - SmartPsiElementPointerImpl p2 = SoftReference.dereference(o2); - if (p1 == null || p2 == null) { - return p1 != null ? -1 : p2 != null ? 1 : 0; // null references to the end - } + public int compare(SmartPsiElementPointerImpl p1, SmartPsiElementPointerImpl p2) { return MarkerCache.INFO_COMPARATOR.compare((SelfElementInfo)p1.getElementInfo(), (SelfElementInfo)p2.getElementInfo()); } }); - nextAvailableIndex = hardRefs.size(); + + for (int i = 0; i < pointers.size(); i++) { + storePointerReference(references, i, pointers.get(i).pointerReference); + } + Arrays.fill(references, pointers.size(), nextAvailableIndex, null); + nextAvailableIndex = pointers.size(); mySorted = true; } + } - List infos = ContainerUtil.newArrayListWithCapacity(size); - for (int i = 0; i < nextAvailableIndex; i++) { - Reference reference = references[i]; - SmartPsiElementPointerImpl pointer = SoftReference.dereference(reference); - if (pointer != null) { + private static void storePointerReference(PointerReference[] references, int index, PointerReference ref) { + references[index] = ref; + ref.index = index; + } + + synchronized List getSortedInfos() { + ensureSorted(); + + final List infos = ContainerUtil.newArrayListWithCapacity(size); + processAlivePointers(new Processor() { + @Override + public boolean process(SmartPsiElementPointerImpl pointer) { SelfElementInfo info = (SelfElementInfo)pointer.getElementInfo(); - if (!info.hasRange()) break; + if (!info.hasRange()) return false; infos.add(info); + return true; } - } + }); return infos; } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java index ee7c4c9c249a..01e43e3b8d35 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPsiElementPointerImpl.java @@ -46,6 +46,7 @@ class SmartPsiElementPointerImpl implements SmartPointerEx private final SmartPointerElementInfo myElementInfo; private final Class myElementClass; private byte myReferenceCount = 1; + @Nullable SmartPointerManagerImpl.PointerReference pointerReference; SmartPsiElementPointerImpl(@NotNull Project project, @NotNull E element, @Nullable PsiFile containingFile, boolean forInjected) { this(element, createElementInfo(project, element, containingFile, forInjected), element.getClass()); diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java index b6485d6c5432..ac368eae64bd 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java @@ -54,9 +54,7 @@ import java.util.Set; * A: There are two ways. The easier and preferred one is to provide constructor in your contributor and register completion providers there: * {@link #extend(CompletionType, ElementPattern, CompletionProvider)}.
* A more generic way is to override default {@link #fillCompletionVariants(CompletionParameters, CompletionResultSet)} implementation - * and provide your own. It's easier to debug, but harder to write. Remember, that completion variant collection is done in a dedicated thread - * WITHOUT read action, so you'll have to manually invoke {@link com.intellij.openapi.application.Application#runReadAction(Runnable)} each time - * you access PSI. Don't spend long time inside read action, since this will prevent user from selecting lookup element or cancelling completion.

+ * and provide your own. It's easier to debug, but harder to write.

* * Q: What does the {@link CompletionParameters#getPosition()} return?
* A: When completion is invoked, the file being edited is first copied (the original file can be accessed from {@link com.intellij.psi.PsiFile#getOriginalFile()} diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java b/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java index 90a9b12292e9..8f28dffa0dcb 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java @@ -19,10 +19,10 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import gnu.trove.THashSet; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -48,10 +48,10 @@ public class OffsetMap implements Disposable { public int getOffset(OffsetKey key) { synchronized (myMap) { final RangeMarker marker = myMap.get(key); - if (marker == null) return -1; + if (marker == null) throw new IllegalArgumentException("Offset " + key + " is not registered"); if (!marker.isValid()) { removeOffset(key); - return -1; + throw new IllegalStateException("Offset " + key + " is invalid: " + marker); } final int endOffset = marker.getEndOffset(); @@ -62,6 +62,11 @@ public class OffsetMap implements Disposable { } } + public boolean containsOffset(OffsetKey key) { + final RangeMarker marker = myMap.get(key); + return marker != null && marker.isValid(); + } + /** * Register key-offset binding. Offset will change together with {@link Document} editing operations * unless an operation replaces completely the offset vicinity. @@ -108,7 +113,7 @@ public class OffsetMap implements Disposable { synchronized (myMap) { ProgressManager.checkCanceled(); assert !myDisposed; - return new ArrayList(myMap.keySet()); + return ContainerUtil.filter(myMap.keySet(), this::containsOffset); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 34a67a149b82..bb8e159880e0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -566,10 +566,9 @@ public class CodeCompletionHandlerBase { final Editor editor = indicator.getEditor(); final int caretOffset = indicator.getCaret().getOffset(); - int idEndOffset = indicator.getIdentifierEndOffset(); - if (idEndOffset < 0) { - idEndOffset = CompletionInitializationContext.calcDefaultIdentifierEnd(editor, caretOffset); - } + final int idEndOffset = indicator.getOffsetMap().containsOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) ? + indicator.getIdentifierEndOffset() : + CompletionInitializationContext.calcDefaultIdentifierEnd(editor, caretOffset); final int idEndOffsetDelta = idEndOffset - caretOffset; CompletionAssertions.WatchingInsertionContext context; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java index 59159a84a440..10994f07e85b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java @@ -18,6 +18,8 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.util.Key; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.ui.StringComboboxEditor; @@ -28,7 +30,9 @@ import javax.swing.*; /** * @author peter */ -public class ComboEditorCompletionContributor extends CompletionContributor{ +public class ComboEditorCompletionContributor extends CompletionContributor implements DumbAware { + + public static final Key CONTINUE_RUN_COMPLETION = Key.create("CONTINUE_RUN_COMPLETION"); @Override public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) { @@ -60,7 +64,9 @@ public class ComboEditorCompletionContributor extends CompletionContributor{ }), count-i)); } } - result.stopHere(); + if (!Boolean.TRUE.equals(document.getUserData(CONTINUE_RUN_COMPLETION))) { + result.stopHere(); + } } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index 1a4be6bf4c56..20a099c0dfb9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -462,6 +462,10 @@ public class CompletionLookupArranger extends LookupArranger { return; } + if (!context.getOffsetMap().containsOffset(CompletionInitializationContext.START_OFFSET)) { + return; + } + final Document document = context.getDocument(); int startOffset = context.getStartOffset(); int tailOffset = context.getEditor().getCaretModel().getOffset(); @@ -550,7 +554,9 @@ public class CompletionLookupArranger extends LookupArranger { public void addSparedChars(CompletionProgressIndicator indicator, LookupElement item, InsertionContext context, char completionChar) { String textInserted; - if (context.getStartOffset() >= 0 && context.getTailOffset() >= context.getStartOffset()) { + if (context.getOffsetMap().containsOffset(CompletionInitializationContext.START_OFFSET) && + context.getOffsetMap().containsOffset(InsertionContext.TAIL_OFFSET) && + context.getTailOffset() >= context.getStartOffset()) { textInserted = context.getDocument().getImmutableCharSequence().subSequence(context.getStartOffset(), context.getTailOffset()).toString(); } else { textInserted = item.getLookupString(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java index 534ec24f9e19..87c490400fec 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java @@ -35,18 +35,17 @@ import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import gnu.trove.THashMap; @@ -57,7 +56,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; import java.util.*; -import java.util.concurrent.*; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -506,10 +508,18 @@ class PassExecutorService implements Disposable { pass.applyInformationToEditor(); } } - catch (RuntimeException e) { + catch (ProcessCanceledException e) { log(updateProgress, pass, "Error " + e); throw e; } + catch (RuntimeException e) { + Document document = pass.getDocument(); + VirtualFile file = document == null ? null : FileDocumentManager.getInstance().getFile(document); + FileType fileType = file == null ? null : file.getFileType(); + String message = "Exception while applying information to " + fileEditor + "("+fileType+")"; + log(updateProgress, pass, message + e); + throw new RuntimeException(message, e); + } if (threadsToStartCountdown.decrementAndGet() == 0) { log(updateProgress, pass, "Stopping "); updateProgress.stopIfRunning(); diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 3ff4aa000ccd..fe96142f26cf 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -767,13 +767,15 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - processValuesImpl(indexId, dataKey, true, restrictToFile, new ValueProcessor() { - @Override - public boolean process(final VirtualFile file, final V value) { - values.add(value); - return true; - } - }, filter, null); + ValueProcessor processor = (file, value) -> { + values.add(value); + return true; + }; + if (restrictToFile != null) { + processValuesInOneFile(indexId, dataKey, restrictToFile, processor, filter); + } else { + processValuesInScope(indexId, dataKey, true, filter, null, processor); + } return values; } @@ -783,13 +785,10 @@ public class FileBasedIndexImpl extends FileBasedIndex { @NotNull K dataKey, @NotNull final GlobalSearchScope filter) { final Set files = new THashSet(); - processValuesImpl(indexId, dataKey, false, null, new ValueProcessor() { - @Override - public boolean process(final VirtualFile file, final V value) { - files.add(file); - return true; - } - }, filter, null); + processValuesInScope(indexId, dataKey, false, filter, null, (file, value) -> { + files.add(file); + return true; + }); return files; } @@ -807,7 +806,40 @@ public class FileBasedIndexImpl extends FileBasedIndex { @NotNull ValueProcessor processor, @NotNull GlobalSearchScope filter, @Nullable IdFilter idFilter) { - return processValuesImpl(indexId, dataKey, false, inFile, processor, filter, idFilter); + return inFile != null + ? processValuesInOneFile(indexId, dataKey, inFile, processor, filter) + : processValuesInScope(indexId, dataKey, false, filter, idFilter, processor); + } + + public interface IdValueProcessor { + /** + * @param fileId the id of the file that the value came from + * @param value a value to process + * @return false if no further processing is needed, true otherwise + */ + boolean process(int fileId, V value); + } + + /** + * Process values for a given index key together with their containing file ids. Note that project is supplied + * only to ensure that all the indices in that project are up to date; there's no guarantee that the processed file ids belong + * to this project. + */ + public boolean processAllValues(@NotNull ID indexId, + @NotNull K key, + @NotNull Project project, + @NotNull IdValueProcessor processor) { + return processValueIterator(indexId, key, null, GlobalSearchScope.allScope(project), valueIt -> { + while (valueIt.hasNext()) { + V value = valueIt.next(); + for (ValueContainer.IntIterator inputIdsIterator = valueIt.getInputIdsIterator(); inputIdsIterator.hasNext(); ) { + if (!processor.process(inputIdsIterator.next(), value)) { + return false; + } + } + } + return true; + }); } @Nullable @@ -854,54 +886,61 @@ public class FileBasedIndexImpl extends FileBasedIndex { return null; } - private boolean processValuesImpl(@NotNull final ID indexId, @NotNull final K dataKey, final boolean ensureValueProcessedOnce, - @Nullable final VirtualFile restrictToFile, @NotNull final ValueProcessor processor, - @NotNull final GlobalSearchScope scope, @Nullable final IdFilter idFilter) { - ThrowableConvertor, Boolean, StorageException> keyProcessor = - index -> { - final ValueContainer container = index.getData(dataKey); + private boolean processValuesInOneFile(@NotNull ID indexId, + @NotNull K dataKey, + @NotNull VirtualFile restrictToFile, + @NotNull ValueProcessor processor, @NotNull GlobalSearchScope scope) { + if (!(restrictToFile instanceof VirtualFileWithId)) return true; - boolean shouldContinue = true; + int restrictedFileId = getFileId(restrictToFile); + return processValueIterator(indexId, dataKey, restrictToFile, scope, valueIt -> { + while (valueIt.hasNext()) { + V value = valueIt.next(); + if (valueIt.getValueAssociationPredicate().contains(restrictedFileId) && !processor.process(restrictToFile, value)) { + return false; + } + } + return true; + }); + } - if (restrictToFile != null) { - if (restrictToFile instanceof VirtualFileWithId) { - final int restrictedFileId = getFileId(restrictToFile); - for (final ValueContainer.ValueIterator valueIt = container.getValueIterator(); valueIt.hasNext(); ) { - final V value = valueIt.next(); - if (valueIt.getValueAssociationPredicate().contains(restrictedFileId)) { - shouldContinue = processor.process(restrictToFile, value); - if (!shouldContinue) { - break; - } - } + private boolean processValuesInScope(@NotNull ID indexId, + @NotNull K dataKey, + boolean ensureValueProcessedOnce, + @NotNull GlobalSearchScope scope, + @Nullable IdFilter idFilter, + @NotNull ValueProcessor processor) { + PersistentFS fs = (PersistentFS)ManagingFS.getInstance(); + IdFilter filter = idFilter != null ? idFilter : projectIndexableFiles(scope.getProject()); + + return processValueIterator(indexId, dataKey, null, scope, valueIt -> { + while (valueIt.hasNext()) { + final V value = valueIt.next(); + for (final ValueContainer.IntIterator inputIdsIterator = valueIt.getInputIdsIterator(); inputIdsIterator.hasNext(); ) { + final int id = inputIdsIterator.next(); + if (filter != null && !filter.containsFileId(id)) continue; + VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id); + if (file != null && scope.accept(file)) { + if (!processor.process(file, value)) { + return false; + } + if (ensureValueProcessedOnce) { + break; // continue with the next value } } } - else { - final PersistentFS fs = (PersistentFS)ManagingFS.getInstance(); - final IdFilter filter = idFilter != null ? idFilter : projectIndexableFiles(scope.getProject()); - VALUES_LOOP: - for (final ValueContainer.ValueIterator valueIt = container.getValueIterator(); valueIt.hasNext(); ) { - final V value = valueIt.next(); - for (final ValueContainer.IntIterator inputIdsIterator = valueIt.getInputIdsIterator(); inputIdsIterator.hasNext(); ) { - final int id = inputIdsIterator.next(); - if (filter != null && !filter.containsFileId(id)) continue; - VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id); - if (file != null && scope.accept(file)) { - shouldContinue = processor.process(file, value); - if (!shouldContinue) { - break VALUES_LOOP; - } - if (ensureValueProcessedOnce) { - break; // continue with the next value - } - } - } - } - } - return shouldContinue; - }; - final Boolean result = processExceptions(indexId, restrictToFile, scope, keyProcessor); + } + return true; + }); + } + + private boolean processValueIterator(@NotNull ID indexId, + @NotNull K dataKey, + @Nullable VirtualFile restrictToFile, + @NotNull GlobalSearchScope scope, + @NotNull Processor> valueProcessor) { + final Boolean result = processExceptions(indexId, restrictToFile, scope, + index -> valueProcessor.process(index.getData(dataKey).getValueIterator())); return result == null || result.booleanValue(); } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java index beda46464af9..8e779cb70315 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java @@ -21,7 +21,6 @@ import com.intellij.util.SmartList; import com.intellij.util.containers.EmptyIterator; import com.intellij.util.indexing.containers.ChangeBufferingList; import com.intellij.util.indexing.containers.IdSet; -import com.intellij.util.indexing.containers.SortedFileIdSetIterator; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.DataInputOutputUtil; import gnu.trove.THashMap; @@ -447,11 +446,8 @@ class ValueContainerImpl extends UpdatableValueContainer implement } else { // serialize positive file ids with delta encoding ChangeBufferingList originalInput = (ChangeBufferingList)fileSetObject; - IntIterator intIterator = originalInput.rawIntIterator(); - if (!intIterator.hasAscendingOrder()) { - // remove possible dupes - intIterator = SortedFileIdSetIterator.getTransientIterator(intIterator); - } + IntIterator intIterator = originalInput.sortedIntIterator(); + if (DebugAssertions.DEBUG) DebugAssertions.assertTrue(intIterator.hasAscendingOrder()); if (intIterator.size() == 1) { DataInputOutputUtil.writeINT(out, intIterator.next()); diff --git a/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java b/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java index d1a7b6734fdd..57512fb4fd4d 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/containers/ChangeBufferingList.java @@ -19,6 +19,8 @@ import com.intellij.util.indexing.DebugAssertions; import com.intellij.util.indexing.ValueContainer; import gnu.trove.TIntProcedure; +import java.util.Arrays; + import static com.intellij.util.indexing.DebugAssertions.EXTRA_SANITY_CHECKS; /** @@ -122,7 +124,6 @@ public class ChangeBufferingList implements Cloneable { if (randomAccessContainer == null) { int someElementsNumberEstimation = length; - int[] minMax = calcMinMax(changes, length); // todo we can check these lengths instead of only relying upon reaching MAX_FILES //int lengthOfBitSet = IdBitSet.sizeInBytes(minMax[1], minMax[0]); @@ -131,7 +132,7 @@ public class ChangeBufferingList implements Cloneable { if (someElementsNumberEstimation < MAX_FILES) { if (!hasRemovals) { if (mayHaveDupes) { - mergeChangesRemovingDupes(); + removingDupesAndSort(); } idSet = new SortedIdSet(currentChanges, length); @@ -144,7 +145,7 @@ public class ChangeBufferingList implements Cloneable { idSet = new IdBitSet(changes, length, 0); copyChanges = false; } else { - idSet = new IdBitSet(minMax, 0); + idSet = new IdBitSet(calcMinMax(changes, length), 0); } } else if (checkSet != null) { idSet = (RandomAccessIntContainer)randomAccessContainer.clone(); @@ -186,15 +187,40 @@ public class ChangeBufferingList implements Cloneable { } } - private void mergeChangesRemovingDupes() { // duplicated ids can be present for some index due to cancellation of indexing for next index - int[] currentChanges = changes; - ValueContainer.IntIterator sorted = SortedFileIdSetIterator.getTransientIterator(new ChangesIterator(currentChanges, length)); - int lastIndex = 0; - while(sorted.hasNext()) { - currentChanges[lastIndex++] = sorted.next(); - } + private void removingDupesAndSort() { // duplicated ids can be present for some index due to cancellation of indexing for next index + final int[] currentChanges = changes; + final int intLength = length; - length = (short)lastIndex; + if (intLength < 250) { // Plain sorting in Arrays works without allocations for small number of elements (see DualPivotQuicksort.QUICKSORT_THRESHOLD) + Arrays.sort(currentChanges, 0, intLength); + boolean hasDupes = false; + + for(int i = 0, max = intLength - 1; i < max; ++i) { + if (currentChanges[i] == currentChanges[i + 1]) { + hasDupes = true; + break; + } + } + + if (hasDupes) { + int ptr = 0; + for(int i = 1; i < intLength; ++i) { + if (currentChanges[i] != currentChanges[ptr]) { + currentChanges[++ptr] = currentChanges[i]; + } + } + length = (short)(ptr + 1); + } + } else { + ValueContainer.IntIterator sorted = + SortedFileIdSetIterator.getTransientIterator(new ChangesIterator(currentChanges, length, false)); + int lastIndex = 0; + while (sorted.hasNext()) { + currentChanges[lastIndex++] = sorted.next(); + } + + length = (short)lastIndex; + } mayHaveDupes = false; } @@ -262,21 +288,22 @@ public class ChangeBufferingList implements Cloneable { if (currentChanges != null) { if (mayHaveDupes) { synchronized (currentChanges) { - if (mayHaveDupes) mergeChangesRemovingDupes(); + if (mayHaveDupes) removingDupesAndSort(); } } - return new ChangesIterator(currentChanges, length); + return new ChangesIterator(currentChanges, length, true); } } return getRandomAccessContainer().intIterator(); } - public ValueContainer.IntIterator rawIntIterator() { - RandomAccessIntContainer intContainer = randomAccessContainer; - if (intContainer == null && !hasRemovals) { - return new ChangesIterator(changes, length); // dupes are possible + public ValueContainer.IntIterator sortedIntIterator() { + ValueContainer.IntIterator intIterator = intIterator(); + + if (!intIterator.hasAscendingOrder()) { + intIterator = SortedFileIdSetIterator.getTransientIterator(intIterator); } - return getRandomAccessContainer().intIterator(); + return intIterator; } public IdSet getCheckSet() { @@ -287,10 +314,12 @@ public class ChangeBufferingList implements Cloneable { private int cursor; private final int length; private final int[] changes; + private final boolean sorted; - ChangesIterator(int[] _changes, int _length) { + ChangesIterator(int[] _changes, int _length, boolean _sorted) { changes = _changes; length = _length; + sorted = _sorted; } @Override @@ -312,12 +341,12 @@ public class ChangeBufferingList implements Cloneable { @Override public boolean hasAscendingOrder() { - return false; + return sorted; } @Override public ValueContainer.IntIterator createCopyInInitialState() { - return new ChangesIterator(changes, length); + return new ChangesIterator(changes, length, sorted); } } } diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/TextEditorLocation.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/TextEditorLocation.java index 9477beb04a11..ef1c4ed6dd23 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/TextEditorLocation.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/TextEditorLocation.java @@ -50,7 +50,7 @@ public class TextEditorLocation implements FileEditorLocation { } @Override - public int compareTo(FileEditorLocation fileEditorLocation) { + public int compareTo(@NotNull FileEditorLocation fileEditorLocation) { TextEditorLocation otherLocation = (TextEditorLocation)fileEditorLocation; if (myEditor != otherLocation.myEditor) { LOG.error("Different editors: " + myEditor + "; and " + otherLocation.myEditor); diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java index 841b46bf6148..9460fd2c3f36 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindow.java @@ -29,7 +29,7 @@ import java.awt.event.InputEvent; public interface ToolWindow extends BusyObject { - Key SHOW_CONTENT_ICON = new Key("ContentIcon"); + Key SHOW_CONTENT_ICON = new Key<>("ContentIcon"); /** * @exception IllegalStateException if tool window isn't installed. @@ -74,7 +74,7 @@ public interface ToolWindow extends BusyObject { /** * @exception IllegalStateException if tool window isn't installed. */ - void setAnchor(ToolWindowAnchor anchor, @Nullable Runnable runnable); + void setAnchor(@NotNull ToolWindowAnchor anchor, @Nullable Runnable runnable); /** * @exception IllegalStateException if tool window isn't installed. @@ -104,7 +104,7 @@ public interface ToolWindow extends BusyObject { /** * @exception IllegalStateException if tool window isn't installed. */ - void setType(ToolWindowType type, @Nullable Runnable runnable); + void setType(@NotNull ToolWindowType type, @Nullable Runnable runnable); /** * @return window icon. Returns null if window has no icon. diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowAnchor.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowAnchor.java index 1628a6f679bf..88f544d237de 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowAnchor.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowAnchor.java @@ -17,6 +17,7 @@ package com.intellij.openapi.wm; import com.intellij.ide.ui.UISettings; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -26,9 +27,10 @@ public final class ToolWindowAnchor { public static final ToolWindowAnchor BOTTOM = new ToolWindowAnchor("bottom"); public static final ToolWindowAnchor RIGHT = new ToolWindowAnchor("right"); + @NotNull private final String myText; - private ToolWindowAnchor(@NonNls String text){ + private ToolWindowAnchor(@NonNls @NotNull String text){ myText = text; } @@ -40,6 +42,7 @@ public final class ToolWindowAnchor { return this == TOP || this == BOTTOM; } + @NotNull public static ToolWindowAnchor get(int swingOrientationConstant) { switch(swingOrientationConstant) { case SwingConstants.TOP: @@ -56,12 +59,16 @@ public final class ToolWindowAnchor { } public boolean isSplitVertically() { - return (this == LEFT && !UISettings.getInstance().LEFT_HORIZONTAL_SPLIT) || (this == RIGHT && !UISettings.getInstance().RIGHT_HORIZONTAL_SPLIT); + return this == LEFT && !UISettings.getInstance().LEFT_HORIZONTAL_SPLIT + || this == RIGHT && !UISettings.getInstance().RIGHT_HORIZONTAL_SPLIT; } + @NotNull public static ToolWindowAnchor fromText(String anchor) { for (ToolWindowAnchor a : new ToolWindowAnchor[]{TOP, LEFT, BOTTOM, RIGHT}) { - if (a.myText.equals(anchor)) return a; + if (a.myText.equals(anchor)) { + return a; + } } throw new IllegalArgumentException("Unknown anchor constant: " + anchor); } diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java index 8baa090b2af2..96fbb41189ad 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowManager.java @@ -73,7 +73,7 @@ public abstract class ToolWindowManager { public abstract ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode); /** * @deprecated {@link ToolWindowManager#registerToolWindow(String, boolean, ToolWindowAnchor)} @@ -83,7 +83,7 @@ public abstract class ToolWindowManager { public abstract ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean canCloseContents); @@ -91,19 +91,31 @@ public abstract class ToolWindowManager { public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor); @NotNull - public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, boolean secondary); + public abstract ToolWindow registerToolWindow(@NotNull String id, + boolean canCloseContent, + @NotNull ToolWindowAnchor anchor, + boolean secondary); @NotNull - public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, Disposable parentDisposable, boolean canWorkInDumbMode); + public abstract ToolWindow registerToolWindow(@NotNull String id, + boolean canCloseContent, + @NotNull ToolWindowAnchor anchor, + @NotNull Disposable parentDisposable, + boolean canWorkInDumbMode); @NotNull - public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, Disposable parentDisposable, boolean canWorkInDumbMode, boolean secondary); + public abstract ToolWindow registerToolWindow(@NotNull String id, + boolean canCloseContent, + @NotNull ToolWindowAnchor anchor, + @NotNull Disposable parentDisposable, + boolean canWorkInDumbMode, + boolean secondary); @NotNull public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor, - final Disposable parentDisposable) { + @NotNull Disposable parentDisposable) { return registerToolWindow(id, canCloseContent, anchor, parentDisposable, false); } diff --git a/platform/platform-impl/src/com/intellij/designer/LightToolWindow.java b/platform/platform-impl/src/com/intellij/designer/LightToolWindow.java index 7bdb59ea19e2..b1b8a84de370 100644 --- a/platform/platform-impl/src/com/intellij/designer/LightToolWindow.java +++ b/platform/platform-impl/src/com/intellij/designer/LightToolWindow.java @@ -46,9 +46,9 @@ import java.awt.event.*; * @author Alexander Lobas */ public class LightToolWindow extends JPanel { - public static final String LEFT_MIN_KEY = "left"; - public static final String RIGHT_MIN_KEY = "right"; - public static final int MINIMIZE_WIDTH = 25; + static final String LEFT_MIN_KEY = "left"; + static final String RIGHT_MIN_KEY = "right"; + static final int MINIMIZE_WIDTH = 25; private static final String IGNORE_WIDTH_KEY = "ignore_width"; private final LightToolWindowContent myContent; @@ -139,12 +139,14 @@ public class LightToolWindow extends JPanel { add(contentWrapper, BorderLayout.CENTER); addMouseListener(new MouseAdapter() { + @Override public void mouseReleased(final MouseEvent e) { IdeFocusManager.getInstance(myProject).requestFocus(myFocusedComponent, true); } }); addMouseListener(new PopupHandler() { + @Override public void invokePopup(Component component, int x, int y) { showGearPopup(component, x, y); } @@ -167,12 +169,9 @@ public class LightToolWindow extends JPanel { return myAnchor; } }; - myMinimizeButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - myMinimizeButton.setSelected(false); - updateContent(true, true); - } + myMinimizeButton.addActionListener(e -> { + myMinimizeButton.setSelected(false); + updateContent(true, true); }); myMinimizeButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5)); myMinimizeButton.setFocusable(false); @@ -233,7 +232,7 @@ public class LightToolWindow extends JPanel { } } - public void updateAnchor(ToolWindowAnchor newAnchor) { + void updateAnchor(ToolWindowAnchor newAnchor) { JComponent minimizeParent = myContentSplitter.getInnerComponent(); minimizeParent.putClientProperty(IGNORE_WIDTH_KEY, Boolean.TRUE); @@ -374,7 +373,7 @@ public class LightToolWindow extends JPanel { } private class GearAction extends AnAction { - public GearAction() { + GearAction() { Presentation presentation = getTemplatePresentation(); presentation.setIcon(AllIcons.General.Gear); presentation.setHoveredIcon(AllIcons.General.GearHover); @@ -462,7 +461,7 @@ public class LightToolWindow extends JPanel { } private class ToggleWindowedModeAction extends ToggleTypeModeAction { - public ToggleWindowedModeAction() { + ToggleWindowedModeAction() { super(ToolWindowType.WINDOWED, InternalDecorator.TOGGLE_WINDOWED_MODE_ACTION_ID); } @@ -475,7 +474,7 @@ public class LightToolWindow extends JPanel { private class ToggleTypeModeAction extends ToggleAction { private final ToolWindowType myType; - public ToggleTypeModeAction(ToolWindowType type, String id) { + ToggleTypeModeAction(@NotNull ToolWindowType type, @NotNull String id) { myType = type; copyFrom(ActionManager.getInstance().getAction(id)); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SaveDocumentAction.java b/platform/platform-impl/src/com/intellij/ide/actions/SaveDocumentAction.java index 5ad331ae5a67..d63683f09f28 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/SaveDocumentAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/SaveDocumentAction.java @@ -1,17 +1,16 @@ package com.intellij.ide.actions; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.DumbAwareAction; /** * @author yole */ -public class SaveDocumentAction extends AnAction { +public class SaveDocumentAction extends DumbAwareAction { @Override public void actionPerformed(AnActionEvent e) { Document doc = getDocument(e); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/ex/DefaultFrameEditorComponentProvider.java b/platform/platform-impl/src/com/intellij/openapi/wm/ex/DefaultFrameEditorComponentProvider.java index efab9e503b62..96346063e4a4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/ex/DefaultFrameEditorComponentProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/ex/DefaultFrameEditorComponentProvider.java @@ -2,6 +2,7 @@ package com.intellij.openapi.wm.ex; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -10,8 +11,8 @@ import javax.swing.*; */ public class DefaultFrameEditorComponentProvider implements FrameEditorComponentProvider { @Override - public JComponent createEditorComponent(Project project) { + public JComponent createEditorComponent(@NotNull Project project) { FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project); - return editorManager.getComponent(); + return editorManager.getComponent(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/ex/FrameEditorComponentProvider.java b/platform/platform-impl/src/com/intellij/openapi/wm/ex/FrameEditorComponentProvider.java index f6fce90c56ab..5f012185e89e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/ex/FrameEditorComponentProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/ex/FrameEditorComponentProvider.java @@ -2,14 +2,16 @@ package com.intellij.openapi.wm.ex; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; import javax.swing.*; /** * @author Konstantin Bulenkov */ +@FunctionalInterface public interface FrameEditorComponentProvider { ExtensionPointName EP = ExtensionPointName.create("com.intellij.frameEditorComponentProvider"); - JComponent createEditorComponent(Project project); + JComponent createEditorComponent(@NotNull Project project); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java b/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java index d8414ddc37ed..f38d3bab16b2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/ex/ToolWindowManagerEx.java @@ -35,9 +35,9 @@ public abstract class ToolWindowManagerEx extends ToolWindowManager { return (ToolWindowManagerEx)getInstance(project); } - public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l); - public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l, @NotNull Disposable parentDisposable); - public abstract void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l); + public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener); + public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener, @NotNull Disposable parentDisposable); + public abstract void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener listener); /** * @return ID of tool window that was activated last time. @@ -69,5 +69,6 @@ public abstract class ToolWindowManagerEx extends ToolWindowManager { public abstract void hideToolWindow(@NotNull String id, boolean hideSide); + @NotNull public abstract List getIdsOn(@NotNull ToolWindowAnchor anchor); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ActiveStack.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ActiveStack.java index ef8cdf338406..f99d3e221238 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ActiveStack.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ActiveStack.java @@ -15,8 +15,10 @@ */ package com.intellij.openapi.wm.impl; +import com.intellij.util.containers.Stack; +import org.jetbrains.annotations.NotNull; + import java.util.Iterator; -import java.util.Stack; /** * Actually this class represent two stacks. @@ -43,8 +45,8 @@ final class ActiveStack { * Creates enabled window stack. */ ActiveStack() { - myStack = new Stack(); - myPersistentStack = new Stack(); + myStack = new Stack<>(); + myPersistentStack = new Stack<>(); } /** @@ -61,10 +63,12 @@ final class ActiveStack { return myStack.isEmpty(); } + @NotNull String pop() { return myStack.pop(); } + @NotNull String peek() { return myStack.peek(); } @@ -73,10 +77,12 @@ final class ActiveStack { return myStack.size(); } - String peek(int i) { + @NotNull + private String peek(int i) { return myStack.get(getSize() - i - 1); } + @NotNull String[] getStack() { String[] result = new String[getSize()]; for (int i = 0; i < getSize(); i++) { @@ -85,6 +91,7 @@ final class ActiveStack { return result; } + @NotNull String[] getPersistentStack() { String[] result = new String[getPersistentSize()]; for (int i = 0; i < getPersistentSize(); i++) { @@ -93,7 +100,7 @@ final class ActiveStack { return result; } - void push(final String id) { + void push(@NotNull String id) { remove(id, true); myStack.push(id); myPersistentStack.push(id); @@ -106,6 +113,7 @@ final class ActiveStack { /** * Peeks element at the persistent stack. 0 means the top of the stack. */ + @NotNull String peekPersistent(final int index) { return myPersistentStack.get(myPersistentStack.size() - index - 1); } @@ -117,7 +125,7 @@ final class ActiveStack { * @param removePersistentAlso if true then clears last active ID * if it's the last active ID. */ - void remove(final String id, final boolean removePersistentAlso) { + void remove(@NotNull String id, final boolean removePersistentAlso) { for (Iterator i = myStack.iterator(); i.hasNext();) { if (id.equals(i.next())) { i.remove(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/DesktopLayout.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/DesktopLayout.java index 62c77fcb1357..a3cc0dea6e31 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/DesktopLayout.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/DesktopLayout.java @@ -36,11 +36,11 @@ public final class DesktopLayout implements JDOMExternalizable { /** * Map between ids and registered WindowInfos. */ - private final Map myRegisteredId2Info; + private final Map myRegisteredId2Info = new HashMap<>(); /** * Map between ids and unregistered WindowInfos. */ - private final Map myUnregisteredId2Info; + private final Map myUnregisteredId2Info = new HashMap<>(); /** * */ @@ -63,19 +63,15 @@ public final class DesktopLayout implements JDOMExternalizable { * if the cached data is invalid. */ private WindowInfoImpl[] myAllInfos; - @NonNls public static final String ID_ATTR = "id"; + @NonNls private static final String ID_ATTR = "id"; - public DesktopLayout() { - myRegisteredId2Info = new HashMap(); - myUnregisteredId2Info = new HashMap(); - } /** * Copies itself from the passed * * @param layout to be copied. */ - public final void copyFrom(final DesktopLayout layout) { + public final void copyFrom(@NotNull DesktopLayout layout) { final WindowInfoImpl[] infos = layout.getAllInfos(); for (WindowInfoImpl info1 : infos) { WindowInfoImpl info = myRegisteredId2Info.get(info1.getId()); @@ -128,7 +124,7 @@ public final class DesktopLayout implements JDOMExternalizable { return info; } - final void unregister(final String id) { + final void unregister(@NotNull String id) { final WindowInfoImpl info = myRegisteredId2Info.remove(id).copy(); myUnregisteredId2Info.put(id, info); // invalidate caches @@ -142,14 +138,12 @@ public final class DesktopLayout implements JDOMExternalizable { * If onlyRegistered is true then returns not null * value if and only if window with id is registered one. */ - final WindowInfoImpl getInfo(final String id, final boolean onlyRegistered) { + final WindowInfoImpl getInfo(String id, final boolean onlyRegistered) { final WindowInfoImpl info = myRegisteredId2Info.get(id); if (onlyRegistered || info != null) { return info; } - else { - return myUnregisteredId2Info.get(id); - } + return myUnregisteredId2Info.get(id); } @Nullable @@ -166,6 +160,7 @@ public final class DesktopLayout implements JDOMExternalizable { /** * @return WindowInfos for all registered tool windows. */ + @NotNull final WindowInfoImpl[] getInfos() { if (myRegisteredInfos == null) { myRegisteredInfos = myRegisteredId2Info.values().toArray(new WindowInfoImpl[myRegisteredId2Info.size()]); @@ -176,6 +171,7 @@ public final class DesktopLayout implements JDOMExternalizable { /** * @return WindowInfoss for all windows that are currently unregistered. */ + @NotNull private WindowInfoImpl[] getUnregisteredInfos() { if (myUnregisteredInfos == null) { myUnregisteredInfos = myUnregisteredId2Info.values().toArray(new WindowInfoImpl[myUnregisteredId2Info.size()]); @@ -186,7 +182,8 @@ public final class DesktopLayout implements JDOMExternalizable { /** * @return WindowInfos of all (registered and unregistered) tool windows. */ - WindowInfoImpl[] getAllInfos() { + @NotNull + private WindowInfoImpl[] getAllInfos() { final WindowInfoImpl[] registeredInfos = getInfos(); final WindowInfoImpl[] unregisteredInfos = getUnregisteredInfos(); myAllInfos = ArrayUtil.mergeArrays(registeredInfos, unregisteredInfos); @@ -197,9 +194,10 @@ public final class DesktopLayout implements JDOMExternalizable { * @return all (registered and not unregistered) WindowInfos for the specified anchor. * Returned infos are sorted by order. */ - private WindowInfoImpl[] getAllInfos(final ToolWindowAnchor anchor) { + @NotNull + private WindowInfoImpl[] getAllInfos(@NotNull ToolWindowAnchor anchor) { WindowInfoImpl[] infos = getAllInfos(); - final ArrayList list = new ArrayList(infos.length); + final ArrayList list = new ArrayList<>(infos.length); for (WindowInfoImpl info : infos) { if (anchor == info.getAnchor()) { list.add(info); @@ -214,7 +212,7 @@ public final class DesktopLayout implements JDOMExternalizable { * Normalizes order of windows in the passed array. Note, that array should be * sorted by order (by ascending). Order of first window will be 0. */ - private static void normalizeOrder(final WindowInfoImpl[] infos) { + private static void normalizeOrder(@NotNull WindowInfoImpl[] infos) { for (int i = 0; i < infos.length; i++) { infos[i].setOrder(i); } @@ -228,7 +226,8 @@ public final class DesktopLayout implements JDOMExternalizable { * @return comparator which compares StripeButtons in the stripe with * specified anchor. */ - final Comparator comparator(final ToolWindowAnchor anchor) { + @NotNull + final Comparator comparator(@NotNull ToolWindowAnchor anchor) { return new MyStripeButtonComparator(anchor); } @@ -237,7 +236,7 @@ public final class DesktopLayout implements JDOMExternalizable { * @return maximum ordinal number in the specified stripe. Returns -1 * if there is no any tool window with the specified anchor. */ - private int getMaxOrder(final ToolWindowAnchor anchor) { + private int getMaxOrder(@NotNull ToolWindowAnchor anchor) { int res = -1; final WindowInfoImpl[] infos = getAllInfos(); for (final WindowInfoImpl info : infos) { @@ -255,7 +254,7 @@ public final class DesktopLayout implements JDOMExternalizable { * @param newAnchor new anchor * @param newOrder new order */ - final void setAnchor(final String id, final ToolWindowAnchor newAnchor, int newOrder) { + final void setAnchor(@NotNull String id, @NotNull ToolWindowAnchor newAnchor, int newOrder) { if (newOrder == -1) { // if order isn't defined then the window will the last in the stripe newOrder = getMaxOrder(newAnchor) + 1; } @@ -279,11 +278,12 @@ public final class DesktopLayout implements JDOMExternalizable { } } - final void setSplitMode(final String id, boolean split) { + final void setSplitMode(@NotNull String id, boolean split) { final WindowInfoImpl info = getInfo(id, true); info.setSplit(split); } + @Override public final void readExternal(final Element layoutElement) { myUnregisteredInfos = null; for (Object o : layoutElement.getChildren()) { @@ -301,6 +301,7 @@ public final class DesktopLayout implements JDOMExternalizable { } } + @Override public final void writeExternal(final Element layoutElement) { final WindowInfoImpl[] infos = getAllInfos(); for (WindowInfoImpl info : infos) { @@ -310,30 +311,30 @@ public final class DesktopLayout implements JDOMExternalizable { } } - public List getVisibleIdsOn(final ToolWindowAnchor anchor, ToolWindowManagerImpl manager) { - ArrayList ids = new ArrayList(); + @NotNull + List getVisibleIdsOn(@NotNull ToolWindowAnchor anchor, @NotNull ToolWindowManagerImpl manager) { + List ids = new ArrayList<>(); for (WindowInfoImpl each : getAllInfos(anchor)) { - if (manager == null) break; - final ToolWindow window = manager.getToolWindow(each.getId()); - if (window == null) continue; - if (window.isAvailable() || UISettings.getInstance().ALWAYS_SHOW_WINDOW_BUTTONS) { - ids.add(each.getId()); - } + final ToolWindow window = manager.getToolWindow(each.getId()); + if (window == null) continue; + if (window.isAvailable() || UISettings.getInstance().ALWAYS_SHOW_WINDOW_BUTTONS) { + ids.add(each.getId()); + } } return ids; } private static final class MyWindowInfoComparator implements Comparator { + @Override public int compare(final WindowInfoImpl info1, final WindowInfoImpl info2) { return info1.getOrder() - info2.getOrder(); } } private final class MyStripeButtonComparator implements Comparator { - private final HashMap myId2Info; + private final HashMap myId2Info = new HashMap<>(); - public MyStripeButtonComparator(final ToolWindowAnchor anchor) { - myId2Info = new HashMap(); + public MyStripeButtonComparator(@NotNull ToolWindowAnchor anchor) { final WindowInfoImpl[] infos = getInfos(); for (final WindowInfoImpl info : infos) { if (anchor == info.getAnchor()) { @@ -342,6 +343,7 @@ public final class DesktopLayout implements JDOMExternalizable { } } + @Override public final int compare(final StripeButton obj1, final StripeButton obj2) { final WindowInfoImpl info1 = myId2Info.get(obj1.getWindowInfo().getId()); final int order1 = info1 != null ? info1.getOrder() : 0; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java index dabd6ada57f2..c3d0bc2f54fb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java @@ -28,6 +28,7 @@ import com.intellij.ui.JBColor; import com.intellij.ui.ScreenUtil; import com.intellij.util.Alarm; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; @@ -66,7 +67,7 @@ public final class FloatingDecorator extends JDialog { private float myEndRatio; // start and end alpha ratio for transparency animation - FloatingDecorator(final IdeFrameImpl owner,final WindowInfoImpl info,final InternalDecorator internalDecorator){ + FloatingDecorator(final IdeFrameImpl owner, @NotNull WindowInfoImpl info, @NotNull InternalDecorator internalDecorator){ super(owner,internalDecorator.getToolWindow().getId()); MnemonicHelper.init(getContentPane()); myInternalDecorator=internalDecorator; @@ -154,7 +155,7 @@ public final class FloatingDecorator extends JDialog { super.dispose(); } - final void apply(final WindowInfoImpl info){ + final void apply(@NotNull WindowInfoImpl info){ LOG.assertTrue(info.isFloating()); myInfo=info; // Set alpha mode diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java index 2dcec6aed305..a214765244fa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -116,7 +116,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr } @Override - protected void toolWindowTypeChanged(ToolWindowType type) { + protected void toolWindowTypeChanged(@NotNull ToolWindowType type) { fireTypeChanged(type); } @@ -214,7 +214,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr myProject = null; } - private void fireAnchorChanged(ToolWindowAnchor anchor) { + private void fireAnchorChanged(@NotNull ToolWindowAnchor anchor) { myDispatcher.getMulticaster().anchorChanged(this, anchor); } @@ -243,7 +243,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr myDispatcher.getMulticaster().activated(this); } - private void fireTypeChanged(ToolWindowType type) { + private void fireTypeChanged(@NotNull ToolWindowType type) { myDispatcher.getMulticaster().typeChanged(this, type); } @@ -255,7 +255,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr myDispatcher.getMulticaster().sideStatusChanged(this, isSide); } - private void fireContentUiTypeChanges(ToolWindowContentUiType type) { + private void fireContentUiTypeChanges(@NotNull ToolWindowContentUiType type) { myDispatcher.getMulticaster().contentUiTypeChanges(this, type); } @@ -512,9 +512,9 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr } private final class ChangeAnchorAction extends AnAction implements DumbAware { - private final ToolWindowAnchor myAnchor; + @NotNull private final ToolWindowAnchor myAnchor; - public ChangeAnchorAction(final String title, final ToolWindowAnchor anchor) { + public ChangeAnchorAction(@NotNull String title, @NotNull ToolWindowAnchor anchor) { super(title); myAnchor = anchor; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecoratorListener.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecoratorListener.java index b59657225a06..38bba5916e71 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecoratorListener.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecoratorListener.java @@ -27,23 +27,23 @@ import java.util.EventListener; */ interface InternalDecoratorListener extends EventListener{ - public void anchorChanged(InternalDecorator source,ToolWindowAnchor anchor); + void anchorChanged(@NotNull InternalDecorator source, @NotNull ToolWindowAnchor anchor); - public void autoHideChanged(InternalDecorator source,boolean autoHide); + void autoHideChanged(@NotNull InternalDecorator source, boolean autoHide); - public void hidden(InternalDecorator source); + void hidden(@NotNull InternalDecorator source); - public void hiddenSide(InternalDecorator source); + void hiddenSide(@NotNull InternalDecorator source); - public void resized(InternalDecorator source); + void resized(@NotNull InternalDecorator source); - public void activated(InternalDecorator source); + void activated(@NotNull InternalDecorator source); - public void typeChanged(InternalDecorator source,ToolWindowType type); + void typeChanged(@NotNull InternalDecorator source, @NotNull ToolWindowType type); - public void sideStatusChanged(InternalDecorator source,boolean isSideTool); + void sideStatusChanged(@NotNull InternalDecorator source, boolean isSideTool); - public void contentUiTypeChanges(InternalDecorator sources, @NotNull ToolWindowContentUiType type); + void contentUiTypeChanges(@NotNull InternalDecorator sources, @NotNull ToolWindowContentUiType type); - public void visibleStripeButtonChanged(InternalDecorator source, boolean visible); + void visibleStripeButtonChanged(@NotNull InternalDecorator source, boolean visible); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/Stripe.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/Stripe.java index 53124343ae01..a381b93e5168 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/Stripe.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/Stripe.java @@ -28,6 +28,7 @@ import com.intellij.ui.ColorUtil; import com.intellij.ui.Gray; import com.intellij.ui.ScreenUtil; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.Border; @@ -166,7 +167,7 @@ final class Stripe extends JPanel implements UISettingsListener { super.removeNotify(); } - void addButton(final StripeButton button, final Comparator comparator) { + void addButton(@NotNull StripeButton button, final Comparator comparator) { myPrefSize = null; myButtons.add(button); Collections.sort(myButtons, comparator); @@ -174,7 +175,7 @@ final class Stripe extends JPanel implements UISettingsListener { revalidate(); } - void removeButton(final StripeButton button) { + void removeButton(@NotNull StripeButton button) { myPrefSize = null; myButtons.remove(button); remove(button); @@ -475,7 +476,7 @@ final class Stripe extends JPanel implements UISettingsListener { } } - public boolean containsScreen(final Rectangle screenRec) { + public boolean containsScreen(@NotNull Rectangle screenRec) { final Point point = screenRec.getLocation(); SwingUtilities.convertPointFromScreen(point, this); return new Rectangle(point, screenRec.getSize()).intersects( diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java index 66633a9f6d83..dc3c222572be 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java @@ -49,7 +49,6 @@ import javax.swing.plaf.PanelUI; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; -import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; @@ -74,7 +73,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS private final DefaultActionGroup myActionGroup = new DefaultActionGroup(); private List myVisibleActions = ContainerUtil.newArrayListWithCapacity(2); - public ToolWindowHeader(final ToolWindowImpl toolWindow, @NotNull WindowInfoImpl info, @NotNull final Producer gearProducer) { + ToolWindowHeader(final ToolWindowImpl toolWindow, @NotNull WindowInfoImpl info, @NotNull final Producer gearProducer) { setLayout(new BorderLayout()); myToolWindow = toolWindow; @@ -89,7 +88,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS Component c = getComponent(0); Dimension size = c.getPreferredSize(); - if (size.width < (r.width - insets.left - insets.right)) { + if (size.width < r.width - insets.left - insets.right) { c.setBounds(insets.left, insets.top, size.width, r.height - insets.top - insets.bottom); } else { c.setBounds(insets.left, insets.top, r.width - insets.left - insets.right, r.height - insets.top - insets.bottom); @@ -170,6 +169,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS myButtonPanel = eastPanel; westPanel.addMouseListener(new PopupHandler() { + @Override public void invokePopup(final Component comp, final int x, final int y) { toolWindow.getContentUI().showContextMenu(comp, x, y, toolWindow.getPopupGroup(), toolWindow.getContentManager().getSelectedContent()); } @@ -182,6 +182,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS }); addMouseListener(new MouseAdapter() { + @Override public void mouseReleased(final MouseEvent e) { if (!e.isPopupTrigger()) { if (UIUtil.isCloseClick(e, MouseEvent.MOUSE_RELEASED)) { @@ -227,7 +228,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS @Override public void mouseReleased(final MouseEvent e) { Runnable runnable = - () -> ToolWindowHeader.this.dispatchEvent(SwingUtilities.convertMouseEvent(e.getComponent(), e, ToolWindowHeader.this)); + () -> dispatchEvent(SwingUtilities.convertMouseEvent(e.getComponent(), e, ToolWindowHeader.this)); //noinspection SSBasedInspection SwingUtilities.invokeLater(runnable); } @@ -253,7 +254,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS myInfo = null; } - public void setAdditionalTitleActions(AnAction[] actions) { + void setAdditionalTitleActions(AnAction[] actions) { myActionGroup.removeAll(); myActionGroup.addAll(actions); myUpdater.updateActions(false, true); @@ -300,7 +301,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS if (anchor == ToolWindowAnchor.BOTTOM) { return AllIcons.General.HideDownPart; } - else if (anchor == ToolWindowAnchor.RIGHT) { + if (anchor == ToolWindowAnchor.RIGHT) { return AllIcons.General.HideRightPart; } @@ -312,7 +313,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS if (anchor == ToolWindowAnchor.BOTTOM) { return AllIcons.General.HideDown; } - else if (anchor == ToolWindowAnchor.RIGHT) { + if (anchor == ToolWindowAnchor.RIGHT) { return AllIcons.General.HideRight; } @@ -324,7 +325,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS if (anchor == ToolWindowAnchor.BOTTOM) { return AllIcons.General.HideDownPartHover; } - else if (anchor == ToolWindowAnchor.RIGHT) { + if (anchor == ToolWindowAnchor.RIGHT) { return AllIcons.General.HideRightPartHover; } @@ -336,7 +337,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS if (anchor == ToolWindowAnchor.BOTTOM) { return AllIcons.General.HideDownHover; } - else if (anchor == ToolWindowAnchor.RIGHT) { + if (anchor == ToolWindowAnchor.RIGHT) { return AllIcons.General.HideRightHover; } @@ -419,7 +420,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS protected abstract void sideHidden(); - protected abstract void toolWindowTypeChanged(ToolWindowType type); + protected abstract void toolWindowTypeChanged(@NotNull ToolWindowType type); @Override public Dimension getPreferredSize() { @@ -468,18 +469,15 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS setIcon(getActiveIcon(), getInactiveIcon() == null ? getActiveIcon() : getInactiveIcon(), getActiveHoveredIcon()); - PropertyChangeListener listener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (myAlternativeAction == null) return; - if ("ancestor".equals(evt.getPropertyName())) { - if (evt.getNewValue() == null) { - AltStateManager.getInstance().removeListener(ActionButton.this); - switchAlternativeAction(false); - } - else { - AltStateManager.getInstance().addListener(ActionButton.this); - } + PropertyChangeListener listener = evt -> { + if (myAlternativeAction == null) return; + if ("ancestor".equals(evt.getPropertyName())) { + if (evt.getNewValue() == null) { + AltStateManager.getInstance().removeListener(this); + switchAlternativeAction(false); + } + else { + AltStateManager.getInstance().addListener(this); } } }; @@ -487,7 +485,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS addPropertyChangeListener(listener); } - public void updateTooltip() { + void updateTooltip() { myButton.setToolTipText(getToolTipTextByAction(myCurrentAction)); } @@ -533,6 +531,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS this(action, activeIcon, activeIcon); } + @Override public void actionPerformed(final ActionEvent e) { AnAction action = myAlternativeAction != null && BitUtil.isSet(e.getModifiers(), InputEvent.ALT_MASK) ? myAlternativeAction : myAction; @@ -557,6 +556,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS myButton.setIcons(active, inactive, hovered); } + @Override public void setToolTipText(final String text) { myButton.setToolTipText(text); } @@ -588,15 +588,17 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS } private abstract class HideSideAction extends AnAction implements DumbAware { - @NonNls public static final String HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID; + @NonNls static final String HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID; public HideSideAction() { copyFrom(ActionManager.getInstance().getAction(HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID)); getTemplatePresentation().setText(UIBundle.message("tool.window.hideSide.action.name")); } + @Override public abstract void actionPerformed(@NotNull final AnActionEvent e); + @Override public final void update(@NotNull final AnActionEvent event) { final Presentation presentation = event.getPresentation(); presentation.setEnabled(myInfo.isVisible()); @@ -604,13 +606,14 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS } private abstract class HideAction extends AnAction implements DumbAware { - @NonNls public static final String HIDE_ACTIVE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_WINDOW_ACTION_ID; + @NonNls static final String HIDE_ACTIVE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_WINDOW_ACTION_ID; public HideAction() { copyFrom(ActionManager.getInstance().getAction(HIDE_ACTIVE_WINDOW_ACTION_ID)); getTemplatePresentation().setText(UIBundle.message("tool.window.hide.action.name")); } + @Override public final void update(@NotNull final AnActionEvent event) { final Presentation presentation = event.getPresentation(); presentation.setEnabled(myInfo.isVisible()); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java index 3c89e2642939..29f8cbeae9ca 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java @@ -53,9 +53,9 @@ import java.beans.PropertyChangeListener; import java.util.*; import java.util.List; -@SuppressWarnings({"ConstantConditions"}) +@SuppressWarnings("ConstantConditions") public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { - private final Map myToolWindows = new HashMap(); + private final Map myToolWindows = new HashMap<>(); private final Project myProject; public ToolWindowHeadlessManagerImpl(Project project) { @@ -75,12 +75,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { MockToolWindow tw = new MockToolWindow(myProject); myToolWindows.put(id, tw); if (parentDisposable != null) { - Disposer.register(parentDisposable, new Disposable() { - @Override - public void dispose() { - unregisterToolWindow(id); - } - }); + Disposer.register(parentDisposable, () -> unregisterToolWindow(id)); } return tw; } @@ -90,7 +85,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode) { return doRegisterToolWindow(id, parentDisposable); } @@ -106,7 +101,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean canCloseContents) { return doRegisterToolWindow(id, parentDisposable); @@ -139,7 +134,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { @NotNull @Override public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor, - final Disposable parentDisposable, final boolean dumbAware) { + @NotNull final Disposable parentDisposable, final boolean dumbAware) { return doRegisterToolWindow(id, parentDisposable); } @@ -148,7 +143,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { public ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean secondary) { return doRegisterToolWindow(id, parentDisposable); @@ -222,16 +217,16 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { } @Override - public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { + public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) { } @Override - public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l, @NotNull Disposable parentDisposable) { + public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener, @NotNull Disposable parentDisposable) { } @Override - public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { + public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) { } @Override @@ -270,9 +265,10 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { public void hideToolWindow(@NotNull final String id, final boolean hideSide) { } + @NotNull @Override public List getIdsOn(@NotNull final ToolWindowAnchor anchor) { - return new ArrayList(); + return new ArrayList<>(); } public static class MockToolWindow implements ToolWindowEx { @@ -330,7 +326,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { } @Override - public void setAnchor(ToolWindowAnchor anchor, @Nullable Runnable runnable) { + public void setAnchor(@NotNull ToolWindowAnchor anchor, @Nullable Runnable runnable) { } @Override @@ -367,7 +363,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { } @Override - public void setType(ToolWindowType type, @Nullable Runnable runnable) { + public void setType(@NotNull ToolWindowType type, @Nullable Runnable runnable) { } @Override @@ -500,7 +496,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx { private static class MockContentManager implements ContentManager { private final EventDispatcher myDispatcher = EventDispatcher.create(ContentManagerListener.class); - private final List myContents = new ArrayList(); + private final List myContents = new ArrayList<>(); private Content mySelected; @NotNull diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java index d58f6ce9a646..c97831818eec 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -60,11 +60,11 @@ import java.util.Set; * @author Vladimir Kondratyev */ public final class ToolWindowImpl implements ToolWindowEx { - private final PropertyChangeSupport myChangeSupport; + private final PropertyChangeSupport myChangeSupport = new PropertyChangeSupport(this); private final ToolWindowManagerImpl myToolWindowManager; private final String myId; private final JComponent myComponent; - private boolean myAvailable; + private boolean myAvailable = true; private final ContentManager myContentManager; private Icon myIcon; private String myStripeTitle; @@ -74,18 +74,18 @@ public final class ToolWindowImpl implements ToolWindowEx { private InternalDecorator myDecorator; - private boolean myHideOnEmptyContent = false; + private boolean myHideOnEmptyContent; private boolean myPlaceholderMode; private ToolWindowFactory myContentFactory; - private static Set FORWARD_TRAVERSAL_KEYSTROKES = new HashSet(Arrays.asList( - new KeyStroke[] { + private static final Set FORWARD_TRAVERSAL_KEYSTROKES = new HashSet<>(Arrays.asList( + new KeyStroke[]{ KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0) } )); - private static Set BACKWARD_TRAVERSAL_KEYSTROKES = new HashSet(Arrays.asList( - new KeyStroke[] { + private static final Set BACKWARD_TRAVERSAL_KEYSTROKES = new HashSet<>(Arrays.asList( + new KeyStroke[]{ KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK) } )); @@ -102,16 +102,13 @@ public final class ToolWindowImpl implements ToolWindowEx { private static final Logger LOG = Logger.getInstance(ToolWindowImpl.class); - ToolWindowImpl(final ToolWindowManagerImpl toolWindowManager, final String id, boolean canCloseContent, @Nullable final JComponent component) { + ToolWindowImpl(@NotNull ToolWindowManagerImpl toolWindowManager, @NotNull String id, boolean canCloseContent, @Nullable final JComponent component) { myToolWindowManager = toolWindowManager; - myChangeSupport = new PropertyChangeSupport(this); myId = id; - myAvailable = true; final ContentFactory contentFactory = ServiceManager.getService(ContentFactory.class); myContentUI = new ToolWindowContentUi(this); - myContentManager = - contentFactory.createContentManager(myContentUI, canCloseContent, toolWindowManager.getProject()); + myContentManager = contentFactory.createContentManager(myContentUI, canCloseContent, toolWindowManager.getProject()); if (component != null) { final Content content = contentFactory.createContent(component, "", false); @@ -224,7 +221,7 @@ public final class ToolWindowImpl implements ToolWindowEx { public ActionCallback getReady(@NotNull final Object requestor) { final ActionCallback result = new ActionCallback(); myShowing.getReady(this).doWhenDone(() -> { - ArrayList cmd = new ArrayList(); + ArrayList cmd = new ArrayList<>(); cmd.add(new FinalizableCommand(null) { @Override public void run() { @@ -268,7 +265,7 @@ public final class ToolWindowImpl implements ToolWindowEx { } @Override - public final void setAnchor(final ToolWindowAnchor anchor, @Nullable final Runnable runnable) { + public final void setAnchor(@NotNull final ToolWindowAnchor anchor, @Nullable final Runnable runnable) { ApplicationManager.getApplication().assertIsDispatchThread(); myToolWindowManager.setToolWindowAnchor(myId, anchor); if (runnable != null) { @@ -330,7 +327,7 @@ public final class ToolWindowImpl implements ToolWindowEx { } @Override - public final void setType(final ToolWindowType type, @Nullable final Runnable runnable) { + public final void setType(@NotNull final ToolWindowType type, @Nullable final Runnable runnable) { ApplicationManager.getApplication().assertIsDispatchThread(); myToolWindowManager.setToolWindowType(myId, type); if (runnable != null) { @@ -416,6 +413,7 @@ public final class ToolWindowImpl implements ToolWindowEx { //return getSelectedContent().getIcon(); } + @NotNull public final String getId() { return myId; } @@ -531,11 +529,11 @@ public final class ToolWindowImpl implements ToolWindowEx { return myContentManager.isDisposed(); } - public boolean isPlaceholderMode() { + boolean isPlaceholderMode() { return myPlaceholderMode; } - public void setPlaceholderMode(final boolean placeholderMode) { + void setPlaceholderMode(final boolean placeholderMode) { myPlaceholderMode = placeholderMode; } @@ -546,7 +544,7 @@ public final class ToolWindowImpl implements ToolWindowEx { } @NotNull - public ActionCallback setActivation(@NotNull ActionCallback activation) { + ActionCallback setActivation(@NotNull ActionCallback activation) { if (!myActivation.isProcessed() && !myActivation.equals(activation)) { myActivation.setRejected(); } 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 977407222522..1fcbb33e3af1 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 @@ -95,26 +95,26 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private final Project myProject; private final WindowManagerEx myWindowManager; private final EventDispatcher myDispatcher = EventDispatcher.create(ToolWindowManagerListener.class); - private final DesktopLayout myLayout; - private final Map myId2InternalDecorator; - private final Map myId2FloatingDecorator; - private final Map myId2WindowedDecorator; - private final Map myId2StripeButton; - private final Map myId2FocusWatcher; + private final DesktopLayout myLayout = new DesktopLayout(); + private final Map myId2InternalDecorator = new HashMap<>(); + private final Map myId2FloatingDecorator = new HashMap<>(); + private final Map myId2WindowedDecorator = new HashMap<>(); + private final Map myId2StripeButton = new HashMap<>(); + private final Map myId2FocusWatcher = new HashMap<>(); private final Set myDumbAwareIds = Collections.synchronizedSet(ContainerUtil.newTroveSet()); - private final EditorComponentFocusWatcher myEditorComponentFocusWatcher; - private final MyToolWindowPropertyChangeListener myToolWindowPropertyChangeListener; - private final InternalDecoratorListener myInternalDecoratorListener; + private final EditorComponentFocusWatcher myEditorComponentFocusWatcher = new EditorComponentFocusWatcher(); + private final MyToolWindowPropertyChangeListener myToolWindowPropertyChangeListener = new MyToolWindowPropertyChangeListener(); + private final InternalDecoratorListener myInternalDecoratorListener = new MyInternalDecoratorListener(); private boolean myEditorWasActive; - private final ActiveStack myActiveStack; - private final SideStack mySideStack; + private final ActiveStack myActiveStack = new ActiveStack(); + private final SideStack mySideStack = new SideStack(); private ToolWindowsPane myToolWindowsPane; private IdeFrameImpl myFrame; - private DesktopLayout myLayoutToRestoreLater = null; + private DesktopLayout myLayoutToRestoreLater; @NonNls private static final String EDITOR_ELEMENT = "editor"; @NonNls private static final String ACTIVE_ATTR_VALUE = "active"; @NonNls private static final String FRAME_ELEMENT = "frame"; @@ -127,8 +127,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private final FileEditorManager myFileEditorManager; private final LafManager myLafManager; - private final Map myWindow2Balloon = new HashMap(); - private Pair myMaximizedToolwindowSize = null; + private final Map myWindow2Balloon = new HashMap<>(); private KeyState myCurrentState = KeyState.waiting; private final Alarm myWaiterForSecondPress = new Alarm(); @@ -139,7 +138,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }; private final PropertyChangeListener myFocusListener; - public boolean isToolWindowRegistered(String id) { + boolean isToolWindowRegistered(@NotNull String id) { return myLayout.isToolWindowRegistered(id); } @@ -148,7 +147,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } private final Alarm myUpdateHeadersAlarm = new Alarm(); - private final Runnable myUpdateHeadersRunnable = () -> updateToolWindowHeaders(); /** * invoked by reflection @@ -182,22 +180,8 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }, project); } - myLayout = new DesktopLayout(); myLayout.copyFrom(windowManagerEx.getLayout()); - myId2InternalDecorator = new HashMap(); - myId2FloatingDecorator = new HashMap(); - myId2WindowedDecorator = new HashMap(); - myId2StripeButton = new HashMap(); - myId2FocusWatcher = new HashMap(); - - myEditorComponentFocusWatcher = new EditorComponentFocusWatcher(); - myToolWindowPropertyChangeListener = new MyToolWindowPropertyChangeListener(); - myInternalDecoratorListener = new MyInternalDecoratorListener(); - - myActiveStack = new ActiveStack(); - mySideStack = new SideStack(); - project.getMessageBus().connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerListener() { @Override public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) { @@ -220,13 +204,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } }); - myFocusListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if ("focusOwner".equals(evt.getPropertyName())) { - myUpdateHeadersAlarm.cancelAllRequests(); - myUpdateHeadersAlarm.addRequest(myUpdateHeadersRunnable, 50); - } + myFocusListener = evt -> { + if ("focusOwner".equals(evt.getPropertyName())) { + myUpdateHeadersAlarm.cancelAllRequests(); + myUpdateHeadersAlarm.addRequest(this::updateToolWindowHeaders, 50); } }; KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(myFocusListener); @@ -253,7 +234,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }); } - public boolean dispatchKeyEvent(KeyEvent e) { + public boolean dispatchKeyEvent(@NotNull KeyEvent e) { if (e.getKeyCode() != KeyEvent.VK_CONTROL && e.getKeyCode() != KeyEvent.VK_ALT && e.getKeyCode() != KeyEvent.VK_SHIFT && @@ -299,8 +280,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements return false; } - public static Set getActivateToolWindowVKs() { - if (ApplicationManager.getApplication() == null) return new HashSet(); + @NotNull + private static Set getActivateToolWindowVKs() { + if (ApplicationManager.getApplication() == null) return new HashSet<>(); Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); Shortcut[] baseShortcut = keymap.getShortcuts("ActivateProjectToolWindow"); @@ -373,7 +355,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @Override public void disposeComponent() { - for (String id : new ArrayList(myId2StripeButton.keySet())) { + for (String id : new ArrayList<>(myId2StripeButton.keySet())) { unregisterToolWindow(id); } @@ -390,21 +372,17 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements UIManager.addPropertyChangeListener(uiManagerPropertyListener); myLafManager.addLafManagerListener(lafManagerListener); - Disposer.register(myProject, new Disposable() { - @Override - public void dispose() { - UIManager.removePropertyChangeListener(uiManagerPropertyListener); - myLafManager.removeLafManagerListener(lafManagerListener); - } + Disposer.register(myProject, () -> { + UIManager.removePropertyChangeListener(uiManagerPropertyListener); + myLafManager.removeLafManagerListener(lafManagerListener); }); myFrame = myWindowManager.allocateFrame(myProject); LOG.assertTrue(myFrame != null); - final ArrayList commandsList = new ArrayList(); - myToolWindowsPane = new ToolWindowsPane(myFrame, this); Disposer.register(myProject, myToolWindowsPane); ((IdeRootPane)myFrame.getRootPane()).setToolWindowsPane(myToolWindowsPane); + List commandsList = new ArrayList<>(); appendUpdateToolWindowsPaneCmd(commandsList); myFrame.setTitle(FrameTitleBuilder.getInstance().getProjectTitle(myProject)); @@ -432,13 +410,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }; myProject.getMessageBus().connect().subscribe(DumbService.DUMB_MODE, dumbModeListener); - StartupManager.getInstance(myProject).registerPostStartupActivity(new DumbAwareRunnable() { - @Override - public void run() { - registerToolWindowsFromBeans(); - if (DumbService.getInstance(myProject).isDumb()) { - disableStripeButtons(); - } + StartupManager.getInstance(myProject).registerPostStartupActivity((DumbAwareRunnable)() -> { + registerToolWindowsFromBeans(); + if (DumbService.getInstance(myProject).isDumb()) { + disableStripeButtons(); } }); @@ -446,7 +421,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements if (e instanceof KeyEvent) { dispatchKeyEvent((KeyEvent)e); } - if (e instanceof WindowEvent && (e.getID() == WindowEvent.WINDOW_LOST_FOCUS) && e.getSource() == myFrame) { + if (e instanceof WindowEvent && e.getID() == WindowEvent.WINDOW_LOST_FOCUS && e.getSource() == myFrame) { resetHoldState(); } return false; @@ -467,7 +442,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - private JComponent createEditorComponent(Project project) { + private static JComponent createEditorComponent(@NotNull Project project) { return FrameEditorComponentProvider.EP.getExtensions()[0].createEditorComponent(project); } @@ -542,19 +517,16 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements WindowInfoImpl info = getInfo(bean.id); if (!info.isSplit() && bean.secondary && !info.wasRead()) { - toolWindow.setSplitMode(bean.secondary, null); + toolWindow.setSplitMode(true, null); } final ActionCallback activation = toolWindow.setActivation(new ActionCallback()); - final DumbAwareRunnable runnable = new DumbAwareRunnable() { - @Override - public void run() { - if (toolWindow.isDisposed()) return; + final DumbAwareRunnable runnable = () -> { + if (toolWindow.isDisposed()) return; - toolWindow.ensureContentInitialized(); - activation.setDone(); - } + toolWindow.ensureContentInitialized(); + activation.setDone(); }; if (ApplicationManager.getApplication().isUnitTestMode()) { runnable.run(); @@ -566,7 +538,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @Override public void projectClosed() { - final ArrayList commandsList = new ArrayList(); final String[] ids = getToolWindowIds(); // Remove ToolWindowsPane @@ -574,6 +545,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements ((IdeRootPane)myFrame.getRootPane()).setToolWindowsPane(null); myWindowManager.releaseFrame(myFrame); } + List commandsList = new ArrayList<>(); appendUpdateToolWindowsPaneCmd(commandsList); // Hide all tool windows @@ -591,18 +563,18 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } @Override - public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { - myDispatcher.addListener(l); + public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) { + myDispatcher.addListener(listener); } @Override - public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l, @NotNull Disposable parentDisposable) { - myDispatcher.addListener(l, parentDisposable); + public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener, @NotNull Disposable parentDisposable) { + myDispatcher.addListener(listener, parentDisposable); } @Override - public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) { - myDispatcher.removeListener(l); + public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) { + myDispatcher.removeListener(listener); } /** @@ -641,7 +613,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements final ExpirableRunnable runnable = new ExpirableRunnable.ForProject(myProject) { @Override public void run() { - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); activateEditorComponentImpl(commandList, forced); execute(commandList); } @@ -669,15 +641,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - private void activateEditorComponentImpl(List commandList, final boolean forced) { + private void activateEditorComponentImpl(@NotNull List commandList, final boolean forced) { final String active = getActiveToolWindowId(); // Now we have to request focus into most recent focused editor appendRequestFocusInEditorComponentCmd(commandList, forced).doWhenDone(() -> { - final ArrayList commandList12 = new ArrayList(); - if (LOG.isDebugEnabled()) { LOG.debug("editor activated"); } + List commandList12 = new ArrayList<>(); deactivateWindows(null, commandList12); myActiveStack.clear(); @@ -688,9 +659,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @NotNull @Override public ActionCallback run() { - final ArrayList commandList1 = new ArrayList(); + List commandList1 = new ArrayList<>(); - final WindowInfoImpl toReactivate = getInfo(active); + final WindowInfoImpl toReactivate = active == null ? null : getInfo(active); final boolean reactivateLastActive = toReactivate != null && !isToHideOnDeactivation(toReactivate); deactivateWindows(reactivateLastActive ? active : null, commandList1); execute(commandList1); @@ -714,7 +685,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }); } - private void deactivateWindows( @Nullable String idToIgnore, final List commandList) { + private void deactivateWindows(@Nullable String idToIgnore, @NotNull List commandList) { final WindowInfoImpl[] infos = myLayout.getInfos(); for (final WindowInfoImpl info : infos) { if (idToIgnore != null && idToIgnore.equals(info.getId())) { @@ -736,11 +707,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements * * @param dirtyMode if true then all UI operations are performed in "dirty" mode. * It means that UI isn't validated and repainted just after each add/remove operation. - * @see ToolWindowManagerImpl#prepareForActivation */ - private void showAndActivate(final String id, + private void showAndActivate(@NotNull String id, final boolean dirtyMode, - List commandsList, + @NotNull List commandsList, boolean autoFocusContents, boolean forcedFocusRequest) { if (!getToolWindow(id).isAvailable()) { @@ -766,7 +736,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - void activateToolWindow(final String id, boolean forced, boolean autoFocusContents) { + void activateToolWindow(@NotNull String id, boolean forced, boolean autoFocusContents) { if (LOG.isDebugEnabled()) { LOG.debug("enter: activateToolWindow(" + id + ")"); } @@ -776,13 +746,13 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements return; } - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); activateToolWindowImpl(id, commandList, forced, autoFocusContents); execute(commandList); } - private void activateToolWindowImpl(final String id, - List commandList, + private void activateToolWindowImpl(@NotNull String id, + @NotNull List commandList, boolean forced, boolean autoFocusContents) { if (!FocusManagerImpl.getInstance().isUnforcedRequestAllowed() && !forced) return; @@ -810,7 +780,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements * * @throws IllegalStateException if tool window isn't installed. */ - private void checkId(final String id) { + private void checkId(@NotNull String id) { if (!myLayout.isToolWindowRegistered(id)) { throw new IllegalStateException("window with id=\"" + id + "\" isn't registered"); } @@ -822,7 +792,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements * @param id id of the tool window to be deactivated. * @param shouldHide if true then also hides specified tool window. */ - private void deactivateToolWindowImpl(final String id, final boolean shouldHide, final List commandsList) { + private void deactivateToolWindowImpl(@NotNull String id, final boolean shouldHide, @NotNull List commandsList) { if (LOG.isDebugEnabled()) { LOG.debug("enter: deactivateToolWindowImpl(" + id + "," + shouldHide + ")"); } @@ -887,37 +857,38 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * @return floating decorator for the tool window with specified ID. */ - private FloatingDecorator getFloatingDecorator(final String id) { + private FloatingDecorator getFloatingDecorator(@NotNull String id) { return myId2FloatingDecorator.get(id); } /** * @return windowed decorator for the tool window with specified ID. */ - private WindowedDecorator getWindowedDecorator(String id) { + private WindowedDecorator getWindowedDecorator(@NotNull String id) { return myId2WindowedDecorator.get(id); } /** * @return internal decorator for the tool window with specified ID. */ - private InternalDecorator getInternalDecorator(final String id) { + private InternalDecorator getInternalDecorator(@NotNull String id) { return myId2InternalDecorator.get(id); } /** * @return tool button for the window with specified ID. */ - private StripeButton getStripeButton(final String id) { + private StripeButton getStripeButton(@NotNull String id) { return myId2StripeButton.get(id); } /** * @return info for the tool window with specified ID. */ - private WindowInfoImpl getInfo(final String id) { + private WindowInfoImpl getInfo(@NotNull String id) { return myLayout.getInfo(id, true); } @Override + @NotNull public List getIdsOn(@NotNull final ToolWindowAnchor anchor) { return myLayout.getVisibleIdsOn(anchor, this); } @@ -931,12 +902,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements return decorator != null ? decorator.getToolWindow() : null; } - void showToolWindow(final String id) { + void showToolWindow(@NotNull String id) { if (LOG.isDebugEnabled()) { LOG.debug("enter: showToolWindow(" + id + ")"); } ApplicationManager.getApplication().assertIsDispatchThread(); - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); showToolWindowImpl(id, false, commandList); execute(commandList); } @@ -946,12 +917,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements hideToolWindow(id, hideSide, true); } - public void hideToolWindow(final String id, final boolean hideSide, final boolean moveFocus) { + public void hideToolWindow(@NotNull String id, final boolean hideSide, final boolean moveFocus) { ApplicationManager.getApplication().assertIsDispatchThread(); checkId(id); final WindowInfoImpl info = getInfo(id); if (!info.isVisible()) return; - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); final boolean wasActive = info.isActive(); // hide and deactivate @@ -1024,7 +995,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } else { final String toBeActivatedId = myActiveStack.pop(); - if (toBeActivatedId != null && (getInfo(toBeActivatedId).isVisible() || isStackEnabled())) { + if (getInfo(toBeActivatedId).isVisible() || isStackEnabled()) { activateToolWindowImpl(toBeActivatedId, commandList, false, true); } else { @@ -1044,7 +1015,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * @param dirtyMode if true then all UI operations are performed in dirty mode. */ - private void showToolWindowImpl(final String id, final boolean dirtyMode, final List commandsList) { + private void showToolWindowImpl(@NotNull String id, final boolean dirtyMode, @NotNull List commandsList) { final WindowInfoImpl toBeShownInfo = getInfo(id); if (toBeShownInfo.isVisible() || !getToolWindow(id).isAvailable()) { return; @@ -1184,7 +1155,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements public ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean secondary) { ToolWindow window = registerToolWindow(id, null, anchor, secondary, canCloseContent, canWorkInDumbMode); @@ -1226,7 +1197,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements final StripeButton button = new StripeButton(decorator, myToolWindowsPane); myId2StripeButton.put(id, button); - List commandsList = new ArrayList(); + List commandsList = new ArrayList<>(); appendAddButtonCmd(button, info, commandsList); if (canWorkInDumbMode) { @@ -1260,12 +1231,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @NotNull private ToolWindow registerDisposable(@NotNull final String id, @NotNull final Disposable parentDisposable, @NotNull ToolWindow window) { - Disposer.register(parentDisposable, new Disposable() { - @Override - public void dispose() { - unregisterToolWindow(id); - } - }); + Disposer.register(parentDisposable, () -> unregisterToolWindow(id)); return window; } @@ -1284,7 +1250,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements // Save recent appearance of tool window myLayout.unregister(id); // Remove decorator and tool button from the screen - final ArrayList commandsList = new ArrayList(); + List commandsList = new ArrayList<>(); if (info.isVisible()) { info.setVisible(false); if (info.isFloating()) { @@ -1338,7 +1304,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @Override public void setLayout(@NotNull final DesktopLayout layout) { ApplicationManager.getApplication().assertIsDispatchThread(); - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); // hide tool window that are invisible in new layout final WindowInfoImpl[] currentInfos = myLayout.getInfos(); for (final WindowInfoImpl currentInfo : currentInfos) { @@ -1400,7 +1366,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements @Override public void invokeLater(@NotNull final Runnable runnable) { - List commandList = new ArrayList(); + List commandList = new ArrayList<>(); commandList.add(new InvokeLaterCmd(runnable, myWindowManager.getCommandProcessor())); execute(commandList); } @@ -1480,19 +1446,16 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }); listenerWrapper.myBalloon = balloon; myWindow2Balloon.put(toolWindowId, balloon); - Disposer.register(balloon, new Disposable() { - @Override - public void dispose() { - window.setPlaceholderMode(false); - stripe.updatePresentation(); - stripe.revalidate(); - stripe.repaint(); - myWindow2Balloon.remove(toolWindowId); - } + Disposer.register(balloon, () -> { + window.setPlaceholderMode(false); + stripe.updatePresentation(); + stripe.revalidate(); + stripe.repaint(); + myWindow2Balloon.remove(toolWindowId); }); Disposer.register(getProject(), balloon); - execute(new ArrayList(Arrays.asList(new FinalizableCommand(null) { + execute(new ArrayList<>(Collections.singletonList(new FinalizableCommand(null) { @Override public void run() { final StripeButton button = stripe.getButtonFor(toolWindowId); @@ -1550,7 +1513,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements }; if (!button.isValid()) { - SwingUtilities.invokeLater(() -> show.run()); + SwingUtilities.invokeLater(show); } else { show.run(); @@ -1573,27 +1536,28 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements return splitters != null; } - ToolWindowAnchor getToolWindowAnchor(final String id) { + @NotNull + ToolWindowAnchor getToolWindowAnchor(@NotNull String id) { checkId(id); return getInfo(id).getAnchor(); } - void setToolWindowAnchor(final String id, final ToolWindowAnchor anchor) { + void setToolWindowAnchor(@NotNull String id, @NotNull ToolWindowAnchor anchor) { ApplicationManager.getApplication().assertIsDispatchThread(); setToolWindowAnchor(id, anchor, -1); } - void setToolWindowAnchor(final String id, final ToolWindowAnchor anchor, final int order) { + private void setToolWindowAnchor(@NotNull String id, @NotNull ToolWindowAnchor anchor, final int order) { ApplicationManager.getApplication().assertIsDispatchThread(); - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); setToolWindowAnchorImpl(id, anchor, order, commandList); execute(commandList); } - private void setToolWindowAnchorImpl(final String id, - final ToolWindowAnchor anchor, + private void setToolWindowAnchorImpl(@NotNull String id, + @NotNull ToolWindowAnchor anchor, final int order, - final ArrayList commandsList) { + @NotNull List commandsList) { checkId(id); final WindowInfoImpl info = getInfo(id); if (anchor == info.getAnchor() && order == info.getOrder()) { @@ -1630,42 +1594,42 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - boolean isSplitMode(String id) { + boolean isSplitMode(@NotNull String id) { ApplicationManager.getApplication().assertIsDispatchThread(); checkId(id); return getInfo(id).isSplit(); } @NotNull - ToolWindowContentUiType getContentUiType(String id) { + ToolWindowContentUiType getContentUiType(@NotNull String id) { ApplicationManager.getApplication().assertIsDispatchThread(); checkId(id); return getInfo(id).getContentUiType(); } - void setSideTool(String id, boolean isSide) { - final ArrayList commandList = new ArrayList(); + void setSideTool(@NotNull String id, boolean isSide) { + List commandList = new ArrayList<>(); setSplitModeImpl(id, isSide, commandList); execute(commandList); } - public void setContentUiType(String id, @NotNull ToolWindowContentUiType type) { - final ArrayList commandList = new ArrayList(); + void setContentUiType(@NotNull String id, @NotNull ToolWindowContentUiType type) { checkId(id); WindowInfoImpl info = getInfo(id); info.setContentUiType(type); + List commandList = new ArrayList<>(); appendApplyWindowInfoCmd(info, commandList); execute(commandList); } - void setSideToolAndAnchor(String id, ToolWindowAnchor anchor, int order, boolean isSide) { - final ArrayList commandList = new ArrayList(); + void setSideToolAndAnchor(@NotNull String id, @NotNull ToolWindowAnchor anchor, int order, boolean isSide) { setToolWindowAnchor(id, anchor, order); + List commandList = new ArrayList<>(); setSplitModeImpl(id, isSide, commandList); execute(commandList); } - private void setSplitModeImpl(final String id, final boolean isSplit, final ArrayList commandList) { + private void setSplitModeImpl(@NotNull String id, final boolean isSplit, @NotNull List commandList) { checkId(id); final WindowInfoImpl info = getInfo(id); if (isSplit == info.isSplit()) { @@ -1688,18 +1652,18 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements commandList.add(myToolWindowsPane.createUpdateButtonPositionCmd(id, myWindowManager.getCommandProcessor())); } - ToolWindowType getToolWindowInternalType(final String id) { + ToolWindowType getToolWindowInternalType(@NotNull String id) { ApplicationManager.getApplication().assertIsDispatchThread(); checkId(id); return getInfo(id).getInternalType(); } - ToolWindowType getToolWindowType(final String id) { + ToolWindowType getToolWindowType(@NotNull String id) { checkId(id); return getInfo(id).getType(); } - private void fireToolWindowRegistered(final String id) { + private void fireToolWindowRegistered(@NotNull String id) { myDispatcher.getMulticaster().toolWindowRegistered(id); } @@ -1707,31 +1671,31 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements myDispatcher.getMulticaster().stateChanged(); } - boolean isToolWindowActive(final String id) { + boolean isToolWindowActive(@NotNull String id) { ApplicationManager.getApplication().assertIsDispatchThread(); checkId(id); return getInfo(id).isActive(); } - boolean isToolWindowAutoHide(final String id) { + boolean isToolWindowAutoHide(@NotNull String id) { ApplicationManager.getApplication().assertIsDispatchThread(); checkId(id); return getInfo(id).isAutoHide(); } - boolean isToolWindowVisible(final String id) { + boolean isToolWindowVisible(@NotNull String id) { checkId(id); return getInfo(id).isVisible(); } - void setToolWindowAutoHide(final String id, final boolean autoHide) { + void setToolWindowAutoHide(@NotNull String id, final boolean autoHide) { ApplicationManager.getApplication().assertIsDispatchThread(); - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); setToolWindowAutoHideImpl(id, autoHide, commandList); execute(commandList); } - private void setToolWindowAutoHideImpl(final String id, final boolean autoHide, final ArrayList commandsList) { + private void setToolWindowAutoHideImpl(@NotNull String id, final boolean autoHide, @NotNull List commandsList) { checkId(id); final WindowInfoImpl info = getInfo(id); if (info.isAutoHide() == autoHide) { @@ -1745,14 +1709,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - void setToolWindowType(final String id, final ToolWindowType type) { + void setToolWindowType(@NotNull String id, @NotNull ToolWindowType type) { ApplicationManager.getApplication().assertIsDispatchThread(); - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); setToolWindowTypeImpl(id, type, commandList); execute(commandList); } - private void setToolWindowTypeImpl(final String id, final ToolWindowType type, final ArrayList commandsList) { + private void setToolWindowTypeImpl(@NotNull String id, @NotNull ToolWindowType type, @NotNull List commandsList) { checkId(id); final WindowInfoImpl info = getInfo(id); if (info.getType() == type) { @@ -1782,7 +1746,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - private void appendApplyWindowInfoCmd(final WindowInfoImpl info, final List commandsList) { + private void appendApplyWindowInfoCmd(@NotNull WindowInfoImpl info, @NotNull List commandsList) { final StripeButton button = getStripeButton(info.getId()); final InternalDecorator decorator = getInternalDecorator(info.getId()); commandsList.add(new ApplyWindowInfoCmd(info, button, decorator, myWindowManager.getCommandProcessor())); @@ -1791,10 +1755,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * @see ToolWindowsPane#createAddDecoratorCmd */ - private void appendAddDecoratorCmd(final InternalDecorator decorator, - final WindowInfoImpl info, + private void appendAddDecoratorCmd(@NotNull InternalDecorator decorator, + @NotNull WindowInfoImpl info, final boolean dirtyMode, - final List commandsList) { + @NotNull List commandsList) { final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor(); final FinalizableCommand command = myToolWindowsPane.createAddDecoratorCmd(decorator, info, dirtyMode, commandProcessor); commandsList.add(command); @@ -1803,17 +1767,17 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * @see ToolWindowsPane#createRemoveDecoratorCmd */ - private void appendRemoveDecoratorCmd(final String id, final boolean dirtyMode, final List commandsList) { + private void appendRemoveDecoratorCmd(@NotNull String id, final boolean dirtyMode, @NotNull List commandsList) { final FinalizableCommand command = myToolWindowsPane.createRemoveDecoratorCmd(id, dirtyMode, myWindowManager.getCommandProcessor()); commandsList.add(command); } - private void appendRemoveFloatingDecoratorCmd(final WindowInfoImpl info, final List commandsList) { + private void appendRemoveFloatingDecoratorCmd(@NotNull WindowInfoImpl info, @NotNull List commandsList) { final RemoveFloatingDecoratorCmd command = new RemoveFloatingDecoratorCmd(info); commandsList.add(command); } - private void appendRemoveWindowedDecoratorCmd(final WindowInfoImpl info, final List commandsList) { + private void appendRemoveWindowedDecoratorCmd(@NotNull WindowInfoImpl info, @NotNull List commandsList) { final RemoveWindowedDecoratorCmd command = new RemoveWindowedDecoratorCmd(info); commandsList.add(command); } @@ -1821,7 +1785,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * @see ToolWindowsPane#createAddButtonCmd */ - private void appendAddButtonCmd(final StripeButton button, final WindowInfoImpl info, final List commandsList) { + private void appendAddButtonCmd(final StripeButton button, @NotNull WindowInfoImpl info, @NotNull List commandsList) { final Comparator comparator = myLayout.comparator(info.getAnchor()); final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor(); final FinalizableCommand command = myToolWindowsPane.createAddButtonCmd(button, info, comparator, commandProcessor); @@ -1831,7 +1795,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * @see ToolWindowsPane#createAddButtonCmd */ - private void appendRemoveButtonCmd(final String id, final List commandsList) { + private void appendRemoveButtonCmd(@NotNull String id, @NotNull List commandsList) { final FinalizableCommand command = myToolWindowsPane.createRemoveButtonCmd(id, myWindowManager.getCommandProcessor()); commandsList.add(command); } @@ -1855,7 +1819,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * @see ToolWindowsPane#createSetEditorComponentCmd */ - public void appendSetEditorComponentCmd(@Nullable final JComponent component, final List commandsList) { + private void appendSetEditorComponentCmd(@Nullable final JComponent component, @NotNull List commandsList) { final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor(); final FinalizableCommand command = myToolWindowsPane.createSetEditorComponentCmd(component, commandProcessor); commandsList.add(command); @@ -1885,36 +1849,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements return splitters != null ? splitters : fem.getSplitters(); } - /** - * @return true if tool window with the specified id - * is floating and has modal showing child dialog. Such windows should not be closed - * when auto-hide windows are gone. - */ - private boolean hasModalChild(final WindowInfoImpl info) { - if (!info.isVisible() || !info.isFloating()) { - return false; - } - final FloatingDecorator decorator = getFloatingDecorator(info.getId()); - LOG.assertTrue(decorator != null); - return isModalOrHasModalChild(decorator); - } - - private static boolean isModalOrHasModalChild(final Window window) { - if (window instanceof Dialog) { - final Dialog dialog = (Dialog)window; - if (dialog.isModal() && dialog.isShowing()) { - return true; - } - final Window[] ownedWindows = dialog.getOwnedWindows(); - for (int i = ownedWindows.length - 1; i >= 0; i--) { - if (isModalOrHasModalChild(ownedWindows[i])) { - return true; - } - } - } - return false; - } - @Override public void clearSideStack() { mySideStack.clear(); @@ -2000,14 +1934,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } } - public void setDefaultContentUiType(ToolWindowImpl toolWindow, @NotNull ToolWindowContentUiType type) { + void setDefaultContentUiType(@NotNull ToolWindowImpl toolWindow, @NotNull ToolWindowContentUiType type) { final WindowInfoImpl info = getInfo(toolWindow.getId()); if (info.wasRead()) return; toolWindow.setContentUiType(type, null); } - public void stretchWidth(ToolWindowImpl toolWindow, int value) { + void stretchWidth(@NotNull ToolWindowImpl toolWindow, int value) { myToolWindowsPane.stretchWidth(toolWindow, value); } @@ -2021,7 +1955,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements myToolWindowsPane.setMaximized(wnd, maximized); } - public void stretchHeight(ToolWindowImpl toolWindow, int value) { + void stretchHeight(ToolWindowImpl toolWindow, int value) { myToolWindowsPane.stretchHeight(toolWindow, value); } @@ -2029,7 +1963,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private Balloon myBalloon; private final HyperlinkListener myListener; - public BalloonHyperlinkListener(HyperlinkListener listener) { + BalloonHyperlinkListener(HyperlinkListener listener) { myListener = listener; } @@ -2054,7 +1988,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * Creates floating decorator for specified internal decorator. */ - private AddFloatingDecoratorCmd(final InternalDecorator decorator, final WindowInfoImpl info) { + private AddFloatingDecoratorCmd(@NotNull InternalDecorator decorator, @NotNull WindowInfoImpl info) { super(myWindowManager.getCommandProcessor()); myFloatingDecorator = new FloatingDecorator(myFrame, info.copy(), decorator); myId2FloatingDecorator.put(info.getId(), myFloatingDecorator); @@ -2093,7 +2027,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private final class RemoveFloatingDecoratorCmd extends FinalizableCommand { private final FloatingDecorator myFloatingDecorator; - private RemoveFloatingDecoratorCmd(final WindowInfoImpl info) { + private RemoveFloatingDecoratorCmd(@NotNull WindowInfoImpl info) { super(myWindowManager.getCommandProcessor()); myFloatingDecorator = getFloatingDecorator(info.getId()); myId2FloatingDecorator.remove(info.getId()); @@ -2126,7 +2060,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements /** * Creates windowed decorator for specified internal decorator. */ - private AddWindowedDecoratorCmd(final InternalDecorator decorator, final WindowInfoImpl info) { + private AddWindowedDecoratorCmd(@NotNull InternalDecorator decorator, @NotNull WindowInfoImpl info) { super(myWindowManager.getCommandProcessor()); myWindowedDecorator = new WindowedDecorator(myProject, info.copy(), decorator); Window window = myWindowedDecorator.getFrame(); @@ -2146,12 +2080,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements window.setLocationRelativeTo(myFrame); } myId2WindowedDecorator.put(info.getId(), myWindowedDecorator); - myWindowedDecorator.addDisposable(new Disposable() { - @Override - public void dispose() { - if (myId2WindowedDecorator.get(info.getId()) != null) { - hideToolWindow(info.getId(), false); - } + myWindowedDecorator.addDisposable(() -> { + if (myId2WindowedDecorator.get(info.getId()) != null) { + hideToolWindow(info.getId(), false); } }); } @@ -2183,7 +2114,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private final class RemoveWindowedDecoratorCmd extends FinalizableCommand { private final WindowedDecorator myWindowedDecorator; - private RemoveWindowedDecoratorCmd(final WindowInfoImpl info) { + private RemoveWindowedDecoratorCmd(@NotNull WindowInfoImpl info) { super(myWindowManager.getCommandProcessor()); myWindowedDecorator = getWindowedDecorator(info.getId()); myId2WindowedDecorator.remove(info.getId()); @@ -2255,8 +2186,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements private final String myId; private final ToolWindowImpl myToolWindow; - - private ToolWindowFocusWatcher(final ToolWindowImpl toolWindow) { + private ToolWindowFocusWatcher(@NotNull ToolWindowImpl toolWindow) { myId = toolWindow.getId(); install(toolWindow.getComponent()); myToolWindow = toolWindow; @@ -2317,27 +2247,27 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements */ private final class MyInternalDecoratorListener implements InternalDecoratorListener { @Override - public void anchorChanged(final InternalDecorator source, final ToolWindowAnchor anchor) { + public void anchorChanged(@NotNull final InternalDecorator source, @NotNull final ToolWindowAnchor anchor) { setToolWindowAnchor(source.getToolWindow().getId(), anchor); } @Override - public void autoHideChanged(final InternalDecorator source, final boolean autoHide) { + public void autoHideChanged(@NotNull final InternalDecorator source, final boolean autoHide) { setToolWindowAutoHide(source.getToolWindow().getId(), autoHide); } @Override - public void hidden(final InternalDecorator source) { + public void hidden(@NotNull final InternalDecorator source) { hideToolWindow(source.getToolWindow().getId(), false); } @Override - public void hiddenSide(final InternalDecorator source) { + public void hiddenSide(@NotNull final InternalDecorator source) { hideToolWindow(source.getToolWindow().getId(), true); } @Override - public void contentUiTypeChanges(InternalDecorator source, @NotNull ToolWindowContentUiType type) { + public void contentUiTypeChanges(@NotNull InternalDecorator source, @NotNull ToolWindowContentUiType type) { setContentUiType(source.getToolWindow().getId(), type); } @@ -2346,13 +2276,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements * tool window depending on decoration type. */ @Override - public void resized(final InternalDecorator source) { + public void resized(@NotNull final InternalDecorator source) { if (!source.isShowing()) { return; // do not recalculate the tool window size if it is not yet shown (and, therefore, has 0,0,0,0 bounds) } final WindowInfoImpl info = getInfo(source.getToolWindow().getId()); - InternalDecorator another = null; if (info.isFloating()) { final Window owner = SwingUtilities.getWindowAncestor(source); if (owner != null) { @@ -2367,6 +2296,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } else { // docked and sliding windows ToolWindowAnchor anchor = info.getAnchor(); + InternalDecorator another = null; if (source.getParent() instanceof Splitter) { float sizeInSplit = anchor.isSplitVertically() ? source.getHeight() : source.getWidth(); Splitter splitter = (Splitter)source.getParent(); @@ -2399,21 +2329,22 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements } @Override - public void activated(final InternalDecorator source) { + public void activated(@NotNull final InternalDecorator source) { activateToolWindow(source.getToolWindow().getId(), true, true); } @Override - public void typeChanged(final InternalDecorator source, final ToolWindowType type) { + public void typeChanged(@NotNull final InternalDecorator source, @NotNull final ToolWindowType type) { setToolWindowType(source.getToolWindow().getId(), type); } @Override - public void sideStatusChanged(final InternalDecorator source, final boolean isSideTool) { + public void sideStatusChanged(@NotNull final InternalDecorator source, final boolean isSideTool) { setSideTool(source.getToolWindow().getId(), isSideTool); } - public void visibleStripeButtonChanged(InternalDecorator source, boolean visible) { + @Override + public void visibleStripeButtonChanged(@NotNull InternalDecorator source, boolean visible) { setShowStripeButton(source.getToolWindow().getId(), visible); } } @@ -2546,11 +2477,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements return IdeFocusManager.getInstance(myProject).dispatch(e); } + @NotNull public Expirable getTimestamp(boolean trackOnlyForcedCommands) { return IdeFocusManager.getInstance(myProject).getTimestamp(trackOnlyForcedCommands); } - public void setShowStripeButton(String id, boolean visibleOnPanel) { + void setShowStripeButton(@NotNull String id, boolean visibleOnPanel) { checkId(id); WindowInfoImpl info = getInfo(id); if (visibleOnPanel == info.isShowStripeButton()) { @@ -2559,12 +2491,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements info.setShowStripeButton(visibleOnPanel); UsageTrigger.trigger("StripeButton[" + id + "]." + (visibleOnPanel ? "shown" : "hidden")); - final ArrayList commandList = new ArrayList(); + List commandList = new ArrayList<>(); appendApplyWindowInfoCmd(info, commandList); execute(commandList); } - public boolean isShowStripeButton(String id) { + boolean isShowStripeButton(@NotNull String id) { WindowInfoImpl info = getInfo(id); return info == null || info.isShowStripeButton(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java index 2f626df5477e..86a45f418e26 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java @@ -42,10 +42,10 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; +import java.lang.ref.Reference; import java.util.ArrayList; import java.util.Comparator; +import java.util.List; /** * This panel contains all tool stripes and JLayeredPanle at the center area. All tool windows are @@ -59,12 +59,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final IdeFrameImpl myFrame; - private final HashMap myId2Button; - private final HashMap myId2Decorator; - private final HashMap myButton2Info; - private final HashMap myDecorator2Info; - private final HashMap myId2SplitProportion; - private Pair myMaximizedProportion = null; + private final HashMap myId2Button = new HashMap<>(); + private final HashMap myId2Decorator = new HashMap<>(); + private final HashMap myButton2Info = new HashMap<>(); + private final HashMap myDecorator2Info = new HashMap<>(); + private final HashMap myId2SplitProportion = new HashMap<>(); + private Pair myMaximizedProportion; /** * This panel is the layered pane where all sliding tool windows are located. The DEFAULT * layer contains splitters. The PALETTE layer contains all sliding tool windows. @@ -84,29 +84,23 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final Stripe myBottomStripe; private final Stripe myTopStripe; - private final ArrayList myStripes = new ArrayList(); + private final List myStripes = new ArrayList<>(); private final ToolWindowManagerImpl myManager; private boolean myStripesOverlayed; private final Disposable myDisposable = Disposer.newDisposable(); - private boolean myWidescreen = false; - private boolean myLeftHorizontalSplit = false; - private boolean myRightHorizontalSplit = false; + private boolean myWidescreen; + private boolean myLeftHorizontalSplit; + private boolean myRightHorizontalSplit; - ToolWindowsPane(final IdeFrameImpl frame, ToolWindowManagerImpl manager) { + ToolWindowsPane(@NotNull IdeFrameImpl frame, @NotNull ToolWindowManagerImpl manager) { myManager = manager; setOpaque(false); myFrame = frame; - myId2Button = new HashMap(); - myId2Decorator = new HashMap(); - myButton2Info = new HashMap(); - myDecorator2Info = new HashMap(); - myId2SplitProportion = new HashMap(); // Splitters - myVerticalSplitter = new ThreeComponentsSplitter(true); Disposer.register(this, myVerticalSplitter); myVerticalSplitter.setDividerWidth(0); @@ -193,6 +187,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi /** * Invoked when enclosed frame is being shown. */ + @Override public final void addNotify() { super.addNotify(); } @@ -200,6 +195,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi /** * Invoked when enclosed frame is being disposed. */ + @Override public final void removeNotify() { if (ScreenUtil.isStandardAddRemoveNotify(this)) { Disposer.dispose(myDisposable); @@ -211,6 +207,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi return myFrame.getProject(); } + @Override public final void uiSettingsChanged(final UISettings source) { updateToolStripesVisibility(); updateLayout(); @@ -225,10 +222,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi * @param comparator which is used to sort buttons within the stripe. * @param finishCallBack invoked when the command is completed. */ + @NotNull final FinalizableCommand createAddButtonCmd(final StripeButton button, - final WindowInfoImpl info, - final Comparator comparator, - final Runnable finishCallBack) { + @NotNull WindowInfoImpl info, + @NotNull Comparator comparator, + @NotNull Runnable finishCallBack) { final WindowInfoImpl copiedInfo = info.copy(); myId2Button.put(copiedInfo.getId(), button); myButton2Info.put(button, copiedInfo); @@ -242,12 +240,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi * @param dirtyMode if true then JRootPane will not be validated and repainted after adding * the decorator. Moreover in this (dirty) mode animation doesn't work. */ - final FinalizableCommand createAddDecoratorCmd( - final InternalDecorator decorator, - final WindowInfoImpl info, - final boolean dirtyMode, - final Runnable finishCallBack - ) { + @NotNull + final FinalizableCommand createAddDecoratorCmd(@NotNull InternalDecorator decorator, + @NotNull WindowInfoImpl info, + final boolean dirtyMode, + @NotNull Runnable finishCallBack) { final WindowInfoImpl copiedInfo = info.copy(); final String id = copiedInfo.getId(); @@ -276,10 +273,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi * * @param id ID of the button to be removed. */ - final FinalizableCommand createRemoveButtonCmd(final String id, final Runnable finishCallBack) { + @NotNull + final FinalizableCommand createRemoveButtonCmd(@NotNull String id, @NotNull Runnable finishCallBack) { final StripeButton button = getButtonById(id); final WindowInfoImpl info = getButtonInfoById(id); - // + myButton2Info.remove(button); myId2Button.remove(id); return new RemoveToolStripeButtonCmd(button, info, finishCallBack); @@ -291,7 +289,8 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi * @param dirtyMode if true then JRootPane will not be validated and repainted after removing * the decorator. Moreover in this (dirty) mode animation doesn't work. */ - final FinalizableCommand createRemoveDecoratorCmd(final String id, final boolean dirtyMode, final Runnable finishCallBack) { + @NotNull + final FinalizableCommand createRemoveDecoratorCmd(@NotNull String id, final boolean dirtyMode, @NotNull Runnable finishCallBack) { final Component decorator = getDecoratorById(id); final WindowInfoImpl info = getDecoratorInfoById(id); @@ -321,14 +320,17 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi * * @param component component to be set. */ - final FinalizableCommand createSetEditorComponentCmd(final JComponent component, final Runnable finishCallBack) { + @NotNull + final FinalizableCommand createSetEditorComponentCmd(final JComponent component, @NotNull Runnable finishCallBack) { return new SetEditorComponentCmd(component, finishCallBack); } - final FinalizableCommand createUpdateButtonPositionCmd(String id, final Runnable finishCallback) { + @NotNull + final FinalizableCommand createUpdateButtonPositionCmd(@NotNull String id, @NotNull Runnable finishCallback) { return new UpdateButtonPositionCmd(id, finishCallback); } + @NotNull public final JComponent getMyLayeredPane() { return myLayeredPane; } @@ -361,7 +363,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi /** * Sets (docks) specified component to the specified anchor. */ - private void setComponent(final JComponent component, final ToolWindowAnchor anchor, final float weight) { + private void setComponent(final JComponent component, @NotNull ToolWindowAnchor anchor, final float weight) { if (ToolWindowAnchor.TOP == anchor) { myVerticalSplitter.setFirstComponent(component); myVerticalSplitter.setFirstSize((int)(myLayeredPane.getHeight() * weight)); @@ -383,7 +385,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } } - private JComponent getComponentAt(ToolWindowAnchor anchor) { + private JComponent getComponentAt(@NotNull ToolWindowAnchor anchor) { if (ToolWindowAnchor.TOP == anchor) { return myVerticalSplitter.getFirstComponent(); } @@ -402,12 +404,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } } - private float getPreferredSplitProportion(String id, float defaultValue) { + private float getPreferredSplitProportion(@NotNull String id, float defaultValue) { Float f = myId2SplitProportion.get(id); - return (f == null ? defaultValue : f); + return f == null ? defaultValue : f; } - private WindowInfoImpl getDockedInfoAt(ToolWindowAnchor anchor, boolean side) { + private WindowInfoImpl getDockedInfoAt(@NotNull ToolWindowAnchor anchor, boolean side) { for (WindowInfoImpl info : myDecorator2Info.values()) { if (info.isVisible() && info.isDocked() && info.getAnchor() == anchor && side == info.isSplit()) { return info; @@ -417,7 +419,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi return null; } - public void setDocumentComponent(final JComponent component) { + private void setDocumentComponent(final JComponent component) { (myWidescreen ? myVerticalSplitter : myHorizontalSplitter).setInnerComponent(component); } @@ -464,13 +466,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi if (ToolWindowAnchor.TOP == anchor) { return myTopStripe; } - else if (ToolWindowAnchor.BOTTOM == anchor) { + if (ToolWindowAnchor.BOTTOM == anchor) { return myBottomStripe; } - else if (ToolWindowAnchor.LEFT == anchor) { + if (ToolWindowAnchor.LEFT == anchor) { return myLeftStripe; } - else if (ToolWindowAnchor.RIGHT == anchor) { + if (ToolWindowAnchor.RIGHT == anchor) { return myRightStripe; } @@ -478,7 +480,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } @Nullable - Stripe getStripeFor(final Rectangle screenRec, Stripe preferred) { + Stripe getStripeFor(@NotNull Rectangle screenRec, @NotNull Stripe preferred) { if (preferred.containsScreen(screenRec)) { return myStripes.get(myStripes.indexOf(preferred)); } @@ -504,15 +506,15 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } } - public void stretchWidth(ToolWindow wnd, int value) { + void stretchWidth(@NotNull ToolWindow wnd, int value) { stretch(wnd, value); } - public void stretchHeight(ToolWindow wnd, int value) { + void stretchHeight(@NotNull ToolWindow wnd, int value) { stretch(wnd, value); } - private void stretch(ToolWindow wnd, int value) { + private void stretch(@NotNull ToolWindow wnd, int value) { Pair pair = findResizerAndComponent(wnd); if (pair == null) return; @@ -520,13 +522,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi int actualSize = (vertical ? pair.second.getHeight() : pair.second.getWidth()) + value; boolean first = wnd.getAnchor() == ToolWindowAnchor.LEFT || wnd.getAnchor() == ToolWindowAnchor.TOP; int maxValue = vertical ? myVerticalSplitter.getMaxSize(first) : myHorizontalSplitter.getMaxSize(first); - int minValue = vertical ? myVerticalSplitter.getMinSize(first) : myHorizontalSplitter.getMinSize(first);; + int minValue = vertical ? myVerticalSplitter.getMinSize(first) : myHorizontalSplitter.getMinSize(first); pair.first.setSize(Math.max(minValue, Math.min(maxValue, actualSize))); } @Nullable - private Pair findResizerAndComponent(ToolWindow wnd) { + private Pair findResizerAndComponent(@NotNull ToolWindow wnd) { if (!wnd.isVisible()) return null; Resizer resizer = null; @@ -620,7 +622,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi return myMaximizedProportion != null && myMaximizedProportion.first == wnd; } - public void setMaximized(@NotNull ToolWindow wnd, boolean maximized) { + void setMaximized(@NotNull ToolWindow wnd, boolean maximized) { Pair resizerAndComponent = findResizerAndComponent(wnd); if (resizerAndComponent == null) return; @@ -638,6 +640,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } + @FunctionalInterface interface Resizer { void setSize(int size); @@ -645,25 +648,27 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi abstract class Splitter implements Resizer { ThreeComponentsSplitter mySplitter; - Splitter(ThreeComponentsSplitter splitter) { + Splitter(@NotNull ThreeComponentsSplitter splitter) { mySplitter = splitter; } static class FirstComponent extends Splitter { - FirstComponent(ThreeComponentsSplitter splitter) { + FirstComponent(@NotNull ThreeComponentsSplitter splitter) { super(splitter); } + @Override public void setSize(int size) { mySplitter.setFirstSize(size); } } static class LastComponent extends Splitter { - LastComponent(ThreeComponentsSplitter splitter) { + LastComponent(@NotNull ThreeComponentsSplitter splitter) { super(splitter); } + @Override public void setSize(int size) { mySplitter.setLastSize(size); } @@ -673,10 +678,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi abstract class LayeredPane implements Resizer { Component myComponent; - protected LayeredPane(Component component) { + LayeredPane(@NotNull Component component) { myComponent = component; } + @Override public final void setSize(int size) { _setSize(size); if (myComponent.getParent() instanceof JComponent) { @@ -690,20 +696,22 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi static class Left extends LayeredPane { - Left(Component component) { + Left(@NotNull Component component) { super(component); } + @Override public void _setSize(int size) { myComponent.setSize(size, myComponent.getHeight()); } } static class Right extends LayeredPane { - Right(Component component) { + Right(@NotNull Component component) { super(component); } + @Override public void _setSize(int size) { Rectangle bounds = myComponent.getBounds(); int delta = size - bounds.width; @@ -714,20 +722,22 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } static class Top extends LayeredPane { - Top(Component component) { + Top(@NotNull Component component) { super(component); } + @Override public void _setSize(int size) { myComponent.setSize(myComponent.getWidth(), size); } } static class Bottom extends LayeredPane { - Bottom(Component component) { + Bottom(@NotNull Component component) { super(component); } + @Override public void _setSize(int size) { Rectangle bounds = myComponent.getBounds(); int delta = size - bounds.height; @@ -744,16 +754,17 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final WindowInfoImpl myInfo; private final boolean myDirtyMode; - public AddDockedComponentCmd(final JComponent component, - final WindowInfoImpl info, + public AddDockedComponentCmd(@NotNull JComponent component, + @NotNull WindowInfoImpl info, final boolean dirtyMode, - final Runnable finishCallBack) { + @NotNull Runnable finishCallBack) { super(finishCallBack); myComponent = component; myInfo = info; myDirtyMode = dirtyMode; } + @Override public final void run() { try { final ToolWindowAnchor anchor = myInfo.getAnchor(); @@ -774,17 +785,19 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final WindowInfoImpl myInfo; private final boolean myDirtyMode; - private AddAndSplitDockedComponentCmd(final JComponent newComponent, - final WindowInfoImpl info, final boolean dirtyMode, final Runnable finishCallBack) { + private AddAndSplitDockedComponentCmd(@NotNull JComponent newComponent, + @NotNull WindowInfoImpl info, + final boolean dirtyMode, + @NotNull Runnable finishCallBack) { super(finishCallBack); myNewComponent = newComponent; myInfo = info; myDirtyMode = dirtyMode; } + @Override public void run() { try { - float newWeight; final ToolWindowAnchor anchor = myInfo.getAnchor(); class MySplitter extends Splitter implements UISettingsListener { @Override @@ -801,28 +814,26 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi splitter.setOrientation(anchor.isSplitVertically()); if (!anchor.isHorizontal()) { splitter.setAllowSwitchOrientationByMouseClick(true); - splitter.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (!Splitter.PROP_ORIENTATION.equals(evt.getPropertyName())) return; - boolean isSplitterHorizontalNow = !splitter.isVertical(); - UISettings settings = UISettings.getInstance(); - if (anchor == ToolWindowAnchor.LEFT) { - if (settings.LEFT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) { - settings.LEFT_HORIZONTAL_SPLIT = isSplitterHorizontalNow; - settings.fireUISettingsChanged(); - } + splitter.addPropertyChangeListener(evt -> { + if (!Splitter.PROP_ORIENTATION.equals(evt.getPropertyName())) return; + boolean isSplitterHorizontalNow = !splitter.isVertical(); + UISettings settings = UISettings.getInstance(); + if (anchor == ToolWindowAnchor.LEFT) { + if (settings.LEFT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) { + settings.LEFT_HORIZONTAL_SPLIT = isSplitterHorizontalNow; + settings.fireUISettingsChanged(); } - if (anchor == ToolWindowAnchor.RIGHT) { - if (settings.RIGHT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) { - settings.RIGHT_HORIZONTAL_SPLIT = isSplitterHorizontalNow; - settings.fireUISettingsChanged(); - } + } + if (anchor == ToolWindowAnchor.RIGHT) { + if (settings.RIGHT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) { + settings.RIGHT_HORIZONTAL_SPLIT = isSplitterHorizontalNow; + settings.fireUISettingsChanged(); } } }); } JComponent c = getComponentAt(anchor); + float newWeight; if (c instanceof InternalDecorator) { InternalDecorator oldComponent = (InternalDecorator)c; if (myInfo.isSplit()) { @@ -872,15 +883,16 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final WindowInfoImpl myInfo; private final boolean myDirtyMode; - public AddSlidingComponentCmd(final Component component, - final WindowInfoImpl info, + public AddSlidingComponentCmd(@NotNull Component component, + @NotNull WindowInfoImpl info, final boolean dirtyMode, - final Runnable finishCallBack) { + @NotNull Runnable finishCallBack) { super(finishCallBack); myComponent = component; myInfo = info; myDirtyMode = dirtyMode; } + @Override public final void run() { try { // Show component. @@ -946,15 +958,16 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final Comparator myComparator; public AddToolStripeButtonCmd(final StripeButton button, - final WindowInfoImpl info, - final Comparator comparator, - final Runnable finishCallBack) { + @NotNull WindowInfoImpl info, + @NotNull Comparator comparator, + @NotNull Runnable finishCallBack) { super(finishCallBack); myButton = button; myInfo = info; myComparator = comparator; } + @Override public final void run() { try { final ToolWindowAnchor anchor = myInfo.getAnchor(); @@ -986,12 +999,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final StripeButton myButton; private final WindowInfoImpl myInfo; - public RemoveToolStripeButtonCmd(final StripeButton button, final WindowInfoImpl info, final Runnable finishCallBack) { + public RemoveToolStripeButtonCmd(@NotNull StripeButton button, @NotNull WindowInfoImpl info, @NotNull Runnable finishCallBack) { super(finishCallBack); myButton = button; myInfo = info; } + @Override public final void run() { try { final ToolWindowAnchor anchor = myInfo.getAnchor(); @@ -1023,12 +1037,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final WindowInfoImpl myInfo; private final boolean myDirtyMode; - public RemoveDockedComponentCmd(final WindowInfoImpl info, final boolean dirtyMode, final Runnable finishCallBack) { + public RemoveDockedComponentCmd(@NotNull WindowInfoImpl info, final boolean dirtyMode, @NotNull Runnable finishCallBack) { super(finishCallBack); myInfo = info; myDirtyMode = dirtyMode; } + @Override public final void run() { try { setComponent(null, myInfo.getAnchor(), 0); @@ -1047,14 +1062,15 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final WindowInfoImpl myInfo; private final boolean myDirtyMode; - private RemoveSplitAndDockedComponentCmd(final WindowInfoImpl info, + private RemoveSplitAndDockedComponentCmd(@NotNull WindowInfoImpl info, boolean dirtyMode, - final Runnable finishCallBack) { + @NotNull Runnable finishCallBack) { super(finishCallBack); myInfo = info; myDirtyMode = dirtyMode; } + @Override public void run() { try { ToolWindowAnchor anchor = myInfo.getAnchor(); @@ -1086,12 +1102,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final WindowInfoImpl myInfo; private final boolean myDirtyMode; - public RemoveSlidingComponentCmd(Component component, WindowInfoImpl info, boolean dirtyMode, Runnable finishCallBack) { + public RemoveSlidingComponentCmd(Component component, @NotNull WindowInfoImpl info, boolean dirtyMode, @NotNull Runnable finishCallBack) { super(finishCallBack); myComponent = component; myInfo = info; myDirtyMode = dirtyMode; } + @Override public final void run() { try { final UISettings uiSettings = UISettings.getInstance(); @@ -1147,11 +1164,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final class SetEditorComponentCmd extends FinalizableCommand { private final JComponent myComponent; - public SetEditorComponentCmd(final JComponent component, final Runnable finishCallBack) { + public SetEditorComponentCmd(final JComponent component, @NotNull Runnable finishCallBack) { super(finishCallBack); myComponent = component; } + @Override public void run() { try { setDocumentComponent(myComponent); @@ -1167,11 +1185,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi private final class UpdateButtonPositionCmd extends FinalizableCommand { private final String myId; - private UpdateButtonPositionCmd(String id, final Runnable finishCallBack) { + private UpdateButtonPositionCmd(@NotNull String id, @NotNull Runnable finishCallBack) { super(finishCallBack); myId = id; } + @Override public void run() { try { StripeButton stripeButton = getButtonById(myId); @@ -1209,35 +1228,31 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi * These images are used to perform animated showing and hiding of components. * They are the member for performance reason. */ - private SoftReference myBottomImageRef; - private SoftReference myTopImageRef; + private Reference myBottomImageRef; + private Reference myTopImageRef; - public MyLayeredPane(final JComponent splitter) { - myBottomImageRef = new SoftReference(null); - myTopImageRef = new SoftReference(null); + public MyLayeredPane(@NotNull JComponent splitter) { setOpaque(false); add(splitter, JLayeredPane.DEFAULT_LAYER); } - public final Image getBottomImage() { - Pair> result = getImage(myBottomImageRef); + final Image getBottomImage() { + Pair> result = getImage(myBottomImageRef); myBottomImageRef = result.second; return result.first; } - public final Image getTopImage() { - Pair> result = getImage(myTopImageRef); + final Image getTopImage() { + Pair> result = getImage(myTopImageRef); myTopImageRef = result.second; return result.first; } - private Pair> getImage(SoftReference imageRef) { + @NotNull + private Pair> getImage(@Nullable Reference imageRef) { LOG.assertTrue(UISettings.getInstance().ANIMATE_WINDOWS); - BufferedImage image = imageRef.get(); - if ( - image == null || - image.getWidth(null) < getWidth() || image.getHeight(null) < getHeight() - ) { + BufferedImage image = SoftReference.dereference(imageRef); + if (image == null || image.getWidth(null) < getWidth() || image.getHeight(null) < getHeight()) { final int width = Math.max(Math.max(1, getWidth()), myFrame.getWidth()); final int height = Math.max(Math.max(1, getHeight()), myFrame.getHeight()); if (SystemInfo.isWindows) { @@ -1251,7 +1266,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi image = UIUtil.createImage(width, height, BufferedImage.TYPE_INT_RGB); } - imageRef = new SoftReference(image); + imageRef = new SoftReference<>(image); } return Pair.create(image, imageRef); } @@ -1259,6 +1274,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi /** * When component size becomes larger then bottom and top images should be enlarged. */ + @Override public void doLayout() { final int width = getWidth(); final int height = getHeight(); @@ -1295,7 +1311,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } } - public final void setBoundsInPaletteLayer(final Component component, final ToolWindowAnchor anchor, float weight) { + final void setBoundsInPaletteLayer(@NotNull Component component, @NotNull ToolWindowAnchor anchor, float weight) { if (weight < .0f) { weight = WindowInfoImpl.DEFAULT_WEIGHT; } @@ -1322,7 +1338,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi } } - public void setStripesOverlayed(boolean stripesOverlayed) { + void setStripesOverlayed(boolean stripesOverlayed) { myStripesOverlayed = stripesOverlayed; updateToolStripesVisibility(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowInfoImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowInfoImpl.java index 22558914ce43..ff006a1156e2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowInfoImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowInfoImpl.java @@ -32,16 +32,16 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo /** * XML tag. */ - @NonNls static final String TAG="window_info"; + @NonNls static final String TAG = "window_info"; /** * Default window weight. */ - static final float DEFAULT_WEIGHT= 0.33f; - static final float DEFAULT_SIDE_WEIGHT = 0.5f; + static final float DEFAULT_WEIGHT = 0.33f; + private static final float DEFAULT_SIDE_WEIGHT = 0.5f; private boolean myActive; @NotNull - private ToolWindowAnchor myAnchor; + private ToolWindowAnchor myAnchor = ToolWindowAnchor.LEFT; private boolean myAutoHide; /** * Bounds of window in "floating" mode. It equals to null if @@ -52,9 +52,9 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo private ToolWindowType myInternalType; private ToolWindowType myType; private boolean myVisible; - private boolean myShowStripeButton; - private float myWeight; - private float mySideWeight; + private boolean myShowStripeButton = true; + private float myWeight = DEFAULT_WEIGHT; + private float mySideWeight = DEFAULT_SIDE_WEIGHT; private boolean mySplitMode; @NotNull private ToolWindowContentUiType myContentUiType = ToolWindowContentUiType.TABBED; @@ -62,24 +62,24 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo * Defines order of tool window button inside the stripe. * The default value is -1. */ - private int myOrder; - @NonNls static final String ID_ATTR = "id"; - @NonNls static final String ACTIVE_ATTR = "active"; - @NonNls static final String ANCHOR_ATTR = "anchor"; - @NonNls static final String AUTOHIDE_ATTR = "auto_hide"; - @NonNls static final String INTERNAL_TYPE_ATTR = "internal_type"; - @NonNls static final String TYPE_ATTR = "type"; - @NonNls static final String VISIBLE_ATTR = "visible"; - @NonNls static final String WEIGHT_ATTR = "weight"; - @NonNls static final String SIDE_WEIGHT_ATTR = "sideWeight"; - @NonNls static final String ORDER_ATTR = "order"; - @NonNls static final String X_ATTR = "x"; - @NonNls static final String Y_ATTR = "y"; - @NonNls static final String WIDTH_ATTR = "width"; - @NonNls static final String HEIGHT_ATTR = "height"; - @NonNls static final String SIDE_TOOL_ATTR = "side_tool"; - @NonNls static final String CONTENT_UI_ATTR = "content_ui"; - @NonNls static final String SHOW_STRIPE_BUTTON = "show_stripe_button"; + private int myOrder = -1; + @NonNls private static final String ID_ATTR = "id"; + @NonNls private static final String ACTIVE_ATTR = "active"; + @NonNls private static final String ANCHOR_ATTR = "anchor"; + @NonNls private static final String AUTOHIDE_ATTR = "auto_hide"; + @NonNls private static final String INTERNAL_TYPE_ATTR = "internal_type"; + @NonNls private static final String TYPE_ATTR = "type"; + @NonNls private static final String VISIBLE_ATTR = "visible"; + @NonNls private static final String WEIGHT_ATTR = "weight"; + @NonNls private static final String SIDE_WEIGHT_ATTR = "sideWeight"; + @NonNls private static final String ORDER_ATTR = "order"; + @NonNls private static final String X_ATTR = "x"; + @NonNls private static final String Y_ATTR = "y"; + @NonNls private static final String WIDTH_ATTR = "width"; + @NonNls private static final String HEIGHT_ATTR = "height"; + @NonNls private static final String SIDE_TOOL_ATTR = "side_tool"; + @NonNls private static final String CONTENT_UI_ATTR = "content_ui"; + @NonNls private static final String SHOW_STRIPE_BUTTON = "show_stripe_button"; private boolean myWasRead; @@ -88,18 +88,8 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo * Creates WindowInfo for tool window with specified ID. */ WindowInfoImpl(@NotNull String id) { - myActive = false; - myAnchor = ToolWindowAnchor.LEFT; - myAutoHide = false; - myFloatingBounds = null; myId = id; setType(ToolWindowType.DOCKED); - myVisible = false; - myShowStripeButton = true; - myWeight = DEFAULT_WEIGHT; - mySideWeight = DEFAULT_SIDE_WEIGHT; - myOrder = -1; - mySplitMode = false; } /** @@ -122,7 +112,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo /** * Copies all data from the passed WindowInfo into itself. */ - void copyFrom(final WindowInfoImpl info){ + void copyFrom(@NotNull WindowInfoImpl info){ myActive = info.myActive; myAnchor = info.myAnchor; myAutoHide = info.myAutoHide; @@ -178,15 +168,16 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo * window can be in floating mode, but this method has sense if you want to know what type * tool window had when it was internal one. The method never returns null. */ + @NotNull ToolWindowType getInternalType(){ return myInternalType; } /** * @return current type of tool window. - * @see com.intellij.openapi.wm.ToolWindowType#DOCKED - * @see com.intellij.openapi.wm.ToolWindowType#FLOATING - * @see com.intellij.openapi.wm.ToolWindowType#SLIDING + * @see ToolWindowType#DOCKED + * @see ToolWindowType#FLOATING + * @see ToolWindowType#SLIDING */ @Override public ToolWindowType getType(){ @@ -248,11 +239,12 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo return myVisible; } + @Override public boolean isShowStripeButton() { return myShowStripeButton; } - public void setShowStripeButton(boolean showStripeButton) { + void setShowStripeButton(boolean showStripeButton) { myShowStripeButton = showStripeButton; } @@ -266,7 +258,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo } @Override - @SuppressWarnings({"EmptyCatchBlock"}) + @SuppressWarnings("EmptyCatchBlock") public void readExternal(final Element element) { myId = element.getAttributeValue(ID_ATTR); myWasRead = true; @@ -353,7 +345,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo setTypeAndCheck(type); } //Hardcoded to avoid single-usage-API - private void setTypeAndCheck(ToolWindowType type) { + private void setTypeAndCheck(@NotNull ToolWindowType type) { myType = ToolWindowId.PREVIEW == myId && type == ToolWindowType.DOCKED ? ToolWindowType.SLIDING : type; } @@ -420,7 +412,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo return myAnchor.hashCode()+myId.hashCode()+myType.hashCode()+myOrder; } - @SuppressWarnings({"HardCodedStringLiteral"}) + @SuppressWarnings("HardCodedStringLiteral") public String toString(){ return getClass().getName() + "[myId=" + myId + "; myVisible=" + myVisible @@ -439,7 +431,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo ']'; } - public boolean wasRead() { + boolean wasRead() { return myWasRead; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowedDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowedDecorator.java index 53e29a1a8749..0d1b997aff80 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowedDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowedDecorator.java @@ -15,14 +15,11 @@ */ package com.intellij.openapi.wm.impl; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.FrameWrapper; import org.jetbrains.annotations.NotNull; -public final class WindowedDecorator extends FrameWrapper { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.WindowedDecorator"); - +final class WindowedDecorator extends FrameWrapper { private final Project myProject; WindowedDecorator(@NotNull Project project, @NotNull WindowInfoImpl info, @NotNull InternalDecorator internalDecorator) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java index 249391cc253f..b11387bdb1dd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/FinalizableCommand.java @@ -17,6 +17,7 @@ package com.intellij.openapi.wm.impl.commands; import com.intellij.openapi.util.Condition; import com.intellij.openapi.wm.ToolWindowManager; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -27,15 +28,15 @@ public abstract class FinalizableCommand implements Runnable{ protected ToolWindowManager myManager; - public FinalizableCommand(final Runnable finishCallBack){ - myFinishCallBack=finishCallBack; + public FinalizableCommand(Runnable finishCallBack){ + myFinishCallBack = finishCallBack; } public final void finish(){ myFinishCallBack.run(); } - public void beforeExecute(final ToolWindowManager toolWindowManager) { + public void beforeExecute(@NotNull ToolWindowManager toolWindowManager) { myManager = toolWindowManager; } diff --git a/platform/testFramework/src/com/intellij/mock/Mock.java b/platform/testFramework/src/com/intellij/mock/Mock.java index d6d960f5bd17..89a0106fff6a 100644 --- a/platform/testFramework/src/com/intellij/mock/Mock.java +++ b/platform/testFramework/src/com/intellij/mock/Mock.java @@ -562,7 +562,7 @@ public class Mock { public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean canCloseContents) { throw new RuntimeException(); } @@ -572,7 +572,7 @@ public class Mock { public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode) { throw new RuntimeException(); } @@ -592,7 +592,7 @@ public class Mock { @NotNull @Override public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor, - final Disposable parentDisposable, final boolean dumbAware) { + @NotNull final Disposable parentDisposable, final boolean dumbAware) { throw new RuntimeException(); } @@ -601,7 +601,7 @@ public class Mock { public ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, - Disposable parentDisposable, + @NotNull Disposable parentDisposable, boolean canWorkInDumbMode, boolean secondary) { throw new RuntimeException(); diff --git a/platform/util/src/com/intellij/util/RetinaImage.java b/platform/util/src/com/intellij/util/RetinaImage.java index c9e0eda32c19..590b78241a4d 100644 --- a/platform/util/src/com/intellij/util/RetinaImage.java +++ b/platform/util/src/com/intellij/util/RetinaImage.java @@ -17,6 +17,7 @@ package com.intellij.util; import com.intellij.openapi.util.SystemInfo; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import java.awt.*; import java.awt.image.BufferedImage; @@ -50,6 +51,7 @@ public class RetinaImage { * @param observer the raw image observer * @return the Retina-aware wrapper */ + @NotNull public static Image createFrom(Image image, final int scale, ImageObserver observer) { int w = image.getWidth(observer); int h = image.getHeight(observer); @@ -65,11 +67,13 @@ public class RetinaImage { return hidpi; } + @NotNull public static BufferedImage create(final int width, int height, int type) { return create(null, width, height, type); } + @NotNull private static BufferedImage create(Image image, final int width, int height, int type) { if (SystemInfo.isAppleJvm) { return AppleHiDPIScaledImage.create(width, height, type); diff --git a/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java b/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java index 52aad13bc246..bdf89a41ddd6 100644 --- a/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java +++ b/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java @@ -183,8 +183,7 @@ class SchedulingWrapper implements ScheduledExecutorService { @Override public int compareTo(@NotNull Delayed other) { - if (other == this) // compare zero if same object - { + if (other == this) { return 0; } if (other instanceof MyScheduledFutureTask) { diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index a5ef76f881ef..ec24c55d3434 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -1779,6 +1779,7 @@ public class UIUtil { } } + @NotNull public static BufferedImage createImage(int width, int height, int type) { if (isRetina()) { return RetinaImage.create(width, height, type); @@ -1787,6 +1788,7 @@ public class UIUtil { return new BufferedImage(width, height, type); } + @NotNull public static BufferedImage createImageForGraphics(Graphics2D g, int width, int height, int type) { if (isRetina(g)) { return RetinaImage.create(width, height, type); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java index 3a4f74e753e6..6d234ea67fd7 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java @@ -60,7 +60,6 @@ import com.intellij.ui.*; import com.intellij.util.Alarm; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.Convertor; import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; @@ -196,7 +195,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { myReset = myCanChangePatchFile ? this::reset : EmptyRunnable.getInstance(); myChangeListChooser = new ChangeListChooserPanel(project, errorMessage -> { - setOKActionEnabled(errorMessage == null); + setOKActionEnabled(errorMessage == null && isChangeTreeEnabled()); setErrorText(errorMessage); }); ChangeListManager changeListManager = ChangeListManager.getInstance(project); @@ -244,7 +243,15 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { } private void updateOkActions() { - setOKActionEnabled(!myChangesTreeList.getIncludedChanges().isEmpty()); + boolean changeTreeEnabled = isChangeTreeEnabled(); + setOKActionEnabled(changeTreeEnabled); + if (changeTreeEnabled) { + myChangeListChooser.updateEnabled(); + } + } + + private boolean isChangeTreeEnabled() { + return !myChangesTreeList.getIncludedChanges().isEmpty(); } private void queueRequest() { @@ -371,6 +378,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { myReader = patchReader; updateTree(true); paintBusy(false); + updateOkActions(); }, ModalityState.stateForComponent(myCenterPanel)); } } @@ -519,8 +527,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { protected DefaultTreeModel buildTreeModel(List changes, ChangeNodeDecorator changeNodeDecorator) { TreeModelBuilder builder = new TreeModelBuilder(myProject, isShowFlatten()); - return builder.buildModel(ObjectsConvertor.convert(changes, - (Convertor)o -> o), changeNodeDecorator); + return builder.buildModel(ObjectsConvertor.convert(changes, o -> o), changeNodeDecorator); } @Override diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeListChooserPanel.form b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeListChooserPanel.form deleted file mode 100644 index 7228db028df1..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeListChooserPanel.form +++ /dev/null @@ -1,50 +0,0 @@ - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeListChooserPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeListChooserPanel.java index 363d5f1e319f..1c93f351669a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeListChooserPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeListChooserPanel.java @@ -15,20 +15,23 @@ */ package com.intellij.openapi.vcs.changes.ui; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.VcsConfiguration; import com.intellij.openapi.vcs.changes.ChangeList; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.LocalChangeList; import com.intellij.openapi.vcs.changes.committed.CommittedChangeListRenderer; -import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkRenderer; -import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.*; import com.intellij.util.NullableConsumer; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -36,140 +39,144 @@ import javax.swing.*; import java.awt.*; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.util.*; +import java.util.Collection; +import java.util.Collections; import java.util.List; -/** - * @author yole - */ -public class ChangeListChooserPanel extends JPanel { - private static final Comparator CHANGE_LIST_COMPARATOR = new Comparator() { - @Override - public int compare(ChangeList o1, ChangeList o2) { - return o1.getName().compareToIgnoreCase(o2.getName()); - } - }; +import static com.intellij.codeInsight.completion.ComboEditorCompletionContributor.CONTINUE_RUN_COMPLETION; - private JPanel myPanel; - private JRadioButton myRbExisting; - private JRadioButton myRbNew; - private JComboBox myExistingListsCombo; - private NewEditChangelistPanel myNewListPanel; +public class ChangeListChooserPanel extends JPanel { + + private final MyEditorComboBox myExistingListsCombo; + private final NewEditChangelistPanel myListPanel; private final NullableConsumer myOkEnabledListener; - private Project myProject; + private final Project myProject; + private String myLastTypedDescription; public ChangeListChooserPanel(final Project project, @NotNull final NullableConsumer okEnabledListener) { super(new BorderLayout()); myProject = project; - myOkEnabledListener = okEnabledListener; - add(myPanel, BorderLayout.CENTER); - - myRbExisting.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - updateEnabledItems(); - } - }); - } - - public void init() { - myExistingListsCombo.setRenderer(new ColoredListCellRendererWrapper() { - private final IssueLinkRenderer myLinkRenderer = new IssueLinkRenderer(myProject, this); - + myExistingListsCombo = new MyEditorComboBox(project); + myExistingListsCombo.setEditable(true); + myExistingListsCombo.setRenderer(new ColoredListCellRenderer() { @Override - protected void doCustomize(JList list, Object value, int index, boolean selected, boolean hasFocus) { - if (value instanceof LocalChangeList) { - String name = ((LocalChangeList) value).getName(); - - if (myExistingListsCombo.getWidth() == 0) { + protected void customizeCellRenderer(@NotNull JList list, + String value, + int index, + boolean selected, + boolean hasFocus) { + if (value != null) { + String name = value; + LocalChangeList changeList = ChangeListManager.getInstance(myProject).findChangeList(name); + int visibleWidth = myExistingListsCombo.getEditorTextField().getVisibleRect().width; + if (visibleWidth == 0) { name = name.length() > 10 ? name.substring(0, 7) + " .." : name; } else { final FontMetrics fm = list.getFontMetrics(list.getFont()); final int width = fm.stringWidth(name); - final int listWidth = myExistingListsCombo.getWidth(); - if ((listWidth > 0) && (width > listWidth)) { - final String truncated = CommittedChangeListRenderer.truncateDescription(name, fm, listWidth - fm.stringWidth(" ..") - 7); + if ((visibleWidth > 0) && (width > visibleWidth)) { + final String truncated = CommittedChangeListRenderer + .truncateDescription(name, fm, visibleWidth - fm.stringWidth(" ..") - 7); if (truncated.length() > 5) { name = truncated + " .."; } } } - myLinkRenderer.appendTextWithLinks(name, ((LocalChangeList)value).isDefault() - ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES); + append(name, changeList != null && changeList.isDefault() + ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES + : SimpleTextAttributes.REGULAR_ATTRIBUTES); } } }); - myNewListPanel.init(null); - myRbNew.addFocusListener(new FocusAdapter() { + myListPanel = new NewEditChangelistPanel(myProject) { + @Override - public void focusGained(FocusEvent e) { - if (myRbNew.isSelected()) { - IdeFocusManager.getInstance(myProject).requestFocus(myNewListPanel.getPreferredFocusedComponent(), true); - } + protected NewEditChangelistPanel.ComponentWithTextFieldWrapper createComponentWithTextField(Project project) { + return new ComponentWithTextFieldWrapper(myExistingListsCombo) { + @NotNull + @Override + public EditorTextField getEditorTextField() { + return myExistingListsCombo.getEditorTextField(); + } + }; } - }); - final ComboboxSpeedSearch search = new ComboboxSpeedSearch(myExistingListsCombo); - search.setComparator(new SpeedSearchComparator(true, false)); + + @Override + @CalledInAwt + protected void nameChanged(String errorMessage) { + //invoke later because of undo manager problem: when you try to undo changelist after description was already changed manually + ApplicationManager.getApplication().invokeLater(() -> updateDescription(), ModalityState.current()); + myOkEnabledListener.consume(errorMessage); + } + + @Override + public void init(LocalChangeList initial) { + super.init(initial); + myDescriptionTextArea.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + super.focusLost(e); + if (getExistingChangelist() == null) { + myLastTypedDescription = myListPanel.getDescription(); + } + } + }); + } + + @Override + protected void nameChangedImpl(Project project, LocalChangeList initial) { + nameChanged(StringUtil.isEmptyOrSpaces(getChangeListName()) ? "Cannot create new changelist with empty name." : null); + } + }; + myOkEnabledListener = okEnabledListener; + add(myListPanel, BorderLayout.CENTER); + } + + public void init() { + myListPanel.init(null); } public void setChangeLists(Collection changeLists) { - List list = new ArrayList(changeLists); - Collections.sort(list, CHANGE_LIST_COMPARATOR); - myExistingListsCombo.setModel(new CollectionComboBoxModel(list, null)); + List changelistNames = ContainerUtil.map(changeLists, ChangeList::getName); + Collections.sort(changelistNames); + myExistingListsCombo.setModel(new CollectionComboBoxModel(changelistNames)); } public void setDefaultName(String name) { - if (! StringUtil.isEmptyOrSpaces(name)) { - myNewListPanel.setChangeListName(name); + if (!StringUtil.isEmptyOrSpaces(name)) { + myListPanel.setChangeListName(name); } } - private void updateEnabledItems() { - if (myRbExisting.isSelected()) { - myExistingListsCombo.setEnabled(true); - UIUtil.setEnabled(myNewListPanel, false, true); - myExistingListsCombo.requestFocus(); - } - else { - myExistingListsCombo.setEnabled(false); - UIUtil.setEnabled(myNewListPanel, true, true); - myNewListPanel.requestFocus(); - } + public void updateEnabled() { if (myProject != null) { - myNewListPanel.nameChangedImpl(myProject, null); + myListPanel.nameChangedImpl(myProject, null); } } + /** + * Method used as getResult, usually invoked inside doOkAction + */ @Nullable public LocalChangeList getSelectedList(Project project) { ChangeListManager manager = ChangeListManager.getInstance(project); - if (myRbNew.isSelected()) { - String newText = myNewListPanel.getChangeListName(); - if (manager.findChangeList(newText) != null) { - Messages.showErrorDialog(project, - VcsBundle.message("changes.newchangelist.warning.already.exists.text", newText), - VcsBundle.message("changes.newchangelist.warning.already.exists.title")); - return null; - } - } - final boolean existingSelected = myRbExisting.isSelected(); - VcsConfiguration.getInstance(myProject).PRESELECT_EXISTING_CHANGELIST = existingSelected; + String changeListName = myListPanel.getChangeListName(); + LocalChangeList localChangeList = manager.findChangeList(changeListName); - if (existingSelected) { - return (LocalChangeList)myExistingListsCombo.getSelectedItem(); + if (localChangeList == null) { + localChangeList = manager.addChangeList(changeListName, myListPanel.getDescription()); + myListPanel.changelistCreatedOrChanged(localChangeList); } else { - LocalChangeList changeList = manager.addChangeList(myNewListPanel.getChangeListName(), myNewListPanel.getDescription()); - myNewListPanel.changelistCreatedOrChanged(changeList); - if (myNewListPanel.getMakeActiveCheckBox().isSelected()) { - manager.setDefaultChangeList(changeList); - } - VcsConfiguration.getInstance(project).MAKE_NEW_CHANGELIST_ACTIVE = myNewListPanel.getMakeActiveCheckBox().isSelected(); - - return changeList; + //update description if changed + localChangeList.setComment(myListPanel.getDescription()); } + if (myListPanel.getMakeActiveCheckBox().isSelected()) { + manager.setDefaultChangeList(localChangeList); + } + VcsConfiguration.getInstance(project).MAKE_NEW_CHANGELIST_ACTIVE = myListPanel.getMakeActiveCheckBox().isSelected(); + return localChangeList; } public void setDefaultSelection(final ChangeList defaultSelection) { @@ -177,34 +184,46 @@ public class ChangeListChooserPanel extends JPanel { myExistingListsCombo.setSelectedIndex(0); } else { - myExistingListsCombo.setSelectedItem(defaultSelection); - } - //if defaultSelection was predefined as null then it means we could not use existing is this context - if (defaultSelection != null && VcsConfiguration.getInstance(myProject).PRESELECT_EXISTING_CHANGELIST) { - myRbExisting.setSelected(true); - } - else { - myRbNew.setSelected(true); + myExistingListsCombo.setSelectedItem(defaultSelection.getName()); } + updateDescription(); + updateEnabled(); + } - updateEnabledItems(); + private void updateDescription() { + LocalChangeList list = getExistingChangelist(); + String newText = list != null ? list.getComment() : myLastTypedDescription; + if (!StringUtil.equals(myListPanel.getDescription(), newText)) { + myListPanel.setDescription(newText); + } + } + + private LocalChangeList getExistingChangelist() { + ChangeListManager manager = ChangeListManager.getInstance(myProject); + String changeListName = myListPanel.getChangeListName(); + return manager.findChangeList(changeListName); } public JComponent getPreferredFocusedComponent() { - return myRbExisting.isSelected() ? myExistingListsCombo : myNewListPanel.getPreferredFocusedComponent(); + return myExistingListsCombo; } - private void createUIComponents() { - myNewListPanel = new NewEditChangelistPanel(myProject) { + private static class MyEditorComboBox extends ComboBox { - @Override - protected void nameChanged(String errorMessage) { - if (myRbExisting.isSelected()) { - myOkEnabledListener.consume(null); - } else { - myOkEnabledListener.consume(errorMessage); + public MyEditorComboBox(Project project) { + super(); + setEditor(new StringComboboxEditor(project, FileTypes.PLAIN_TEXT, this) { + @Override + protected void onEditorCreate(EditorEx editor) { + super.onEditorCreate(editor); + getDocument().putUserData(CONTINUE_RUN_COMPLETION, true); } - } - }; + }); + } + + @NotNull + private EditorTextField getEditorTextField() { + return ObjectUtils.assertNotNull((EditorTextField)getEditor().getEditorComponent()); + } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/NewEditChangelistPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/NewEditChangelistPanel.java index e9a1fa117556..98260d3f6a08 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/NewEditChangelistPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/NewEditChangelistPanel.java @@ -17,8 +17,8 @@ package com.intellij.openapi.vcs.changes.ui; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.SpellCheckingEditorCustomizationProvider; +import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.editor.event.DocumentListener; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; @@ -30,19 +30,20 @@ import com.intellij.ui.*; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.JBUI; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; import java.util.Set; public abstract class NewEditChangelistPanel extends JPanel { - private EditorTextField myNameTextField; - private EditorTextField myDescriptionTextArea; - private JPanel myAdditionalControlsPanel; - private JCheckBox myMakeActiveCheckBox; + protected final EditorTextField myNameTextField; + protected final EditorTextField myDescriptionTextArea; + private final JPanel myAdditionalControlsPanel; + private final JCheckBox myMakeActiveCheckBox; private Consumer myConsumer; - private final Project myProject; + protected final Project myProject; public NewEditChangelistPanel(final Project project) { super(new GridBagLayout()); @@ -52,14 +53,15 @@ public abstract class NewEditChangelistPanel extends JPanel { final JLabel nameLabel = new JLabel(VcsBundle.message("edit.changelist.name")); add(nameLabel, gb); - ++ gb.gridx; + ++gb.gridx; gb.fill = GridBagConstraints.HORIZONTAL; gb.weightx = 1; - myNameTextField = createEditorField(project, 1); + ComponentWithTextFieldWrapper componentWithTextField = createComponentWithTextField(project); + myNameTextField = componentWithTextField.getEditorTextField(); myNameTextField.setOneLineMode(true); myNameTextField.setText("New changelist"); myNameTextField.selectAll(); - add(myNameTextField, gb); + add(componentWithTextField.myComponent, gb); nameLabel.setLabelFor(myNameTextField); ++ gb.gridy; @@ -100,11 +102,7 @@ public abstract class NewEditChangelistPanel extends JPanel { support.installSearch(myNameTextField, myDescriptionTextArea); myConsumer = support.addControls(myAdditionalControlsPanel, initial); } - myNameTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void beforeDocumentChange(DocumentEvent event) { - } - + myNameTextField.getDocument().addDocumentListener(new DocumentAdapter() { @Override public void documentChanged(DocumentEvent event) { nameChangedImpl(myProject, initial); @@ -160,6 +158,17 @@ public abstract class NewEditChangelistPanel extends JPanel { protected abstract void nameChanged(String errorMessage); + protected ComponentWithTextFieldWrapper createComponentWithTextField(Project project) { + final EditorTextField editorTextField = createEditorField(project, 1); + return new ComponentWithTextFieldWrapper(editorTextField) { + @NotNull + @Override + public EditorTextField getEditorTextField() { + return editorTextField; + } + }; + } + private static EditorTextField createEditorField(final Project project, final int defaultLines) { final EditorTextFieldProvider service = ServiceManager.getService(project, EditorTextFieldProvider.class); final EditorTextField editorField; @@ -178,4 +187,15 @@ public abstract class NewEditChangelistPanel extends JPanel { editorField.getComponent().setMinimumSize(new Dimension(100, (int)(height * 1.3))); return editorField; } + + protected abstract static class ComponentWithTextFieldWrapper { + @NotNull private final Component myComponent; + + public ComponentWithTextFieldWrapper(@NotNull Component component) { + myComponent = component; + } + + @NotNull + abstract EditorTextField getEditorTextField(); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java index b158bf52d26e..fc1252f72e40 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java @@ -33,6 +33,8 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerAdapter; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; @@ -128,24 +130,35 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme private final VcsFileListenerContextHelper myVcsFileListenerContextHelper; private final VcsAnnotationLocalChangesListenerImpl myAnnotationLocalChangesListener; - public ProjectLevelVcsManagerImpl(Project project, final FileStatusManager manager, MessageBus messageBus, - final FileIndexFacade excludedFileIndex) { + public ProjectLevelVcsManagerImpl(Project project, + final FileStatusManager manager, + MessageBus messageBus, + final FileIndexFacade excludedFileIndex, + ProjectManager projectManager, + DefaultVcsRootPolicy defaultVcsRootPolicy, + VcsFileListenerContextHelper vcsFileListenerContextHelper) { myProject = project; myMessageBus = messageBus; mySerialization = new ProjectLevelVcsManagerSerialization(); myOptionsAndConfirmations = new OptionsAndConfirmations(); - myDefaultVcsRootPolicy = DefaultVcsRootPolicy.getInstance(project); + myDefaultVcsRootPolicy = defaultVcsRootPolicy; myInitialization = new VcsInitialization(myProject); Disposer.register(project, myInitialization); // wait for the thread spawned in VcsInitialization to terminate + projectManager.addProjectManagerListener(project, new ProjectManagerAdapter() { + @Override + public void projectClosing(Project project) { + Disposer.dispose(myInitialization); + } + }); myMappings = new NewMappings(myProject, myMessageBus, this, manager); myMappingsToRoots = new MappingsToRoots(myMappings, myProject); myVcsHistoryCache = new VcsHistoryCache(); myContentRevisionCache = new ContentRevisionCache(); myConnect = myMessageBus.connect(); - myVcsFileListenerContextHelper = VcsFileListenerContextHelper.getInstance(myProject); + myVcsFileListenerContextHelper = vcsFileListenerContextHelper; VcsListener vcsListener = new VcsListener() { @Override public void directoryMappingChanged() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java index 83498737c18b..b6ee4ff05886 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsInitialization.java @@ -76,7 +76,7 @@ public class VcsInitialization implements Disposable { } } - public void execute() { + private void execute() { final List> list; synchronized (myLock) { list = myList; @@ -103,6 +103,11 @@ public class VcsInitialization implements Disposable { @Override public void dispose() { myIndicator.cancel(); + cancelBackgroundInitialization(); + } + + private void cancelBackgroundInitialization() { + // do not leave VCS initialization run in background when the project is closed Future future = myFuture; if (future != null) { future.cancel(false); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/hierarchy/GrStubIndexer.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/hierarchy/GrStubIndexer.java index 2a9303c09d62..c124aae6cc20 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/hierarchy/GrStubIndexer.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/hierarchy/GrStubIndexer.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.groovy.lang.psi.stubs.hierarchy; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiNameHelper; import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree; @@ -33,7 +32,10 @@ import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.stubs.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; public class GrStubIndexer extends StubHierarchyIndexer { @Override @@ -48,14 +50,14 @@ public class GrStubIndexer extends StubHierarchyIndexer { @Nullable @Override - public List> indexFile(@NotNull FileContent content) { + public Unit indexFile(@NotNull FileContent content) { Stub stubTree = StubTreeBuilder.buildStubTree(content); if (!(stubTree instanceof GrFileStub)) return null; GrFileStub grFileStub = (GrFileStub)stubTree; new StubTree(grFileStub, false); - String pid = null; + String pid = ""; ArrayList classList = new ArrayList(); Set usedNames = new HashSet(); for (StubElement el : grFileStub.getChildrenStubs()) { @@ -82,7 +84,7 @@ public class GrStubIndexer extends StubHierarchyIndexer { } ClassDecl[] classes = classList.isEmpty() ? ClassDecl.EMPTY_ARRAY : classList.toArray(new ClassDecl[classList.size()]); Import[] imports = importList.isEmpty() ? Import.EMPTY_ARRAY : importList.toArray(new Import[importList.size()]); - return Collections.singletonList(Pair.create(pid, new Unit(IndexTree.GROOVY, imports, classes))); + return new Unit(pid, IndexTree.GROOVY, imports, classes); } @Nullable diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java index 99163eea7916..35ecc643f5bf 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyBasePluginConfigurator.java @@ -56,6 +56,11 @@ public abstract class StudyBasePluginConfigurator implements StudyPluginConfigur @Override public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) { + for (VirtualFile openedFile : source.getOpenFiles()) { + if (StudyUtils.getTaskFile(project, openedFile) != null) { + return; + } + } toolWindow.setEmptyText(project); } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java index cfb8faa2bbb0..5a505d0bb7f3 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java @@ -26,6 +26,8 @@ import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.util.containers.hash.HashMap; import com.jetbrains.edu.learning.actions.StudyActionWithShortcut; +import com.jetbrains.edu.learning.actions.StudyNextWindowAction; +import com.jetbrains.edu.learning.actions.StudyPrevWindowAction; import com.jetbrains.edu.learning.core.EduNames; import com.jetbrains.edu.learning.core.EduUtils; import com.jetbrains.edu.learning.courseFormat.Course; @@ -113,6 +115,8 @@ public class StudyProjectComponent implements ProjectComponent { } } } + addShortcut(StudyNextWindowAction.ACTION_ID, new String[]{StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.SHORTCUT2}); + addShortcut(StudyPrevWindowAction.ACTION_ID, new String[]{StudyPrevWindowAction.SHORTCUT}); } else { LOG.warn("Actions on toolbar are nulls"); diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java b/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java index 363e73e37018..97495aad8f0d 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyTaskNavigationAction.java @@ -8,7 +8,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; -import com.intellij.util.ui.tree.TreeUtil; import com.jetbrains.edu.learning.StudyState; import com.jetbrains.edu.learning.StudyUtils; import com.jetbrains.edu.learning.core.EduNames; @@ -44,9 +43,6 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut int nextTaskIndex = nextTask.getIndex(); int lessonIndex = nextTask.getLesson().getIndex(); Map nextTaskFiles = nextTask.getTaskFiles(); - if (nextTaskFiles.isEmpty()) { - return; - } VirtualFile projectDir = project.getBaseDir(); String lessonDirName = EduNames.LESSON + String.valueOf(lessonIndex); if (projectDir == null) { @@ -61,15 +57,26 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut if (taskDir == null) { return; } + if (nextTaskFiles.isEmpty()) { + ProjectView.getInstance(project).select(taskDir, taskDir, false); + return; + } VirtualFile shouldBeActive = getFileToActivate(project, nextTaskFiles, taskDir); JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree(); - TreePath path = TreeUtil.getFirstNodePath(tree); - tree.collapsePath(path); + TreePath path = tree.getSelectionPath(); + if (path != null) { + TreePath oldSelectionPath = path.getParentPath(); + if (oldSelectionPath != null) { + tree.collapsePath(oldSelectionPath); + tree.fireTreeCollapsed(oldSelectionPath); + } + } if (shouldBeActive != null) { ProjectView.getInstance(project).select(shouldBeActive, shouldBeActive, false); FileEditorManager.getInstance(project).openFile(shouldBeActive, true); } + ToolWindow runToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.RUN); if (runToolWindow != null) { runToolWindow.hide(null); @@ -82,11 +89,13 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut for (Map.Entry entry : nextTaskFiles.entrySet()) { String name = entry.getKey(); TaskFile taskFile = entry.getValue(); - VirtualFile srcDir = taskDir.findChild("src"); + VirtualFile srcDir = taskDir.findChild(EduNames.SRC); VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name); if (vf != null) { - FileEditorManager.getInstance(project).openFile(vf, true); - if (!taskFile.getAnswerPlaceholders().isEmpty()) { + if (shouldBeActive != null) { + FileEditorManager.getInstance(project).openFile(vf, true); + } + if (shouldBeActive == null && !taskFile.getAnswerPlaceholders().isEmpty()) { shouldBeActive = vf; } } diff --git a/python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestsConfigurationProducer.java b/python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestsConfigurationProducer.java index 617345600d30..80f40044bca7 100644 --- a/python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestsConfigurationProducer.java +++ b/python/educational-python/course-creator-python/src/com/jetbrains/edu/coursecreator/run/PyCCRunTestsConfigurationProducer.java @@ -81,7 +81,8 @@ public class PyCCRunTestsConfigurationProducer extends RunConfigurationProducer< String testsPath = taskDir.findChild(EduNames.SRC) != null ? FileUtil.join(taskDirPath, EduNames.SRC, EduNames.TESTS_FILE) : FileUtil.join(taskDirPath, EduNames.TESTS_FILE); - return file.getPath().equals(testsPath) ? testsPath : null; + String filePath = FileUtil.toSystemDependentName(file.getPath()); + return filePath.equals(testsPath) ? testsPath : null; } @Override diff --git a/python/educational-python/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java b/python/educational-python/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java index 49d301b1c327..d479b31c6893 100644 --- a/python/educational-python/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java +++ b/python/educational-python/src/com/jetbrains/python/edu/PyCharmEduInitialConfigurator.java @@ -56,10 +56,15 @@ import com.intellij.openapi.project.ProjectManagerAdapter; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.*; import com.intellij.platform.DirectoryProjectConfigurator; import com.intellij.platform.PlatformProjectViewOpener; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiManager; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.ui.treeStructure.Tree; @@ -68,6 +73,7 @@ import com.intellij.util.messages.MessageBus; import com.intellij.util.ui.tree.TreeUtil; import com.jetbrains.python.PythonLanguage; import com.jetbrains.python.codeInsight.PyCodeInsightSettings; +import com.jetbrains.python.inspections.PyPep8Inspection; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,6 +83,7 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -201,7 +208,11 @@ public class PyCharmEduInitialConfigurator { @Override public void run() { if (project.isDisposed()) return; + updateInspectionsProfile(); + openProjectStructure(); + } + private void openProjectStructure() { ToolWindowManager.getInstance(project).invokeLater(new Runnable() { int count = 0; @@ -212,12 +223,24 @@ public class PyCharmEduInitialConfigurator { return; } ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Project"); - if (toolWindow !=null && toolWindow.getType() != ToolWindowType.SLIDING) { + if (toolWindow != null && toolWindow.getType() != ToolWindowType.SLIDING) { toolWindow.activate(null); } } }); } + + private void updateInspectionsProfile() { + final String[] codes = new String[]{"W29", "E501"}; + final VirtualFile baseDir = project.getBaseDir(); + final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(baseDir); + if (directory != null) { + InspectionProjectProfileManager.getInstance(project).getInspectionProfile().modifyToolSettings( + Key.create(PyPep8Inspection.INSPECTION_SHORT_NAME), directory, + inspection -> Collections.addAll(inspection.ignoredErrors, codes) + ); + } + } }); } }); diff --git a/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py b/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py index 19be9971bda1..c9078e14457d 100644 --- a/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py +++ b/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py @@ -114,6 +114,31 @@ class StdIn(BaseStdIn): return '\n' +#======================================================================================================================= +# DebugConsoleStdIn +#======================================================================================================================= +class DebugConsoleStdIn(BaseStdIn): + ''' + Object to be added to stdin (to emulate it as non-blocking while the next line arrives) + ''' + + def __init__(self, dbg, original_stdin): + BaseStdIn.__init__(self) + self.debugger = dbg + self.original_stdin = original_stdin + + def readline(self, *args, **kwargs): + # Notify Java side about input and call original function + try: + cmd = self.debugger.cmd_factory.make_input_requested_message() + self.debugger.writer.add_command(cmd) + except Exception: + import traceback + traceback.print_exc() + return '\n' + return self.original_stdin.readline(*args, **kwargs) + + class CodeFragment: def __init__(self, text, is_single_line=True): self.text = text diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py index babdc3571d0a..ec0c13d692b5 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py @@ -138,6 +138,7 @@ CMD_GET_ARRAY = 143 CMD_STEP_INTO_MY_CODE = 144 CMD_GET_CONCURRENCY_EVENT = 145 CMD_SHOW_RETURN_VALUES = 146 +CMD_INPUT_REQUESTED = 147 CMD_VERSION = 501 CMD_RETURN = 502 @@ -191,6 +192,7 @@ ID_TO_MEANING = { '144': 'CMD_STEP_INTO_MY_CODE', '145': 'CMD_GET_CONCURRENCY_EVENT', '146': 'CMD_SHOW_RETURN_VALUES', + '147': 'CMD_INPUT_REQUESTED', '501': 'CMD_VERSION', '502': 'CMD_RETURN', @@ -779,6 +781,13 @@ class NetCommandFactory: except: return self.make_error_message(0, get_exception_traceback_str()) + def make_input_requested_message(self): + try: + return NetCommand(CMD_INPUT_REQUESTED, 0, '') + except: + return self.make_error_message(0, get_exception_traceback_str()) + + def make_exit_message(self): try: net = NetCommand(CMD_EXIT, 0, '') diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py index b27daef92c57..e333f90df1c7 100644 --- a/python/helpers/pydev/pydevd.py +++ b/python/helpers/pydev/pydevd.py @@ -1180,6 +1180,7 @@ def _locked_settrace( if bufferStdErrToServer: init_stderr_redirect() + patch_stdin(debugger) debugger.set_trace_for_frame_and_parents(get_frame(), False, overwrite_prev_trace=overwrite_prev_trace) @@ -1382,6 +1383,12 @@ def apply_debugger_options(setup_options): enable_qt_support() +def patch_stdin(debugger): + from _pydev_bundle.pydev_console_utils import DebugConsoleStdIn + orig_stdin = sys.stdin + sys.stdin = DebugConsoleStdIn(debugger, orig_stdin) + + #======================================================================================================================= # main #======================================================================================================================= @@ -1512,6 +1519,7 @@ if __name__ == '__main__': pass # It's ok not having stackless there... is_module = setup['module'] + patch_stdin(debugger) if fix_app_engine_debug: sys.stderr.write("pydev debugger: google app engine integration enabled\n") diff --git a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java index 1bdc5359402e..6952315028b8 100644 --- a/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java +++ b/python/ide/src/com/jetbrains/python/newProject/actions/ProjectSpecificSettingsStep.java @@ -139,6 +139,7 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase impleme super.initGeneratorListeners(); if (myProjectGenerator instanceof PythonProjectGenerator) { ((PythonProjectGenerator)myProjectGenerator).addSettingsStateListener(this::checkValid); + myErrorLabel.addMouseListener(((PythonProjectGenerator)myProjectGenerator).getErrorLabelMouseListener()); } } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java b/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java index 82155bacd88f..ce55d8e87e83 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/IPyDebugProcess.java @@ -37,5 +37,7 @@ public interface IPyDebugProcess extends PyFrameAccessor { boolean isSuspendedOnAllThreadsPolicy(); + void consoleInputRequested(); + XDebugSession getSession(); } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java index 4ed466cacbc6..941e39343ba4 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/AbstractCommand.java @@ -50,6 +50,7 @@ public abstract class AbstractCommand { public static final int STEP_INTO_MY_CODE = 144; public static final int LOG_CONCURRENCY_EVENT = 145; public static final int SHOW_RETURN_VALUES = 146; + public static final int INPUT_REQUESTED = 147; public static final int ERROR = 901; @@ -197,6 +198,10 @@ public abstract class AbstractCommand { return command == WRITE_TO_CONSOLE; } + public static boolean isInputRequested(final int command) { + return command == INPUT_REQUESTED; + } + public static boolean isExitEvent(final int command) { return command == EXIT; } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java index 7b15821aef8b..08b93e8fbfa1 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java @@ -547,6 +547,9 @@ public class RemoteDebugger implements ProcessDebugger { else if (AbstractCommand.isConcurrencyEvent(frame.getCommand())) { recordConcurrencyEvent(ProtocolParser.parseConcurrencyEvent(frame.getPayload(), myDebugProcess.getPositionConverter())); } + else if (AbstractCommand.isInputRequested(frame.getCommand())) { + myDebugProcess.consoleInputRequested(); + } else { placeResponse(frame.getSequence(), frame); } diff --git a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java index 4f1b10b78692..67f52844bfe9 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleExecuteActionHandler.java @@ -100,6 +100,10 @@ public class PydevConsoleExecuteActionHandler extends ProcessBackedConsoleExecut sendLineToConsole(new ConsoleCommunication.ConsoleCodeFragment(myInputBuffer.toString(), false)); } + public void clearInputBuffer() { + myInputBuffer = null; + } + private void processOneLine(String line) { int indentSize = IndentHelperImpl.getIndent(getProject(), PythonFileType.INSTANCE, line, false); line = StringUtil.trimTrailing(line); diff --git a/python/src/com/jetbrains/python/console/PythonConsoleView.java b/python/src/com/jetbrains/python/console/PythonConsoleView.java index e3e17b295f02..98a25946f70b 100644 --- a/python/src/com/jetbrains/python/console/PythonConsoleView.java +++ b/python/src/com/jetbrains/python/console/PythonConsoleView.java @@ -95,6 +95,18 @@ public class PythonConsoleView extends LanguageConsoleImpl implements Observable myExecuteActionHandler = consoleExecuteActionHandler; } + public void inputRequested() { + if (myExecuteActionHandler != null) { + final ConsoleCommunication consoleCommunication = myExecuteActionHandler.getConsoleCommunication(); + if (consoleCommunication instanceof PythonDebugConsoleCommunication) { + ((PythonDebugConsoleCommunication)consoleCommunication).waitingForInput = true; + myExecuteActionHandler.inputRequested(); + myExecuteActionHandler.setEnabled(true); + myExecuteActionHandler.clearInputBuffer(); + } + } + } + @Override public void requestFocus() { IdeFocusManager.findInstance().requestFocus(getConsoleEditor().getContentComponent(), true); diff --git a/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java b/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java index 25eb30cc0552..78ecbf99578b 100644 --- a/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java +++ b/python/src/com/jetbrains/python/console/PythonDebugConsoleCommunication.java @@ -15,8 +15,10 @@ */ package com.jetbrains.python.console; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.util.Function; import com.jetbrains.python.console.pydev.AbstractConsoleCommunication; import com.jetbrains.python.console.pydev.InterpreterResponse; @@ -26,12 +28,16 @@ import com.jetbrains.python.debugger.PyDebuggerException; import com.jetbrains.python.debugger.pydev.PyDebugCallback; import org.jetbrains.annotations.NotNull; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; import java.util.List; /** * @author traff */ public class PythonDebugConsoleCommunication extends AbstractConsoleCommunication { + private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.console.pydev.PythonDebugConsoleCommunication"); private final PyDebugProcess myDebugProcess; private final StringBuilder myExpression = new StringBuilder(); @@ -55,7 +61,7 @@ public class PythonDebugConsoleCommunication extends AbstractConsoleCommunicatio @Override public boolean isWaitingForInput() { - return false; + return waitingForInput; } @Override @@ -78,24 +84,41 @@ public class PythonDebugConsoleCommunication extends AbstractConsoleCommunicatio } public void execInterpreter(ConsoleCodeFragment code, final Function callback) { - myExpression.append(code.getText()); - exec(new ConsoleCodeFragment(myExpression.toString(), false), new PyDebugCallback>() { - @Override - public void ok(Pair executed) { - boolean more = executed.second; - - if (!more) { - myExpression.setLength(0); + if (waitingForInput) { + final OutputStream processInput = myDebugProcess.getProcessHandler().getProcessInput(); + if (processInput != null) { + try { + final Charset defaultCharset = EncodingProjectManager.getInstance(myDebugProcess.getProject()).getDefaultCharset(); + processInput.write((code.getText()).getBytes(defaultCharset)); + processInput.flush(); + } + catch (IOException e) { + LOG.error(e.getMessage()); } - callback.fun(new InterpreterResponse(more, isWaitingForInput())); } + waitingForInput = false; + } + else { - @Override - public void error(PyDebuggerException exception) { - myExpression.setLength(0); - callback.fun(new InterpreterResponse(false, isWaitingForInput())); - } - }); + myExpression.append(code.getText()); + exec(new ConsoleCodeFragment(myExpression.toString(), false), new PyDebugCallback>() { + @Override + public void ok(Pair executed) { + boolean more = executed.second; + + if (!more) { + myExpression.setLength(0); + } + callback.fun(new InterpreterResponse(more, isWaitingForInput())); + } + + @Override + public void error(PyDebuggerException exception) { + myExpression.setLength(0); + callback.fun(new InterpreterResponse(false, isWaitingForInput())); + } + }); + } } @Override diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index ea7c3afccd9c..3570746593d0 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -346,6 +346,13 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr } } + @Override + public void consoleInputRequested() { + if (myExecutionConsole instanceof PythonDebugLanguageConsoleView) { + ((PythonDebugLanguageConsoleView)myExecutionConsole).getPydevConsoleView().inputRequested(); + } + } + protected void afterConnect() { } @@ -526,7 +533,8 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr breakpoint = myRegisteredExceptionBreakpoints.get(exceptionName); } } - if ((breakpoint != null) && (breakpoint.getSuspendPolicy() == SuspendPolicy.ALL)) { + if ((breakpoint != null) && (breakpoint.getType().isSuspendThreadSupported()) && + (breakpoint.getSuspendPolicy() == SuspendPolicy.ALL)) { return true; } } @@ -848,7 +856,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr } } if (breakpoint != null) { - if (breakpoint.getSuspendPolicy() == SuspendPolicy.ALL) { + if ((breakpoint.getType().isSuspendThreadSupported()) && (breakpoint.getSuspendPolicy() == SuspendPolicy.ALL)) { suspendAllOtherThreads(threadInfo); } } diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index f45a1331e6b7..f4e78a80c7c8 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -59,7 +59,6 @@ import com.intellij.remote.ext.LanguageCaseCollector; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.ExceptionUtil; -import com.intellij.util.NullableConsumer; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; @@ -322,9 +321,11 @@ public final class PythonSdkType extends SdkType { final String version = getVersionString(sdk); if (flavor != null && version != null) { for (Sdk baseSdk : getAllSdks()) { - final PythonSdkFlavor baseFlavor = PythonSdkFlavor.getFlavor(baseSdk); - if (!isVirtualEnv(baseSdk) && flavor.equals(baseFlavor) && version.equals(getVersionString(baseSdk))) { - return baseSdk; + if (!isRemote(baseSdk)) { + final PythonSdkFlavor baseFlavor = PythonSdkFlavor.getFlavor(baseSdk); + if (!isVirtualEnv(baseSdk) && flavor.equals(baseFlavor) && version.equals(getVersionString(baseSdk))) { + return baseSdk; + } } } } diff --git a/resources-en/src/inspectionDescriptions/RedundantLambdaParameterType.html b/resources-en/src/inspectionDescriptions/RedundantLambdaParameterType.html new file mode 100644 index 000000000000..ea49461e2613 --- /dev/null +++ b/resources-en/src/inspectionDescriptions/RedundantLambdaParameterType.html @@ -0,0 +1,5 @@ + + +This inspection removes lambda formal parameter types when they can be inferred from context. + + \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/after.java.template b/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/after.java.template deleted file mode 100644 index 925e26bf3039..000000000000 --- a/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/after.java.template +++ /dev/null @@ -1,5 +0,0 @@ -class X { - { - Comparable c = o -> 0; - } -} \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/before.java.template b/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/before.java.template deleted file mode 100644 index 84da2abb9213..000000000000 --- a/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/before.java.template +++ /dev/null @@ -1,5 +0,0 @@ -class X { - { - Comparable c = (String o) -> 0; - } -} \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/description.html b/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/description.html deleted file mode 100644 index 7e47e9314b11..000000000000 --- a/resources-en/src/intentionDescriptions/RedundantLambdaParameterTypeIntention/description.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This intention removes lambda formal parameter types when they can be inferred from context. - - \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/after.java.template b/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/after.java.template deleted file mode 100644 index 6bbd9d56135a..000000000000 --- a/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/after.java.template +++ /dev/null @@ -1,8 +0,0 @@ -public class X { - void f(int i) { - if (i==0) { - return; - } - int j = 0; - } -} \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/before.java.template b/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/before.java.template deleted file mode 100644 index edad99d14f45..000000000000 --- a/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/before.java.template +++ /dev/null @@ -1,10 +0,0 @@ -public class X { - void f(int i) { - if (i==0) { - return; - } - else { - int j = 0; - } - } -} \ No newline at end of file diff --git a/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/description.html b/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/description.html deleted file mode 100644 index 8992a7b29b2c..000000000000 --- a/resources-en/src/intentionDescriptions/RemoveRedundantElseAction/description.html +++ /dev/null @@ -1,7 +0,0 @@ - - -This intention detaches else clause from the if statement, -if corresponding then clause never completes normally. - - - diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 29201b0565b2..ca43d4c44eda 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -800,11 +800,12 @@ groupKey="group.names.declaration.redundancy" enabledByDefault="true" level="WARNING" implementationClass="com.intellij.codeInspection.SimplifyStreamApiCallChainsInspection" displayName="Simplify stream API call chains"/> + - - com.intellij.codeInsight.daemon.quickFix.RedundantLambdaParameterTypeIntention - Java/Declaration - com.intellij.codeInsight.intention.impl.SplitIfAction Java/Control Flow @@ -825,10 +826,6 @@ com.intellij.codeInsight.intention.impl.ExtractIfConditionAction Java/Control Flow - - com.intellij.codeInsight.daemon.impl.quickfix.RemoveRedundantElseAction - Java/Control Flow - com.intellij.codeInsight.intention.impl.AddNotNullAnnotationIntention Java/Annotations