diff --git a/RegExpSupport/test/org/intellij/lang/regexp/BaseParseTestCase.java b/RegExpSupport/test/org/intellij/lang/regexp/BaseParseTestCase.java index fe32c28d3d6c..d7881a5b748a 100644 --- a/RegExpSupport/test/org/intellij/lang/regexp/BaseParseTestCase.java +++ b/RegExpSupport/test/org/intellij/lang/regexp/BaseParseTestCase.java @@ -25,6 +25,7 @@ import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import com.intellij.testFramework.fixtures.TestFixtureBuilder; +import org.jetbrains.annotations.NotNull; import java.io.File; @@ -45,7 +46,7 @@ public abstract class BaseParseTestCase extends UsefulTestCase { new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { FileTypeManager.getInstance().registerFileType(RegExpFileType.INSTANCE, new String[]{"regexp"}); } }.execute(); diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index 12e9cf745226..d51b554f9bc7 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -238,7 +238,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir jar("jps-model.jar") { jpsCommonModules.each { module it } } - jar("jps-server.jar") { + jar("jps-builders.jar") { module("jps-builders") } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java index 36021fd098b8..5f4ff24b6c05 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,7 +17,6 @@ package com.intellij.compiler.impl; import com.intellij.compiler.impl.generic.GenericCompilerCache; import com.intellij.compiler.impl.generic.GenericCompilerPersistentData; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.RunResult; @@ -111,7 +110,7 @@ public class GenericCompilerRunner { final Set targetsToRemove = new HashSet(data.getAllTargets()); new ReadAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { for (T target : instance.getAllTargets()) { targetsToRemove.remove(target.getId()); } @@ -290,7 +289,7 @@ public class GenericCompilerRunner { } final RunResult runResult = new ReadAction() { - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { for (Item item : processedItems) { SourceState sourceState = sourceStates.get(item); if (sourceState == null) { diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java index 2b990dc055ef..b1fbe24330d4 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import com.intellij.openapi.module.ConfigurationErrorType; import com.intellij.openapi.project.Project; import com.intellij.packaging.artifacts.ArtifactManager; import com.intellij.packaging.artifacts.ModifiableArtifactModel; +import org.jetbrains.annotations.NotNull; /** * @author nik @@ -42,7 +43,7 @@ public class ArtifactLoadingErrorDescription extends ConfigurationErrorDescripti final ModifiableArtifactModel model = ArtifactManager.getInstance(myProject).createModifiableModel(); model.removeArtifact(myArtifact); new WriteAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { model.commit(); } }.execute(); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java index 09d6ba2e1be2..eca0d28434df 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -48,7 +48,7 @@ public class ArtifactBuildTargetScopeProvider extends BuildTargetScopeProvider { } final List scopes = new ArrayList(); new ReadAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final Set artifacts = ArtifactCompileScope.getArtifactsToBuild(project, baseScope, false); if (ArtifactCompileScope.getArtifacts(baseScope) == null) { Set modules = ArtifactUtil.getModulesIncludedInArtifacts(artifacts, project); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java index d4070de6b844..c0c662adc335 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactManager; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope; import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType; @@ -48,7 +49,7 @@ public class ArtifactCompilerUtil { public static MultiMap createOutputToArtifactMap(final Project project) { final MultiMap result = MultiMap.create(FileUtil.PATH_HASHING_STRATEGY); new ReadAction() { - protected void run(final Result r) { + protected void run(@NotNull final Result r) { for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) { String outputPath = artifact.getOutputFilePath(); if (!StringUtil.isEmpty(outputPath)) { diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java index 10e085ab595a..0009426af389 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -280,7 +280,7 @@ public class ManifestFileUtil { ApplicationManager.getApplication().assertIsDispatchThread(); final Ref exc = Ref.create(null); final VirtualFile file = new WriteAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { VirtualFile dir = directory; try { if (!dir.getName().equals(MANIFEST_DIR_NAME)) { diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java index 5a09db3fe950..8a72229aea95 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java @@ -169,7 +169,7 @@ public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider artifacts = new ArrayList(); new ReadAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { for (ArtifactPointer pointer : task.getArtifactPointers()) { ContainerUtil.addIfNotNull(pointer.getArtifact(), artifacts); } diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java index 8f815f35c40c..ca579d7bd4f1 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -88,7 +88,7 @@ public class PackageFileWorker { indicator.checkCanceled(); new ReadAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { try { packageFile(file, project, artifacts, packIntoArchives); } diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java index 15e9c44a01cf..cd40ee569b80 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.compiler; import com.intellij.ProjectTopics; @@ -32,9 +47,10 @@ import com.intellij.util.concurrency.Semaphore; import com.intellij.util.io.TestFileSystemBuilder; import com.intellij.util.ui.UIUtil; import gnu.trove.THashSet; -import junit.framework.Assert; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.util.JpsPathUtil; +import org.junit.Assert; import javax.swing.*; import java.io.File; @@ -109,7 +125,8 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { throw new RuntimeException(e); } new WriteAction() { - protected void run(final Result result) { + @Override + protected void run(@NotNull final Result result) { VirtualFile virtualDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(target); assertNotNull(target.getAbsolutePath() + " not found", virtualDir); virtualDir.refresh(false, true); @@ -124,7 +141,7 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { protected Module addModule(final String moduleName, final @Nullable VirtualFile sourceRoot, final @Nullable VirtualFile testRoot) { return new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final Module module = createModule(moduleName); if (sourceRoot != null) { PsiTestUtil.addSourceContentToRoots(module, sourceRoot, false); @@ -285,15 +302,6 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { return result.get(); } - private Set getRelativePaths(String[] paths) { - final Set set = new THashSet(); - final String basePath = myProject.getBaseDir().getPath(); - for (String path : paths) { - set.add(StringUtil.trimStart(StringUtil.trimStart(FileUtil.toSystemIndependentName(path), basePath), "/")); - } - return set; - } - protected void changeFile(VirtualFile file) { changeFile(file, null); } @@ -313,7 +321,7 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { protected void deleteFile(final VirtualFile file) { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { try { file.delete(this); } @@ -347,7 +355,7 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { PlatformTestCase.myFilesToDelete.add(moduleFile); return new WriteAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { Module module = ModuleManager.getInstance(myProject) .newModule(FileUtil.toSystemIndependentName(moduleFile.getAbsolutePath()), getModuleType().getId()); module.getModuleFile(); @@ -408,7 +416,7 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { } } - protected class CompilationLog { + protected static class CompilationLog { private final Set myGeneratedPaths; private final boolean myExternalBuildUpToDate; private final CompilerMessage[] myErrors; @@ -438,7 +446,7 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { return myWarnings; } - private void assertSet(String name, Set actual, String[] expected) { + private static void assertSet(String name, Set actual, String[] expected) { for (String path : expected) { if (!actual.remove(path)) { Assert.fail("'" + path + "' is not " + name + ". " + name + ": " + new HashSet(actual)); diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestCase.java index 9c60d0c6f446..bd921428ef79 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestCase.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestCase.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.compiler.artifacts; import com.intellij.facet.Facet; @@ -58,7 +73,7 @@ public abstract class ArtifactsTestCase extends IdeaTestCase { protected static void commitModel(final ModifiableArtifactModel model) { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { model.commit(); } }.execute(); @@ -90,7 +105,7 @@ public abstract class ArtifactsTestCase extends IdeaTestCase { public static void renameFile(final VirtualFile file, final String newName) { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { try { file.rename(IdeaTestCase.class, newName); } @@ -104,7 +119,7 @@ public abstract class ArtifactsTestCase extends IdeaTestCase { protected Module addModule(final String moduleName, final @Nullable VirtualFile sourceRoot) { return new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final Module module = createModule(moduleName); if (sourceRoot != null) { PsiTestUtil.addSourceContentToRoots(module, sourceRoot); diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestUtil.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestUtil.java index 3eb811f2ef4c..9b2b15430a69 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestUtil.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestUtil.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.compiler.artifacts; import com.intellij.openapi.application.Result; @@ -16,6 +31,7 @@ import com.intellij.packaging.elements.PackagingElementResolvingContext; import com.intellij.packaging.impl.elements.ArchivePackagingElement; import com.intellij.packaging.impl.elements.DirectoryPackagingElement; import com.intellij.packaging.impl.elements.ManifestFileUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -86,7 +102,7 @@ public class ArtifactsTestUtil { public static void setOutput(final Project project, final String artifactName, final String outputPath) { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final ModifiableArtifactModel model = ArtifactManager.getInstance(project).createModifiableModel(); model.getOrCreateModifiableArtifact(findArtifact(project, artifactName)).setOutputPath(outputPath); model.commit(); @@ -97,7 +113,7 @@ public class ArtifactsTestUtil { public static void addArtifactToLayout(final Project project, final Artifact parent, final Artifact toAdd) { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final ModifiableArtifactModel model = ArtifactManager.getInstance(project).createModifiableModel(); final PackagingElement artifactElement = PackagingElementFactory.getInstance().createArtifactElement(toAdd, project); model.getOrCreateModifiableArtifact(parent).getRootElement().addOrFindChild(artifactElement); diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/PackagingElementsTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/PackagingElementsTestCase.java index a6a667a14bf0..52c3711a0f2f 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/PackagingElementsTestCase.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/PackagingElementsTestCase.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.compiler.artifacts; import com.intellij.openapi.application.PathManager; @@ -17,6 +32,7 @@ import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.elements.PackagingElement; import com.intellij.testFramework.VfsTestUtil; import com.intellij.util.PathUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -105,7 +121,7 @@ public abstract class PackagingElementsTestCase extends ArtifactsTestCase { final VirtualFile[] jars) { return new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final Library library = LibraryTablesRegistrar.getInstance().getLibraryTable(project).createLibrary(name); final Library.ModifiableModel libraryModel = library.getModifiableModel(); for (VirtualFile jar : jars) { diff --git a/java/debugger/impl/src/com/intellij/debugger/codeinsight/JavaWithRuntimeCastSurrounder.java b/java/debugger/impl/src/com/intellij/debugger/codeinsight/JavaWithRuntimeCastSurrounder.java index 346ff0b9d30a..08cced8c51c4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/codeinsight/JavaWithRuntimeCastSurrounder.java +++ b/java/debugger/impl/src/com/intellij/debugger/codeinsight/JavaWithRuntimeCastSurrounder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -34,6 +34,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -89,7 +90,7 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder { DebuggerInvocationUtil.invokeLater(project, new Runnable() { public void run() { new WriteCommandAction(project, CodeInsightBundle.message("command.name.surround.with.runtime.cast")) { - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { try { PsiElementFactory factory = JavaPsiFacade.getInstance(myElement.getProject()).getElementFactory(); PsiParenthesizedExpression parenth = diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java index cab3811be687..5523463d8359 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -1080,15 +1080,17 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { final boolean performCastToWrapperClass = shouldPerformBoxingConversion && !castingToPrimitive; - String castTypeName = castType.getCanonicalText(); - if (performCastToWrapperClass) { - final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(castType); - if (unboxedType != null) { - castTypeName = unboxedType.getCanonicalText(); + if (!(PsiUtil.resolveClassInClassTypeOnly(castType) instanceof PsiTypeParameter)) { + String castTypeName = castType.getCanonicalText(); + if (performCastToWrapperClass) { + final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(castType); + if (unboxedType != null) { + castTypeName = unboxedType.getCanonicalText(); + } } - } - myResult = new TypeCastEvaluator(operandEvaluator, castTypeName, castingToPrimitive); + myResult = new TypeCastEvaluator(operandEvaluator, castTypeName, castingToPrimitive); + } if (performCastToWrapperClass) { myResult = new BoxingEvaluator(myResult); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java index c6a67510c903..7cde93d52f96 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -26,5 +26,5 @@ import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperti */ public interface JavaBreakpointType

{ @NotNull - Breakpoint createJavaBreakpoint(Project project, XBreakpoint

breakpoint); + Breakpoint

createJavaBreakpoint(Project project, XBreakpoint

breakpoint); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java index 638e6a018c96..496be518f1e5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -140,7 +140,7 @@ public class JavaExceptionBreakpointType extends JavaBreakpointTypeBase breakpoint) { + public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) { if (!XDebuggerManager.getInstance(project).getBreakpointManager().isDefaultBreakpoint(breakpoint)) { return new ExceptionBreakpoint(project, breakpoint); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java index f534e8883a63..af6ac86965dd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java @@ -41,7 +41,9 @@ import javax.swing.*; * @author Eugene Zhuravlev * Date: Apr 26, 2005 */ -public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase implements JavaBreakpointType { +public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase + implements JavaBreakpointType { + public JavaFieldBreakpointType() { super("java-field", DebuggerBundle.message("field.watchpoints.tab.title")); } @@ -121,7 +123,7 @@ public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase addBreakpoint(final Project project, JComponent parentComponent) { - final Ref result = Ref.create(null); + final Ref> result = Ref.create(null); AddFieldBreakpointDialog dialog = new AddFieldBreakpointDialog(project) { protected boolean validateData() { final String className = getClassName(); @@ -178,7 +180,7 @@ public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase createJavaBreakpoint(Project project, XBreakpoint breakpoint) { return new FieldBreakpoint(project, breakpoint); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java index 8f8d0a74bc79..03eadd84385e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java @@ -44,7 +44,8 @@ import java.util.List; * Base class for java line-connected exceptions (line, method, field) * @author egor */ -public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase implements JavaBreakpointType { +public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase + implements JavaBreakpointType { public JavaLineBreakpointType() { super("java-line", DebuggerBundle.message("line.breakpoints.tab.title")); } @@ -78,8 +79,8 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase createJavaBreakpoint(Project project, XBreakpoint breakpoint) { + return new LineBreakpoint(project, breakpoint); } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java index a5358b25c624..b8b56e9b57b3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java @@ -34,7 +34,8 @@ import javax.swing.*; * @author Eugene Zhuravlev * Date: Apr 26, 2005 */ -public class JavaMethodBreakpointType extends JavaLineBreakpointTypeBase implements JavaBreakpointType { +public class JavaMethodBreakpointType extends JavaLineBreakpointTypeBase + implements JavaBreakpointType { public JavaMethodBreakpointType() { super("java-method", DebuggerBundle.message("method.breakpoints.tab.title")); } @@ -124,7 +125,7 @@ public class JavaMethodBreakpointType extends JavaLineBreakpointTypeBase createJavaBreakpoint(Project project, XBreakpoint breakpoint) { return new MethodBreakpoint(project, breakpoint); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java index 9adf87f93c7b..2c824b14fc6e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -33,7 +33,9 @@ import javax.swing.*; /** * @author Egor */ -public class JavaWildcardMethodBreakpointType extends JavaBreakpointTypeBase implements JavaBreakpointType { +public class JavaWildcardMethodBreakpointType extends JavaBreakpointTypeBase + implements JavaBreakpointType { + public JavaWildcardMethodBreakpointType() { super("java-wildcard-method", DebuggerBundle.message("method.breakpoints.tab.title")); } @@ -114,7 +116,7 @@ public class JavaWildcardMethodBreakpointType extends JavaBreakpointTypeBase createJavaBreakpoint(Project project, XBreakpoint breakpoint) { return new WildcardMethodBreakpoint(project, breakpoint); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java index 1d4e2d9d9d1b..8a8f8d71118f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java @@ -62,6 +62,7 @@ import com.sun.jdi.request.BreakpointRequest; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties; import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; @@ -71,7 +72,7 @@ import java.util.Collection; import java.util.List; import java.util.regex.Pattern; -public class LineBreakpoint extends BreakpointWithHighlighter { +public class LineBreakpoint

extends BreakpointWithHighlighter

{ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.LineBreakpoint"); public static final @NonNls Key CATEGORY = BreakpointCategory.lookup("line_breakpoints"); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java index e30d0f866fbe..bb93a44d9e83 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/RunToCursorBreakpoint.java @@ -34,7 +34,7 @@ import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperti * @author Eugene Zhuravlev * Date: Sep 13, 2006 */ -public class RunToCursorBreakpoint extends LineBreakpoint { +public class RunToCursorBreakpoint

extends LineBreakpoint

{ private final boolean myRestoreBreakpoints; @NotNull protected final SourcePosition myCustomPosition; @@ -116,7 +116,7 @@ public class RunToCursorBreakpoint extends LineBreakpoint { } @Override - protected JavaBreakpointProperties getProperties() { + protected P getProperties() { return null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java index ad56fc217ee9..87665797eff8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StepIntoBreakpoint.java @@ -29,6 +29,7 @@ import com.sun.jdi.*; import com.sun.jdi.request.BreakpointRequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; import java.util.*; @@ -36,7 +37,7 @@ import java.util.*; * @author Eugene Zhuravlev * Date: Sep 13, 2006 */ -public class StepIntoBreakpoint extends RunToCursorBreakpoint { +public class StepIntoBreakpoint

extends RunToCursorBreakpoint

{ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.StepIntoBreakpoint"); @NotNull private final BreakpointStepMethodFilter myFilter; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java index 1c68f83dcfdc..e23629749a25 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java @@ -61,7 +61,7 @@ public class WildcardMethodBreakpoint extends Breakpoint breakpoint) { super(project, breakpoint); } @@ -69,7 +69,7 @@ public class WildcardMethodBreakpoint extends Breakpoint breakpoint) { super(project, breakpoint); setClassPattern(classPattern); setMethodName(methodName); @@ -253,7 +253,10 @@ public class WildcardMethodBreakpoint extends Breakpoint xBreakpoint) { return new WildcardMethodBreakpoint(project, classPattern, methodName, xBreakpoint); } diff --git a/java/execution/impl/execution-impl.iml b/java/execution/impl/execution-impl.iml index bf85ee694ec4..ed11ab8cf3e1 100644 --- a/java/execution/impl/execution-impl.iml +++ b/java/execution/impl/execution-impl.iml @@ -23,7 +23,9 @@ - + + + diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfiguration.java b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfiguration.java index 3548ffbf46ad..c7412ed4fbfa 100644 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfiguration.java +++ b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfiguration.java @@ -219,4 +219,7 @@ public abstract class TestDiscoveryConfiguration extends JavaTestConfigurationBa public String getChangeList() { return myChangeList; } + + @NotNull + public abstract String getFrameworkPrefix(); } diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfigurationProducer.java b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfigurationProducer.java index f5bd39cf5434..7437395ae729 100644 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfigurationProducer.java +++ b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryConfigurationProducer.java @@ -22,6 +22,7 @@ import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.configurations.ConfigurationType; import com.intellij.execution.junit.JavaRunConfigurationProducerBase; import com.intellij.execution.testframework.TestSearchScope; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.registry.Registry; @@ -31,6 +32,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testIntegration.TestFramework; +import com.intellij.util.containers.ContainerUtil; import java.io.IOException; import java.util.Collection; @@ -41,7 +43,7 @@ public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigur } @Override - protected boolean setupConfigurationFromContext(TestDiscoveryConfiguration configuration, + protected boolean setupConfigurationFromContext(final TestDiscoveryConfiguration configuration, ConfigurationContext configurationContext, Ref ref) { if (!Registry.is("testDiscovery.enabled")) { @@ -56,7 +58,13 @@ public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigur try { final Collection testsByMethodName = TestDiscoveryIndex .getInstance(configuration.getProject()).getTestsByMethodName(position.first, position.second); - if (testsByMethodName == null || testsByMethodName.isEmpty()) return false; + if (testsByMethodName == null || ContainerUtil.filter(testsByMethodName, new Condition() { + @Override + public boolean value(String s) { + return s.startsWith(configuration.getFrameworkPrefix()); + } + }).isEmpty()) return false; + } catch (IOException e) { return false; diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java index 59b854d76b4f..2c5cedca5a94 100644 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java +++ b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java @@ -22,6 +22,7 @@ import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunnerSettings; import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.testframework.JavaTestLocator; import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsAdapter; import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsListener; import com.intellij.execution.testframework.sm.runner.SMTestProxy; @@ -34,7 +35,9 @@ import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Alarm; +import com.intellij.util.ArrayUtil; import com.intellij.util.PathUtil; import com.intellij.util.messages.MessageBusConnection; import org.jdom.Element; @@ -45,6 +48,8 @@ import org.jetbrains.testme.instrumentation.ProjectData; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class TestDiscoveryExtension extends RunConfigurationExtension { private static final Logger LOG = Logger.getInstance("#" + TestDiscoveryExtension.class.getName()); @@ -73,16 +78,25 @@ public class TestDiscoveryExtension extends RunConfigurationExtension { final Alarm processTracesAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, null); final MessageBusConnection connection = configuration.getProject().getMessageBus().connect(); connection.subscribe(SMTRunnerEventsListener.TEST_STATUS, new SMTRunnerEventsAdapter() { + private List myCompletedMethodNames = new ArrayList(); @Override public void onTestFinished(@NotNull SMTestProxy test) { final SMTestProxy.SMRootTestProxy root = test.getRoot(); - if ((root == null || root.getHandler() == handler) && processTracesAlarm.getActiveRequestCount() == 0) { - /*processTracesAlarm.addRequest(new Runnable() { - @Override - public void run() { - processAvailableTraces(configuration); + if ((root == null || root.getHandler() == handler)) { + final String fullTestName = test.getLocationUrl(); + if (fullTestName != null && fullTestName.startsWith(JavaTestLocator.TEST_PROTOCOL)) { + myCompletedMethodNames.add(fullTestName.substring(JavaTestLocator.TEST_PROTOCOL.length() + 3)); + if (myCompletedMethodNames.size() > 50) { + final String[] fullTestNames = ArrayUtil.toStringArray(myCompletedMethodNames); + myCompletedMethodNames.clear(); + processTracesAlarm.addRequest(new Runnable() { + @Override + public void run() { + processAvailableTraces(configuration, fullTestNames); + } + }, 100); } - }, 200);*/ + } } } @@ -144,6 +158,7 @@ public class TestDiscoveryExtension extends RunConfigurationExtension { } private static final Object ourTracesLock = new Object(); + private static void processAvailableTraces(RunConfigurationBase configuration) { final String tracesDirectory = getTracesDirectory(configuration); final TestDiscoveryIndex coverageIndex = TestDiscoveryIndex.getInstance(configuration.getProject()); @@ -167,4 +182,28 @@ public class TestDiscoveryExtension extends RunConfigurationExtension { } } } + + private static void processAvailableTraces(RunConfigurationBase configuration, String[] fullTestNames) { + final String tracesDirectory = getTracesDirectory(configuration); + final TestDiscoveryIndex coverageIndex = TestDiscoveryIndex.getInstance(configuration.getProject()); + synchronized (ourTracesLock) { + for (String fullTestName : fullTestNames) { + final String className = StringUtil.getPackageName(fullTestName); + final String methodName = StringUtil.getShortName(fullTestName); + if (!StringUtil.isEmptyOrSpaces(className) && !StringUtil.isEmptyOrSpaces(methodName)) { + final File testMethodTrace = new File(tracesDirectory, className + "-" + methodName + ".tr"); + if (testMethodTrace.exists()) { + try { + coverageIndex.updateFromTestTrace(testMethodTrace); + FileUtil.delete(testMethodTrace); + } + catch (IOException e) { + LOG.error("Can not load " + testMethodTrace, e); + } + } + } + } + } + + } } \ No newline at end of file diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoverySearchHelper.java b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoverySearchHelper.java index d852e5b20d57..fddb01777669 100644 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoverySearchHelper.java +++ b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoverySearchHelper.java @@ -18,6 +18,7 @@ package com.intellij.execution.testDiscovery; import com.intellij.codeInsight.actions.FormatChangedTextUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vcs.changes.Change; @@ -27,6 +28,7 @@ import com.intellij.openapi.vcs.changes.LocalChangeList; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.diff.FilesTooBigForDiffException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,17 +37,14 @@ import java.io.IOException; import java.util.*; public class TestDiscoverySearchHelper { - public static Set search(final Project project, final Pair position, final String changeList) { + public static Set search(final Project project, + final Pair position, + final String changeList, + final String frameworkPrefix) { final Set patterns = new LinkedHashSet(); if (position != null) { try { - final Collection testsByMethodName = TestDiscoveryIndex - .getInstance(project).getTestsByMethodName(position.first, position.second); - if (testsByMethodName != null) { - for (String pattern : testsByMethodName) { - patterns.add(pattern.replace('-', ',')); - } - } + collectPatterns(project, patterns, position.first, position.second, frameworkPrefix); } catch (IOException ignore) { } @@ -73,7 +72,7 @@ public class TestDiscoverySearchHelper { methods.add(containingMethod); } for (PsiMethod changedMethod : methods) { - final LinkedHashSet detectedPatterns = collectPatterns(changedMethod); + final LinkedHashSet detectedPatterns = collectPatterns(changedMethod, frameworkPrefix); if (detectedPatterns != null) { patterns.addAll(detectedPatterns); } @@ -90,6 +89,25 @@ public class TestDiscoverySearchHelper { return patterns; } + private static void collectPatterns(final Project project, + final Set patterns, + final String classFQName, + final String methodName, + final String frameworkId) throws IOException { + final Collection testsByMethodName = TestDiscoveryIndex + .getInstance(project).getTestsByMethodName(classFQName, methodName); + if (testsByMethodName != null) { + for (String pattern : ContainerUtil.filter(testsByMethodName, new Condition() { + @Override + public boolean value(String s) { + return s.startsWith(frameworkId); + } + })) { + patterns.add(pattern.substring(frameworkId.length()).replace('-', ',')); + } + } + } + @NotNull private static List getAffectedFiles(String changeListName, Project project) { final ChangeListManager changeListManager = ChangeListManager.getInstance(project); @@ -115,20 +133,14 @@ public class TestDiscoverySearchHelper { } @Nullable - private static LinkedHashSet collectPatterns(PsiMethod psiMethod) { + private static LinkedHashSet collectPatterns(PsiMethod psiMethod, String frameworkId) { LinkedHashSet patterns = new LinkedHashSet(); final PsiClass containingClass = psiMethod.getContainingClass(); if (containingClass != null) { final String qualifiedName = containingClass.getQualifiedName(); if (qualifiedName != null) { try { - final Collection testsByMethodName - = TestDiscoveryIndex.getInstance(containingClass.getProject()).getTestsByMethodName(qualifiedName, psiMethod.getName()); - if (testsByMethodName != null) { - for (String pattern : testsByMethodName) { - patterns.add(pattern.replace('-', ',')); - } - } + collectPatterns(psiMethod.getProject(), patterns, qualifiedName, psiMethod.getName(), frameworkId); } catch (IOException e) { return null; diff --git a/java/execution/impl/src/com/intellij/execution/ui/ClassBrowser.java b/java/execution/impl/src/com/intellij/execution/ui/ClassBrowser.java index 522456e711bf..d12493b78e79 100644 --- a/java/execution/impl/src/com/intellij/execution/ui/ClassBrowser.java +++ b/java/execution/impl/src/com/intellij/execution/ui/ClassBrowser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.intellij.execution.ui; import com.intellij.execution.ExecutionBundle; -import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.configuration.BrowseModuleValueActionListener; import com.intellij.execution.configurations.ConfigurationUtil; import com.intellij.ide.util.ClassFilter; @@ -33,6 +32,7 @@ import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiMethod; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiMethodUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class ClassBrowser extends BrowseModuleValueActionListener { @@ -96,7 +96,7 @@ public abstract class ClassBrowser extends BrowseModuleValueActionListener { private PsiMethod findMainMethod(final PsiClass aClass) { return new ReadAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { result.setResult(PsiMethodUtil.findMainMethod(aClass)); } }.execute().getResultObject(); diff --git a/java/execution/impl/testDiscovery/build.xml b/java/execution/impl/testDiscovery/build.xml new file mode 100644 index 000000000000..e86f1ceb6043 --- /dev/null +++ b/java/execution/impl/testDiscovery/build.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/CoveragePremain.java b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/CoveragePremain.java new file mode 100755 index 000000000000..3cce29a2038d --- /dev/null +++ b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/CoveragePremain.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.testme.instrumentation; + + +import java.io.File; +import java.lang.instrument.Instrumentation; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +public class CoveragePremain { + + public static void premain(String argsString, Instrumentation instrumentation) throws Exception { + final File lib = new File(getArchivePath()).getParentFile(); + final URL[] urls = new URL[3]; + urls[0] = fileToURL(new File(lib, "testDiscoveryInstrumenter.jar")); + urls[1] = fileToURL(new File(lib, "asm-all.jar")); + urls[2] = fileToURL(new File(lib, "trove4j.jar")); + + final Class instrumentator = Class.forName("org.jetbrains.testme.instrumentation.TestDiscoveryInstrumentator", true, new URLClassLoader(urls) { + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + synchronized (this) { + Class result = findLoadedClass(name); + if (result == null) { + try { + result = findClass(name); + } catch (ClassNotFoundException e) { + //ignore, will try to find class in parent + } + } + + if (result != null && resolve) { + resolveClass(result); + } + + if (result != null) { + return result; + } + } + + return getParent().loadClass(name); + } + }); + final Method premainMethod = instrumentator.getDeclaredMethod("premain", new Class[]{String.class, Instrumentation.class}); + premainMethod.invoke(null, new Object[] {argsString, instrumentation}); + } + + private static URL fileToURL(final File file) throws MalformedURLException { + return file.getAbsoluteFile().toURI().toURL(); + } + + private static String getArchivePath() { + final String className = CoveragePremain.class.getName().replace('.', '/') + ".class"; + URL resourceURL = CoveragePremain.class.getResource("/" + className); + if (resourceURL == null) { + resourceURL = ClassLoader.getSystemResource(className); + } + return URLsUtil.extractRoot(resourceURL, "/" + className); + } +} \ No newline at end of file diff --git a/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/InstrumentedMethodsFilter.java b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/InstrumentedMethodsFilter.java new file mode 100644 index 000000000000..5786c953542a --- /dev/null +++ b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/InstrumentedMethodsFilter.java @@ -0,0 +1,37 @@ +package org.jetbrains.testme.instrumentation; + +import org.jetbrains.org.objectweb.asm.Opcodes; + +public class InstrumentedMethodsFilter { + private final String myClassName; + private boolean myEnum; + + public InstrumentedMethodsFilter(String className) { + myClassName = className; + } + + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + myEnum = (access & Opcodes.ACC_ENUM) != 0; + } + + public boolean shouldVisitMethod(final int access, + final String name, + final String desc, + final String signature, + final String[] exceptions) { + if ((access & Opcodes.ACC_BRIDGE) != 0) return false; //try to skip bridge methods + if ((access & Opcodes.ACC_ABSTRACT) != 0) return false; //skip abstracts; do not include interfaces without non-abstract methods in result + if ("".equals(name) || "".equals(name)) return false; //skip (static/instance) initializers + + if (myEnum && isDefaultEnumMethod(name, desc, signature, myClassName)) { + return false; + } + return true; + } + + private static boolean isDefaultEnumMethod(String name, String desc, String signature, String className) { + return name.equals("values") && desc.equals("()[L" + className + ";") || + name.equals("valueOf") && desc.equals("(Ljava/lang/String;)L" + className + ";") || + name.equals("") && signature != null && signature.equals("()V"); + } +} diff --git a/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/Instrumenter.java b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/Instrumenter.java new file mode 100755 index 000000000000..76f9c673c9e2 --- /dev/null +++ b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/Instrumenter.java @@ -0,0 +1,148 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.testme.instrumentation; + +import org.jetbrains.org.objectweb.asm.ClassVisitor; +import org.jetbrains.org.objectweb.asm.Label; +import org.jetbrains.org.objectweb.asm.MethodVisitor; +import org.jetbrains.org.objectweb.asm.Opcodes; + +public class Instrumenter extends ClassVisitor { + protected final ClassVisitor myClassVisitor; + private final String myClassName; + private final String myInternalClassName; + private final InstrumentedMethodsFilter myMethodFilter; + private final String[] myMethodNames; + private int myCurrentMethodCount; + private boolean myVisitedStaticBlock; + + private static final String METHODS_VISITED = "__$methodsVisited$__"; + private static final String METHODS_VISITED_CLASS = "[Z"; + + public Instrumenter(ClassVisitor classVisitor, String className, String[] methodNames) { + super(Opcodes.ASM5, classVisitor); + myClassVisitor = classVisitor; + myMethodFilter = new InstrumentedMethodsFilter(className); + myClassName = className.replace('$', '.'); // for inner classes + myInternalClassName = className.replace('.', '/'); + myMethodNames = methodNames; + } + + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + myMethodFilter.visit(version, access, name, signature, superName, interfaces); + super.visit(version, access, name, signature, superName, interfaces); + } + + public MethodVisitor visitMethod(final int access, + final String name, + final String desc, + final String signature, + final String[] exceptions) { + final MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); + if (mv == null) return mv; + if ("".equals(name)) { + myVisitedStaticBlock = true; + return new StaticBlockMethodVisitor(mv); + } + + if (!myMethodFilter.shouldVisitMethod(access, name, desc, signature, exceptions)) return mv; + + assert myCurrentMethodCount < myMethodNames.length; + + return new MethodVisitor(Opcodes.ASM5, mv) { + final int myMethodId = myCurrentMethodCount++; + + public void visitCode() { + visitFieldInsn(Opcodes.GETSTATIC, myInternalClassName, METHODS_VISITED, METHODS_VISITED_CLASS); + pushInstruction(this, myMethodId); + visitInsn(Opcodes.ICONST_1); + visitInsn(Opcodes.BASTORE); + + super.visitCode(); + } + }; + } + + @Override + public void visitEnd() { + visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, METHODS_VISITED, + METHODS_VISITED_CLASS, null, null); + + if (!myVisitedStaticBlock) { + MethodVisitor mv = super.visitMethod(Opcodes.ACC_STATIC, "", "()V", null, null); + mv = new StaticBlockMethodVisitor(mv); + mv.visitCode(); + mv.visitInsn(Opcodes.RETURN); + mv.visitMaxs(myMethodNames.length + 2, 1); + mv.visitEnd(); + } + super.visitEnd(); + } + + private class StaticBlockMethodVisitor extends MethodVisitor { + public StaticBlockMethodVisitor(MethodVisitor mv) { + super(Opcodes.ASM5, mv); + } + + public void visitCode() { + super.visitCode(); + + pushInstruction(this, myMethodNames.length); + visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_BOOLEAN); + visitFieldInsn(Opcodes.PUTSTATIC, myInternalClassName, METHODS_VISITED, METHODS_VISITED_CLASS); + + pushInstruction(this, myMethodNames.length); + + visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String"); + + for(int i = 0; i < myMethodNames.length; ++i) { + visitInsn(Opcodes.DUP); + pushInstruction(this, i); + visitLdcInsn(myMethodNames[i]); + visitInsn(Opcodes.AASTORE); + } + + visitVarInsn(Opcodes.ASTORE, 0); + + Label startLabel = new Label(); + visitLabel(startLabel); + + visitLdcInsn(myClassName); + visitFieldInsn(Opcodes.GETSTATIC, myInternalClassName, METHODS_VISITED, METHODS_VISITED_CLASS); + visitVarInsn(Opcodes.ALOAD, 0); + visitMethodInsn(Opcodes.INVOKESTATIC, ProjectData.PROJECT_DATA_OWNER, "trace", "(Ljava/lang/String;[Z[Ljava/lang/String;)V", false); + + Label endLabel = new Label(); + visitLabel(endLabel); + + visitLocalVariable("methodNames", "[Ljava/lang/String;", null, startLabel, endLabel, 0); + // no return here + } + + public void visitMaxs(int maxStack, int maxLocals) { + final int ourMaxStack = myMethodNames.length + 2; + final int ourMaxLocals = 1; + + super.visitMaxs(Math.max(ourMaxStack, maxStack), Math.max(ourMaxLocals, maxLocals)); + } + } + + private static void pushInstruction(MethodVisitor mv, int operand) { + if (operand < Byte.MAX_VALUE) mv.visitIntInsn(Opcodes.BIPUSH, operand); + else mv.visitIntInsn(Opcodes.SIPUSH, operand); + } +} \ No newline at end of file diff --git a/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/ProjectData.java b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/ProjectData.java new file mode 100644 index 000000000000..31336bd6e1fc --- /dev/null +++ b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/ProjectData.java @@ -0,0 +1,158 @@ +package org.jetbrains.testme.instrumentation; + +import java.io.*; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; + +public class ProjectData { + public static final String PROJECT_DATA_OWNER = "org/jetbrains/testme/instrumentation/ProjectData"; + public static final String TRACE_DIR = "org.jetbrains.testme.instrumentation.trace.dir"; + + protected static final ProjectData ourData = new ProjectData(); + + private String myTraceDir = System.getProperty(TRACE_DIR, ""); + + public void setTraceDir(String traceDir) { + myTraceDir = traceDir; + } + + private ConcurrentMap> myTrace; + private final ConcurrentMap myTrace2 = new ConcurrentHashMap(); + private final ConcurrentMap myTrace3 = new ConcurrentHashMap(); + + public static ProjectData getProjectData() { + return ourData; + } + + public static void trace(String className, String methodSignature) { + ourData.traceLines(className, methodSignature); + } + + // called from instrumented code during class's static init + public static void trace(String className, boolean[] methodFlags, String[] methodNames) { + ourData.traceLines(className, methodFlags, methodNames); + } + + public void traceLines(String className, String methodSignature) { + if (myTrace != null) { + Set methods = myTrace.get(className); + if (methods == null) { + methods = new HashSet(); + Set previousMethods = myTrace.putIfAbsent(className, methods); + if (previousMethods != null) methods = previousMethods; + } + synchronized (methods) { + methods.add(methodSignature); + } + } + } + + public synchronized void traceLines(String className, boolean[] methodFlags, String[] methodNames) { + //System.out.println("Registering " + className); + assert methodFlags.length == methodNames.length; + myTrace2.put(className, methodFlags); + myTrace3.put(className, methodNames); + } + + private static volatile boolean traceDirDumped; + + public synchronized void testEnded(final String name) { + //if (myTrace == null) return; + if (!traceDirDumped) { + ClassLoader classLoader = TestDiscoveryInstrumentator.class.getClassLoader(); + System.out.println(ourData + "; cl: " + classLoader+ "," + classLoader.getParent()); + System.out.println("Trace dir:" + myTraceDir); + traceDirDumped = true; + } + new File(myTraceDir).mkdirs(); + final File traceFile = new File(myTraceDir, name + ".tr"); + try { + if (!traceFile.exists()) { + traceFile.createNewFile(); + } + DataOutputStream os = null; + Deflater def = new Deflater(1); + try { + os = new DataOutputStream(new DeflaterOutputStream(new BufferedOutputStream(new FileOutputStream(traceFile)), def)); + + //saveOldTrace(os); + + Map classToUsedMethods = new HashMap(); + for(Map.Entry e: myTrace2.entrySet()) { + boolean[] used = e.getValue(); + int usedMethodsCount = 0; + + for (boolean anUsed : used) { + if (anUsed) ++usedMethodsCount; + } + + if (usedMethodsCount > 0) { + classToUsedMethods.put(e.getKey(), usedMethodsCount); + } + } + + os.writeInt(classToUsedMethods.size()); + for(Map.Entry e: myTrace2.entrySet()) { + final boolean[] used = e.getValue(); + final String className = e.getKey(); + + Integer integer = classToUsedMethods.get(className); + if (integer == null) continue;; + + int usedMethodsCount = integer; + + os.writeUTF(className); + os.writeInt(usedMethodsCount); + + String[] methodNames = myTrace3.get(className); + for (int i = 0, len = used.length; i < len; ++i) { + // we check usedMethodCount here since used was observed to change // ? + if (used[i] && usedMethodsCount-- > 0) os.writeUTF(methodNames[i]); + } + } + } + finally { + if (os != null) { + os.close(); + } + def.end(); + } + } + catch (IOException e) { + e.printStackTrace(); + } + finally { + myTrace = null; + } + } + + private void saveOldTrace(DataOutputStream os) throws IOException { + os.writeInt(myTrace.size()); + for (Iterator it = myTrace.keySet().iterator(); it.hasNext();) { + final String classData = it.next(); + os.writeUTF(classData); + final Set methods = myTrace.get(classData); + os.writeInt(methods.size()); + for (Iterator iterator = methods.iterator(); iterator.hasNext(); ) { + os.writeUTF(iterator.next()); + } + } + } + + public synchronized void testStarted(final String name) { + //clearOldTrace(); + for(Map.Entry e: myTrace2.entrySet()) { + boolean[] used = e.getValue(); + for(int i = 0, len = used.length; i < len; ++i) { + if(used[i]) used[i] = false; + } + } + } + + private void clearOldTrace() { + myTrace = new ConcurrentHashMap>(); + } +} diff --git a/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/TestDiscoveryInstrumentator.java b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/TestDiscoveryInstrumentator.java new file mode 100755 index 000000000000..71d91feb7743 --- /dev/null +++ b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/TestDiscoveryInstrumentator.java @@ -0,0 +1,265 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.testme.instrumentation; + +import org.jetbrains.org.objectweb.asm.*; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + + +public class TestDiscoveryInstrumentator { + + public static void premain(String argsString, Instrumentation instrumentation) throws Exception { + instrumentation.addTransformer(new ClassFileTransformer() { + private boolean computeFrames = computeFrames(); + + public byte[] transform(ClassLoader loader, + String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer) throws IllegalClassFormatException { + try { + if (className == null) { + return null; + } + if (loader == null) { + // skip classes loaded by system classloader + //System.out.println("Skipping " + className); + return null; + } + if (className.endsWith(".class")) { + className = className.substring(0, className.length() - 6); + } + className = className.replace('\\', '.').replace('/', '.'); + + if (className.startsWith("com.intellij.rt.") + || className.startsWith("com.intellij.util.lang.") + || className.startsWith("com.intellij.util.containers.") + || className.startsWith("com.intellij.openapi.util.text.") + || className.startsWith("com.intellij.openapi.util.io.") + || className.startsWith("java.") + || className.startsWith("sun.") + || className.startsWith("gnu.trove.") + || className.startsWith("org.jetbrains.org.objectweb.asm.") + || className.startsWith("org.apache.oro.text.regex.") + || className.startsWith("org.jetbrains.testme.") + || className.startsWith("org.junit.") + || className.startsWith("com.sun.") + || className.startsWith("junit.") + || className.startsWith("jdk.internal.") + || className.startsWith("com.intellij.junit3.") + || className.startsWith("com.intellij.junit4.")) { + return null; + } + //System.out.println(className); + return instrument(classfileBuffer, className, loader, computeFrames); + } catch (Throwable e) { + e.printStackTrace(); + } + return null; + } + + private boolean computeFrames() { + return System.getProperty("idea.coverage.no.frames") == null; + } + }); + } + + private final static AtomicInteger myInstrumentedClasses = new AtomicInteger(); + private final static AtomicInteger myInstrumentedMethods = new AtomicInteger(); + private final static AtomicLong myInstrumentedClassesTime = new AtomicLong(); + + private static byte[] instrument(final byte[] classfileBuffer, final String className, ClassLoader loader, boolean computeFrames) { + long started = System.nanoTime(); + final ClassReader cr = new ClassReader(classfileBuffer); + final ClassWriter cw; + if (computeFrames && false) { + final int version = getClassFileVersion(cr); + cw = getClassWriter(version >= Opcodes.V1_6 && version != Opcodes.V1_1 ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS, loader); + } else { + cw = getClassWriter(ClassWriter.COMPUTE_MAXS, loader); + } + + final List instrumentedMethods = new ArrayList(); + + final ClassVisitor instrumentedMethodCounter = new ClassVisitor(Opcodes.ASM5) { + final InstrumentedMethodsFilter methodsFilter = new InstrumentedMethodsFilter(className); + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + methodsFilter.visit(version, access, name, signature, superName, interfaces); + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (methodsFilter.shouldVisitMethod(access, name, desc, signature, exceptions)) { + instrumentedMethods.add(name); + } + return super.visitMethod(access, name, desc, signature, exceptions); + } + }; + + cr.accept(instrumentedMethodCounter, 0); + + // todo there are duplicates in array of instrumented methods + final ClassVisitor cv = new Instrumenter(cw, className, instrumentedMethods.toArray(new String[instrumentedMethods.size()])); + cr.accept(cv, 0); + byte[] bytes = cw.toByteArray(); + + long time = myInstrumentedClassesTime.addAndGet(System.nanoTime() - started); + int classes = myInstrumentedClasses.incrementAndGet(); + int methods = myInstrumentedMethods.addAndGet(instrumentedMethods.size()); + if (classes % 1000 == 0) { + System.out.println("Done instrumenting " + classes + ", methods:" + methods + " for " + (time / 1000000)); + } + + if (false) { + try { + FileOutputStream fileOutputStream = new FileOutputStream("transformed-" + className); + try { + fileOutputStream.write(bytes); + fileOutputStream.close(); + } finally { + fileOutputStream.close(); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return bytes; + } + + private static ClassWriter getClassWriter(int flags, final ClassLoader classLoader) { + return new MyClassWriter(flags, classLoader); + } + + public static int getClassFileVersion(ClassReader reader) { + final int[] classFileVersion = new int[1]; + reader.accept(new ClassVisitor(Opcodes.ASM5) { + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + classFileVersion[0] = version; + } + }, 0); + return classFileVersion[0]; + } + + private static class MyClassWriter extends ClassWriter { + public static final String JAVA_LANG_OBJECT = "java/lang/Object"; + private final ClassLoader classLoader; + + public MyClassWriter(int flags, ClassLoader classLoader) { + super(flags); + this.classLoader = classLoader; + } + + protected String getCommonSuperClass(String type1, String type2) { + try { + ClassReader info1 = typeInfo(type1); + ClassReader info2 = typeInfo(type2); + String + superType = checkImplementInterface(type1, type2, info1, info2); + if (superType != null) return superType; + superType = checkImplementInterface(type2, type1, info2, info1); + if (superType != null) return superType; + + StringBuilder b1 = typeAncestors(type1, info1); + StringBuilder b2 = typeAncestors(type2, info2); + String result = JAVA_LANG_OBJECT; + int end1 = b1.length(); + int end2 = b2.length(); + while (true) { + int start1 = b1.lastIndexOf(";", end1 - 1); + int start2 = b2.lastIndexOf(";", end2 - 1); + if (start1 != -1 && start2 != -1 && end1 - start1 == end2 - start2) { + String p1 = b1.substring(start1 + 1, end1); + String p2 = b2.substring(start2 + 1, end2); + if (p1.equals(p2)) { + result = p1; + end1 = start1; + end2 = start2; + } else { + return result; + } + } else { + return result; + } + } + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private String checkImplementInterface(String type1, String type2, ClassReader info1, ClassReader info2) throws IOException { + if ((info1.getAccess() & Opcodes.ACC_INTERFACE) != 0) { + if (typeImplements(type2, info2, type1)) { + return type1; + } + return JAVA_LANG_OBJECT; + } + return null; + } + + private StringBuilder typeAncestors(String type, ClassReader info) throws IOException { + StringBuilder b = new StringBuilder(); + while (!JAVA_LANG_OBJECT.equals(type)) { + b.append(';').append(type); + type = info.getSuperName(); + info = typeInfo(type); + } + return b; + } + + private boolean typeImplements(String type, ClassReader classReader, String interfaceName) throws IOException { + while (!JAVA_LANG_OBJECT.equals(type)) { + String[] itfs = classReader.getInterfaces(); + for (int i = 0; i < itfs.length; ++i) { + if (itfs[i].equals(interfaceName)) { + return true; + } + } + for (int i = 0; i < itfs.length; ++i) { + if (typeImplements(itfs[i], typeInfo(itfs[i]), interfaceName)) { + return true; + } + } + type = classReader.getSuperName(); + classReader = typeInfo(type); + } + return false; + } + + private ClassReader typeInfo(final String type) throws IOException { + InputStream is = classLoader.getResourceAsStream(type + ".class"); + if (is == null) System.out.println(classLoader + "," + type + ".class"); + try { + return new ClassReader(is); + } finally { + is.close(); + } + } + } +} diff --git a/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/URLsUtil.java b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/URLsUtil.java new file mode 100644 index 000000000000..05510fe75f45 --- /dev/null +++ b/java/execution/impl/testDiscovery/org/jetbrains/testme/instrumentation/URLsUtil.java @@ -0,0 +1,137 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.testme.instrumentation; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +public class URLsUtil { + public static final String FILE = "file"; + public static final String PROTOCOL_DELIMITER = ":"; + public static final String JAR_DELIMITER = "!"; + + public static boolean startsWithChar(CharSequence s, char prefix) { +return s != null && s.length() != 0 && s.charAt(0) == prefix; +} + + public static String extractRoot(URL resourceURL, String resourcePath) { + if (!(startsWithChar(resourcePath, '/') || startsWithChar(resourcePath, '\\'))) { + //noinspection HardCodedStringLiteral + System.err.println("precondition failed: "+resourcePath); + return null; + } + String protocol = resourceURL.getProtocol(); + String resultPath = null; + + if (FILE.equals(protocol)) { + String path = resourceURL.getFile(); + final String testPath = path.replace('\\', '/'); + final String testResourcePath = resourcePath.replace('\\', '/'); + if (endsWithIgnoreCase(testPath, testResourcePath)) { + resultPath = path.substring(0, path.length() - resourcePath.length()); + } + } + else if ("jar".equals(protocol)) { + String fullPath = resourceURL.getFile(); + int delimiter = fullPath.indexOf(JAR_DELIMITER); + if (delimiter >= 0) { + String archivePath = fullPath.substring(0, delimiter); + if (startsWithConcatenationOf(archivePath, FILE, PROTOCOL_DELIMITER)) { + resultPath = archivePath.substring(FILE.length() + PROTOCOL_DELIMITER.length()); + } + } + } + if (resultPath == null) { + //noinspection HardCodedStringLiteral + System.err.println("cannot extract: "+resultPath + " from "+resourceURL); + return null; + } + + if (resourcePath.endsWith(File.separator)) { + resultPath = resultPath.substring(0, resultPath.lastIndexOf(File.separator)); + } + resultPath = unescapePercentSequences(resultPath); + return resultPath; + } + + public static boolean startsWithConcatenationOf(String testee, String firstPrefix, String secondPrefix) { + int l1 = firstPrefix.length(); + int l2 = secondPrefix.length(); + if (testee.length() < l1 + l2) return false; + return testee.startsWith(firstPrefix) && testee.regionMatches(l1, secondPrefix, 0, l2); + } + + public static boolean endsWithIgnoreCase(String str, String suffix) { + final int stringLength = str.length(); + final int suffixLength = suffix.length(); + return stringLength >= suffixLength && str.regionMatches(true, stringLength - suffixLength, suffix, 0, suffixLength); + } + + public static String unescapePercentSequences(String s) { + if (s.indexOf('%') == -1) { + return s; + } + + StringBuilder decoded = new StringBuilder(); + final int len = s.length(); + int i = 0; + while (i < len) { + char c = s.charAt(i); + if (c == '%') { + List bytes = new ArrayList(); + while (i + 2 < len && s.charAt(i) == '%') { + final int d1 = decode(s.charAt(i + 1)); + final int d2 = decode(s.charAt(i + 2)); + if (d1 != -1 && d2 != -1) { + bytes.add(new Integer(((d1 & 0xf) << 4 | d2 & 0xf))); + i += 3; + } else { + break; + } + } + if (!bytes.isEmpty()) { + final byte[] bytesArray = new byte[bytes.size()]; + for (int j = 0; j < bytes.size(); j++) { + bytesArray[j] = (byte) ((Integer) bytes.get(j)).intValue(); + } + try { + decoded.append(new String(bytesArray, "UTF-8")); + continue; + } + catch (UnsupportedEncodingException ignored) { + } + } + } + + decoded.append(c); + i++; + } + return decoded.toString(); + } + + private static int decode(char c) { + if ((c >= '0') && (c <= '9')) + return c - '0'; + if ((c >= 'a') && (c <= 'f')) + return c - 'a' + 10; + if ((c >= 'A') && (c <= 'F')) + return c - 'A' + 10; + return -1; + } +} \ No newline at end of file diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java index a890bdad527d..f67d69f83d98 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/LibraryOptionsPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -334,7 +334,7 @@ public class LibraryOptionsPanel implements Disposable { dialog.show(); if (item instanceof ExistingLibraryEditor) { new WriteAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { ((ExistingLibraryEditor)item).commit(); } }.execute(); diff --git a/java/idea-ui/src/com/intellij/framework/addSupport/impl/AddSupportForSingleFrameworkDialog.java b/java/idea-ui/src/com/intellij/framework/addSupport/impl/AddSupportForSingleFrameworkDialog.java index 84816f8220f8..7eb0e166c741 100644 --- a/java/idea-ui/src/com/intellij/framework/addSupport/impl/AddSupportForSingleFrameworkDialog.java +++ b/java/idea-ui/src/com/intellij/framework/addSupport/impl/AddSupportForSingleFrameworkDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,7 +99,7 @@ public class AddSupportForSingleFrameworkDialog extends DialogWrapper { } new WriteAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { myModifiableModelsProvider.commitModuleModifiableModel(modifiableModel); } }.execute(); @@ -116,7 +116,7 @@ public class AddSupportForSingleFrameworkDialog extends DialogWrapper { } new WriteAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final ModifiableRootModel rootModel = myModifiableModelsProvider.getModuleModifiableModel(myModule); if (librarySettings != null) { librarySettings.addLibraries(rootModel, new ArrayList(), myModel.getLibrariesContainer()); diff --git a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/AddFrameworkSupportDialog.java b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/AddFrameworkSupportDialog.java index 42fdab95640c..8bdac3ef81bc 100644 --- a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/AddFrameworkSupportDialog.java +++ b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/AddFrameworkSupportDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -96,7 +96,7 @@ public class AddFrameworkSupportDialog extends DialogWrapper { } new WriteAction() { - protected void run(final Result result) { + protected void run(@NotNull final Result result) { ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel(); myAddSupportPanel.addSupport(myModule, model); model.commit(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java index d65c1a62b267..965512c4a382 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModulesConfigurator.java @@ -32,6 +32,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.Sdk; @@ -300,23 +301,27 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change } myFacetsConfigurator.applyEditors(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override + DumbService.getInstance(myProject).allowStartingDumbModeInside(DumbService.DumbModePermission.MAY_START_BACKGROUND, new Runnable() { public void run() { - try { - final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]); - ModifiableModelCommitter.multiCommit(rootModels, myModuleModel); - myModuleModelCommitted = true; - myFacetsConfigurator.commitFacets(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]); + ModifiableModelCommitter.multiCommit(rootModels, myModuleModel); + myModuleModelCommitted = true; + myFacetsConfigurator.commitFacets(); - } - finally { - ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade().clearMaps(false); + } + finally { + ModuleStructureConfigurable.getInstance(myProject).getFacetEditorFacade().clearMaps(false); - myFacetsConfigurator = createFacetsConfigurator(); - myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel(); - myModuleModelCommitted = false; - } + myFacetsConfigurator = createFacetsConfigurator(); + myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel(); + myModuleModelCommitted = false; + } + } + }); } }); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java index ce14999f05b9..4b57f49d9822 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -303,7 +303,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable { if (modifiableModel != null) { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { modifiableModel.commit(); } }.execute(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java index 5ff6700c385e..69bbb16f0f81 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactsStructureConfigurableContextImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -39,7 +39,10 @@ import com.intellij.packaging.ui.ManifestFileConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; /** * @author nik @@ -142,7 +145,7 @@ public class ArtifactsStructureConfigurableContextImpl implements ArtifactsStruc final Artifact originalArtifact = getOriginalArtifact(artifact); new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final ModifiableArtifact modifiableArtifact = getOrCreateModifiableArtifactModel().getOrCreateModifiableArtifact(originalArtifact); if (modifiableArtifact.getRootElement() == originalArtifact.getRootElement()) { modifiableArtifact.setRootElement(getOrCreateModifiableRootElement(originalArtifact)); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java index 4997fbaa0d25..5c3ff2adac6c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ChangeLibraryLevelActionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -167,7 +167,7 @@ public abstract class ChangeLibraryLevelActionBase extends AnAction { new WriteAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { for (Map.Entry entry : copiedFiles.entrySet()) { String fromPath = entry.getKey(); String toPath = entry.getValue(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/AddCustomLibraryDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/AddCustomLibraryDialog.java index 72239c852b1e..dfa569e24f62 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/AddCustomLibraryDialog.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraries/AddCustomLibraryDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -92,7 +92,7 @@ public class AddCustomLibraryDialog extends DialogWrapper { final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel(); new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { addLibraries(model, settings); model.commit(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java index 33445bdda9bc..feb2032345c4 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/CreateNewLibraryDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package com.intellij.openapi.roots.ui.configuration.libraryEditor; -import com.intellij.ui.ListCellRendererWrapper; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.roots.impl.libraries.LibraryEx; @@ -25,6 +24,7 @@ import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryType; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.ui.ComboBox; +import com.intellij.ui.ListCellRendererWrapper; import com.intellij.util.ui.FormBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,7 +77,7 @@ public class CreateNewLibraryDialog extends LibraryEditorDialogBase { myLibraryEditor.applyTo(model); new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { model.commit(); } }.execute(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java index 993f88a92998..8489f0042542 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibrariesContainerFactory.java @@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.impl.OrderEntryUtil; import com.intellij.openapi.roots.impl.libraries.LibraryEx; import com.intellij.openapi.roots.impl.libraries.LibraryTableBase; import com.intellij.openapi.roots.libraries.Library; @@ -236,16 +237,7 @@ public class LibrariesContainerFactory { if (myRootModel != null) { return myRootModel.getModuleLibraryTable().getLibraries(); } - OrderEntry[] orderEntries = ModuleRootManager.getInstance(myModule).getOrderEntries(); - List libraries = new ArrayList(); - for (OrderEntry orderEntry : orderEntries) { - if (orderEntry instanceof LibraryOrderEntry) { - final LibraryOrderEntry entry = (LibraryOrderEntry)orderEntry; - if (entry.isModuleLevel()) { - libraries.add(entry.getLibrary()); - } - } - } + List libraries = OrderEntryUtil.getModuleLibraries(ModuleRootManager.getInstance(myModule)); return libraries.toArray(new Library[libraries.size()]); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java index 97ed5b0da733..3238b057b3e9 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureDaemonAnalyzer.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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.openapi.roots.ui.configuration.projectRoot.daemon; import com.intellij.openapi.Disposable; @@ -57,7 +72,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { final ProjectStructureProblemsHolderImpl problemsHolder = new ProjectStructureProblemsHolderImpl(); new ReadAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { if (myStopped.get()) return; if (LOG.isDebugEnabled()) { @@ -72,7 +87,7 @@ public class ProjectStructureDaemonAnalyzer implements Disposable { private void doCollectUsages(final ProjectStructureElement element) { final List usages = new ReadAction>() { @Override - protected void run(final Result> result) { + protected void run(@NotNull final Result> result) { if (myStopped.get()) return; if (LOG.isDebugEnabled()) { diff --git a/java/idea-ui/src/com/intellij/platform/templates/SystemFileProcessor.java b/java/idea-ui/src/com/intellij/platform/templates/SystemFileProcessor.java index 29f21b4203de..6730b64ea6b4 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/SystemFileProcessor.java +++ b/java/idea-ui/src/com/intellij/platform/templates/SystemFileProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.impl.ComponentManagerImpl; -import com.intellij.openapi.components.impl.stores.ComponentStoreImpl; +import com.intellij.openapi.components.impl.stores.StoreUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.project.Project; @@ -88,7 +88,7 @@ public class SystemFileProcessor extends ProjectTemplateFileProcessor { Object state = ((PersistentStateComponent)component).getState(); Element element1 = XmlSerializer.serialize(state); element.addContent(element1.cloneContent()); - element.setAttribute("name", ComponentStoreImpl.getComponentName((PersistentStateComponent)component)); + element.setAttribute("name", StoreUtil.getComponentName((PersistentStateComponent)component)); } } }); diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java index 4fcefb8f6923..954765b86fe7 100644 --- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java +++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -40,20 +40,24 @@ import java.io.IOException; public class ConfigFileFactoryImpl extends ConfigFileFactory { private static final Logger LOG = Logger.getInstance("#com.intellij.util.descriptors.impl.ConfigFileFactoryImpl"); + @Override public ConfigFileMetaDataProvider createMetaDataProvider(final ConfigFileMetaData... metaDatas) { return new ConfigFileMetaDataRegistryImpl(metaDatas); } + @Override public ConfigFileMetaDataRegistry createMetaDataRegistry() { return new ConfigFileMetaDataRegistryImpl(); } + @Override public ConfigFileInfoSet createConfigFileInfoSet(final ConfigFileMetaDataProvider metaDataProvider) { return new ConfigFileInfoSetImpl(metaDataProvider); } + @Override public ConfigFileContainer createConfigFileContainer(final Project project, final ConfigFileMetaDataProvider metaDataProvider, - final ConfigFileInfoSet configuration) { + final ConfigFileInfoSet configuration) { return new ConfigFileContainerImpl(project, metaDataProvider, (ConfigFileInfoSetImpl)configuration); } @@ -66,6 +70,7 @@ public class ConfigFileFactoryImpl extends ConfigFileFactory { return template.getText(templateManager.getDefaultProperties()); } + @Override @Nullable public VirtualFile createFile(@Nullable Project project, String url, ConfigFileVersion version, final boolean forceNew) { return createFileFromTemplate(project, url, version.getTemplateName(), forceNew); @@ -106,6 +111,7 @@ public class ConfigFileFactoryImpl extends ConfigFileFactory { catch (final IOException e) { LOG.info(e); ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override public void run() { Messages.showErrorDialog(IdeBundle.message("message.text.error.creating.deployment.descriptor", e.getLocalizedMessage()), IdeBundle.message("message.text.creating.deployment.descriptor")); @@ -115,6 +121,7 @@ public class ConfigFileFactoryImpl extends ConfigFileFactory { return null; } + @Override public ConfigFileContainer createSingleFileContainer(Project project, ConfigFileMetaData metaData) { final ConfigFileMetaDataProvider metaDataProvider = createMetaDataProvider(metaData); return createConfigFileContainer(project, metaDataProvider, createConfigFileInfoSet(metaDataProvider)); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java index 5a3b720dc48e..6a27505bcb0b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java @@ -321,12 +321,11 @@ public class AnnotationsHighlightUtil { } @Nullable - static HighlightInfo checkValidAnnotationType(final PsiTypeElement typeElement) { - PsiType type = typeElement.getType(); - if (type.accept(AnnotationReturnTypeVisitor.INSTANCE).booleanValue()) { + static HighlightInfo checkValidAnnotationType(PsiType type, final PsiTypeElement typeElement) { + if (type != null && type.accept(AnnotationReturnTypeVisitor.INSTANCE).booleanValue()) { return null; } - String description = JavaErrorMessages.message("annotation.invalid.annotation.member.type"); + String description = JavaErrorMessages.message("annotation.invalid.annotation.member.type", type != null ? type.getPresentableText() : type); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create(); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 59d316734a15..54cf52204c78 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -275,7 +275,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh myHolder.add(AnnotationsHighlightUtil.checkMemberValueType(value, returnType)); } - myHolder.add(AnnotationsHighlightUtil.checkValidAnnotationType(method.getReturnTypeElement())); + myHolder.add(AnnotationsHighlightUtil.checkValidAnnotationType(method.getReturnType(), method.getReturnTypeElement())); final PsiClass aClass = method.getContainingClass(); myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), aClass)); myHolder.add(AnnotationsHighlightUtil.checkClashesWithSuperMethods(method)); diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java index a8effbfcb884..a970b8371f0d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java @@ -207,7 +207,7 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM } new WriteCommandAction(project) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { appendChosenAnnotationsRoot(entry, newRoot); XmlFile xmlFileInRoot = findXmlFileInRoot(findExternalAnnotationsXmlFiles(listOwner), newRoot); if (xmlFileInRoot != null) { //file already exists under appeared content root @@ -311,7 +311,7 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM new WriteCommandAction(project) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { if (existingXml != null) { annotateExternally(listOwner, annotationFQName, existingXml, fromFile, value); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java index 942379fdc909..da6d94fa2ec1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -42,22 +42,30 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement; */ public class JavaNoVariantsDelegator extends CompletionContributor { @Override - public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) { - LinkedHashSet plainResults = result.runRemainingContributors(parameters, true); - final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters); + public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) { + final InheritorsHolder holder = new InheritorsHolder(parameters.getPosition(), result); + ResultTracker tracker = new ResultTracker(result) { + @Override + public void consume(CompletionResult plainResult) { + super.consume(plainResult); + + LookupElement element = plainResult.getLookupElement(); + Object o = element.getObject(); + if (o instanceof PsiClass) { + holder.registerClass((PsiClass)o); + } + if (element instanceof TypeArgumentCompletionProvider.TypeArgsLookupElement) { + ((TypeArgumentCompletionProvider.TypeArgsLookupElement)element).registerSingleClass(holder); + } + } + }; + result.runRemainingContributors(parameters, tracker); + final boolean empty = tracker.containsOnlyPackages || suggestMetaAnnotations(parameters); if (!empty && parameters.getInvocationCount() == 0) { result.restartCompletionWhenNothingMatches(); } - InheritorsHolder holder = new InheritorsHolder(parameters.getPosition(), result); - for (CompletionResult plainResult : plainResults) { - Object o = plainResult.getLookupElement().getObject(); - if (o instanceof PsiClass) { - holder.registerClass((PsiClass)o); - } - } - if (empty) { delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result), holder); } else if (Registry.is("ide.completion.show.better.matching.classes")) { @@ -66,14 +74,7 @@ public class JavaNoVariantsDelegator extends CompletionContributor { JavaCompletionContributor.mayStartClassName(result) && JavaCompletionContributor.isClassNamePossible(parameters) && !JavaSmartCompletionContributor.AFTER_NEW.accepts(parameters.getPosition())) { - result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults))); - for (CompletionResult plainResult : plainResults) { - LookupElement element = plainResult.getLookupElement(); - if (element instanceof TypeArgumentCompletionProvider.TypeArgsLookupElement) { - ((TypeArgumentCompletionProvider.TypeArgsLookupElement)element).registerSingleClass(holder); - } - } - suggestNonImportedClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result), holder); + suggestNonImportedClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result.withPrefixMatcher(tracker.betterMatcher)), holder); } } } @@ -84,15 +85,6 @@ public class JavaNoVariantsDelegator extends CompletionContributor { psiElement().withSuperParent(4, psiClass().isAnnotationType()).accepts(position); } - public static boolean containsOnlyPackages(LinkedHashSet results) { - for (CompletionResult result : results) { - if (!(CompletionUtil.getTargetElement(result.getLookupElement()) instanceof PsiPackage)) { - return false; - } - } - return true; - } - private static void delegate(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritorsHolder) { if (parameters.getCompletionType() == CompletionType.BASIC) { PsiElement position = parameters.getPosition(); @@ -205,4 +197,27 @@ public class JavaNoVariantsDelegator extends CompletionContributor { } }); } + + public static class ResultTracker implements Consumer { + private final CompletionResultSet myResult; + public boolean containsOnlyPackages = true; + public BetterPrefixMatcher betterMatcher; + + public ResultTracker(CompletionResultSet result) { + myResult = result; + betterMatcher = new BetterPrefixMatcher(result); + } + + @Override + public void consume(CompletionResult plainResult) { + myResult.passResult(plainResult); + + LookupElement element = plainResult.getLookupElement(); + if (containsOnlyPackages && !(CompletionUtil.getTargetElement(element) instanceof PsiPackage)) { + containsOnlyPackages = false; + } + + betterMatcher = betterMatcher.improve(plainResult); + } + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java index ff1b786a3887..6b3bd68cd844 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -67,7 +67,7 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { }, getText(), getText()); new WriteCommandAction(newExpression.getProject(), getText(), getText()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { setupClassFromNewExpression(psiClass[0], newExpression); } }.execute(); @@ -112,7 +112,7 @@ public class CreateClassFromNewFix extends CreateFromUsageBaseFix { public void run() { new WriteCommandAction(project, getText(), getText()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { try { editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset()); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateParameterFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateParameterFromUsageFix.java index eb668943d9e2..6b5103040a9d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateParameterFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateParameterFromUsageFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -123,7 +123,7 @@ public class CreateParameterFromUsageFix extends CreateVarFromUsageFix { JavaPsiFacade.getElementFactory(project).createExpressionFromText(newParamName, finalMethod); new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final PsiReferenceExpression[] refs = CreateFromUsageUtils.collectExpressions(myReferenceExpression, PsiMember.class, PsiFile.class); for (PsiReferenceExpression ref : refs) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java index 1690d1455e8e..fafe750c55f5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -61,7 +61,7 @@ public class GenerifyFileFix implements IntentionAction, LocalQuickFix { myFileName = file.getName(); new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { invoke(project, FileEditorManager.getInstance(project).getSelectedTextEditor(), file); } }.execute(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementAbstractClassMethodsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementAbstractClassMethodsFix.java index d9c2dbbfb19a..e31ef56eae87 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementAbstractClassMethodsFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementAbstractClassMethodsFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -87,7 +87,7 @@ public class ImplementAbstractClassMethodsFix extends ImplementMethodsFix { new WriteCommandAction(project, file) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { PsiNewExpression newExpression = (PsiNewExpression)JavaPsiFacade.getElementFactory(project).createExpressionFromText(startElement.getText() + "{}", startElement); newExpression = (PsiNewExpression)startElement.replace(newExpression); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java index 715da62323de..92ae551b8579 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -28,13 +28,17 @@ import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiEnumConstant; +import com.intellij.psi.PsiFile; import com.intellij.psi.infos.CandidateInfo; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Collection; +import java.util.List; public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiElement { public ImplementMethodsFix(PsiElement aClass) { @@ -82,7 +86,7 @@ public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiEle new WriteCommandAction(project, file) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { final PsiClass psiClass = ((PsiEnumConstant)myPsiElement).getOrCreateInitializingClass(); OverrideImplementUtil.overrideOrImplementMethodsInRightPlace(editor, psiClass, selectedElements, chooser.isCopyJavadoc(), chooser.isInsertOverrideAnnotation()); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java index bcb2b17c2e5a..ccad56346af2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -60,7 +60,8 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import static com.intellij.codeInsight.daemon.impl.quickfix.MissingDependencyFixUtil.*; +import static com.intellij.codeInsight.daemon.impl.quickfix.MissingDependencyFixUtil.findFixes; +import static com.intellij.codeInsight.daemon.impl.quickfix.MissingDependencyFixUtil.provideFix; /** * @author cdr @@ -145,7 +146,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { if (libraryPath != null) { new WriteCommandAction(project) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { addJarsToRootsAndImportClass(Collections.singletonList(libraryPath), null, currentModule, editor, reference, "org.jetbrains.annotations." + referenceName); } @@ -363,7 +364,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { if (libraryPath != null) { new WriteCommandAction(module.getProject()) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { addJarToRoots(libraryPath, module, null); } }.execute(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java index d3c4858ffc34..25f7927aad06 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -131,7 +131,7 @@ public class CreateClassOrPackageFix extends LocalQuickFixAndIntentionActionOnPs if (isAvailable(project, null, file)) { new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final PsiDirectory directory = chooseDirectory(project, file); if (directory == null) return; ApplicationManager.getApplication().runWriteAction(new Runnable() { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java index 956e57c0904f..1e644ba3d5e0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFieldOrPropertyFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -103,7 +103,7 @@ public class CreateFieldOrPropertyFix implements IntentionAction, LocalQuickFix if (editor != null) { new WriteCommandAction(project, file) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { generateMembers(project, editor, file); } diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java index a850d336910a..240678e0726b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/MethodCallFixer.java @@ -83,7 +83,6 @@ public class MethodCallFixer implements Fixer { endOffset = CharArrayUtil.shiftBackward(editor.getDocument().getCharsSequence(), endOffset - 1, " \t\n") + 1; editor.getDocument().insertString(endOffset, ")"); - editor.getCaretModel().moveToOffset(endOffset + 1); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java index 65c4eb3ed3cb..0b31d1771e11 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -205,7 +205,7 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan public void run() { new WriteCommandAction(myProject) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { runTemplates(myProject, editor, templates, index + 1); } }.execute(); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index b4510a993e79..18362cf79fe9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,10 @@ */ package com.intellij.codeInsight.generation; -import com.intellij.codeInsight.*; +import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.MethodImplementor; import com.intellij.codeInsight.intention.AddAnnotationFix; import com.intellij.codeInsight.intention.AddAnnotationPsiFix; import com.intellij.featureStatistics.FeatureUsageTracker; @@ -457,7 +460,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { LOG.assertTrue(aClass.isValid()); new WriteCommandAction(project, aClass.getContainingFile()) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { overrideOrImplementMethodsInRightPlace(editor, aClass, selectedElements, chooser.isCopyJavadoc(), chooser.isInsertOverrideAnnotation()); } }.execute(); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java index a05641db8fb6..26a834ec4fe1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateSubclassAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -145,7 +145,7 @@ public class CreateSubclassAction extends BaseIntentionAction { public static void createInnerClass(final PsiClass aClass) { new WriteCommandAction(aClass.getProject(), getTitle(aClass), getTitle(aClass)) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final PsiClass containingClass = aClass.getContainingClass(); LOG.assertTrue(containingClass != null); @@ -197,7 +197,7 @@ public class CreateSubclassAction extends BaseIntentionAction { final PsiClass[] targetClass = new PsiClass[1]; new WriteCommandAction(project, getTitle(psiClass), getTitle(psiClass)) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace(); final PsiTypeParameterList oldTypeParameterList = psiClass.getTypeParameterList(); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java index 4fba52583963..43203db8d45f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/DeannotateIntentionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -164,7 +164,7 @@ public class DeannotateIntentionAction implements IntentionAction { final PsiModifierListOwner listOwner) { new WriteCommandAction(project, getText()) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { final VirtualFile virtualFile = file.getVirtualFile(); String qualifiedName = annotation.getQualifiedName(); LOG.assertTrue(qualifiedName != null); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExpandStaticImportAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExpandStaticImportAction.java index 5715da0992d0..1663e76317fe 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExpandStaticImportAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExpandStaticImportAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -87,7 +87,7 @@ public class ExpandStaticImportAction extends PsiElementBaseIntentionAction { public PopupStep onChosen(final String selectedValue, boolean finalChoice) { new WriteCommandAction(project, ExpandStaticImportAction.this.getText()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { if (selectedValue == REPLACE_THIS_OCCURRENCE) { expand(refExpr, staticImport); } diff --git a/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java b/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java index 9f5e4db20f02..0a74489bc056 100644 --- a/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java +++ b/java/java-impl/src/com/intellij/codeInspection/actions/ReplaceImplementsWithStaticImportAction.java @@ -43,7 +43,7 @@ import java.util.*; public class ReplaceImplementsWithStaticImportAction extends BaseIntentionAction { private static final Logger LOG = Logger.getInstance(ReplaceImplementsWithStaticImportAction.class); - @NonNls private static final String FIND_CONSTANT_FIELD_USAGES = "Find constant field usages..."; + @NonNls private static final String FIND_CONSTANT_FIELD_USAGES = "Find Constant Field Usages..."; @Override @NotNull @@ -106,10 +106,9 @@ public class ReplaceImplementsWithStaticImportAction extends BaseIntentionAction @Override public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { - if (!FileModificationService.getInstance().preparePsiElementForWrite(file)) return; - final int offset = editor.getCaretModel().getOffset(); - final PsiReference psiReference = file.findReferenceAt(offset); + final PsiClass targetClass; + final PsiReference psiReference = TargetElementUtil.findReference(editor); if (psiReference != null) { final PsiElement element = psiReference.getElement(); @@ -118,155 +117,131 @@ public class ReplaceImplementsWithStaticImportAction extends BaseIntentionAction final PsiElement target = psiReference.resolve(); LOG.assertTrue(target instanceof PsiClass); - - final PsiClass targetClass = (PsiClass)target; - new WriteCommandAction(project, getText()) { - @Override - protected void run(@NotNull Result result) throws Throwable { - for (PsiField constField : targetClass.getAllFields()) { - final String fieldName = constField.getName(); - final PsiClass containingClass = constField.getContainingClass(); - for (PsiReference ref : ReferencesSearch.search(constField)) { - final PsiElement psiElement = ref.getElement(); - if (ref instanceof PsiReferenceExpression) { - final PsiElement qualifier = ((PsiReferenceExpression)ref).getQualifier(); - if (qualifier != null) { - if (qualifier instanceof PsiReferenceExpression) { - final PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve(); - if (resolved instanceof PsiClass && !InheritanceUtil.isInheritorOrSelf(psiClass, (PsiClass)resolved, true)) { - continue; - } - } - qualifier.putCopyableUserData(ChangeContextUtil.CAN_REMOVE_QUALIFIER_KEY, - ChangeContextUtil.canRemoveQualifier((PsiReferenceExpression)ref)); - } - } - bindReference(psiElement.getContainingFile(), constField, containingClass, fieldName, ref, project); - } - } - element.delete(); - JavaCodeStyleManager.getInstance(project).optimizeImports(file); - } - }.execute(); + targetClass = (PsiClass)target; } else { final PsiElement identifier = file.findElementAt(offset); LOG.assertTrue(identifier instanceof PsiIdentifier); final PsiElement element = identifier.getParent(); LOG.assertTrue(element instanceof PsiClass); - final PsiClass targetClass = (PsiClass)element; - final Map>> refs = new HashMap>>(); - if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - for (PsiField field : targetClass.getAllFields()) { - final PsiClass containingClass = field.getContainingClass(); - for (PsiReference reference : ReferencesSearch.search(field)) { - if (reference == null) { - continue; - } - final PsiElement refElement = reference.getElement(); - if (encodeQualifier(containingClass, reference, targetClass)) continue; - final PsiFile psiFile = refElement.getContainingFile(); - if (psiFile instanceof PsiJavaFile) { - Map> references = refs.get(psiFile); - if (references == null) { - references = new HashMap>(); - refs.put(psiFile, references); - } - Set fieldsRefs = references.get(field); - if (fieldsRefs == null) { - fieldsRefs = new HashSet(); - references.put(field, fieldsRefs); - } - fieldsRefs.add(reference); - } - } - } - } - }); - } - }, FIND_CONSTANT_FIELD_USAGES, true, project)) { - return; - } - - final Set refs2Unimplement = new HashSet(); - if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - for (PsiClass psiClass : DirectClassInheritorsSearch.search(targetClass)) { - PsiFile containingFile = psiClass.getContainingFile(); - if (!refs.containsKey(containingFile)) { - refs.put(containingFile, new HashMap>()); - } - if (collectExtendsImplements(targetClass, psiClass.getExtendsList(), refs2Unimplement)) continue; - collectExtendsImplements(targetClass, psiClass.getImplementsList(), refs2Unimplement); - } - } - }); - } - }, "Find references in implement/extends lists...", true, project)) { - return; - } - - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - - for (PsiFile psiFile : refs.keySet()) { - final Map> map = refs.get(psiFile); - for (PsiField psiField : map.keySet()) { - final PsiClass containingClass = psiField.getContainingClass(); - final String fieldName = psiField.getName(); - for (PsiReference reference : map.get(psiField)) { - bindReference(psiFile, psiField, containingClass, fieldName, reference, project); - } - } - } - - for (PsiJavaCodeReferenceElement referenceElement : refs2Unimplement) { - referenceElement.delete(); - } - } - }); - - final Set> redundant = new HashSet>(); - final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); - final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project); - if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable(){ - @Override - public void run() { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - for (PsiFile psiFile : refs.keySet()) { - final Collection red = codeStyleManager.findRedundantImports((PsiJavaFile)psiFile); - if (red != null) { - for (PsiImportStatementBase statementBase : red) { - redundant.add(pointerManager.createSmartPsiElementPointer(statementBase)); - } - } - } - } - }); - } - }, "Collect redundant imports...", true, project)) return; - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - for (SmartPsiElementPointer pointer : redundant) { - final PsiImportStatementBase statementBase = pointer.getElement(); - if (statementBase != null) statementBase.delete(); - } - } - }); + targetClass = (PsiClass)element; } + final Map>> refs = new HashMap>>(); + if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + for (PsiField field : targetClass.getAllFields()) { + final PsiClass containingClass = field.getContainingClass(); + for (PsiReference reference : ReferencesSearch.search(field)) { + if (reference == null) { + continue; + } + final PsiElement refElement = reference.getElement(); + if (encodeQualifier(containingClass, reference, targetClass)) continue; + final PsiFile psiFile = refElement.getContainingFile(); + if (psiFile instanceof PsiJavaFile) { + Map> references = refs.get(psiFile); + if (references == null) { + references = new HashMap>(); + refs.put(psiFile, references); + } + Set fieldsRefs = references.get(field); + if (fieldsRefs == null) { + fieldsRefs = new HashSet(); + references.put(field, fieldsRefs); + } + fieldsRefs.add(reference); + } + } + } + } + }); + } + }, FIND_CONSTANT_FIELD_USAGES, true, project)) { + return; + } + + final Set refs2Unimplement = new HashSet(); + if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + for (PsiClass psiClass : DirectClassInheritorsSearch.search(targetClass)) { + PsiFile containingFile = psiClass.getContainingFile(); + if (!refs.containsKey(containingFile)) { + refs.put(containingFile, new HashMap>()); + } + if (collectExtendsImplements(targetClass, psiClass.getExtendsList(), refs2Unimplement)) continue; + collectExtendsImplements(targetClass, psiClass.getImplementsList(), refs2Unimplement); + } + } + }); + } + }, "Find References in Implement/Extends Lists...", true, project)) { + return; + } + + if (!FileModificationService.getInstance().preparePsiElementsForWrite(refs.keySet())) return; + + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + for (PsiFile psiFile : refs.keySet()) { + final Map> map = refs.get(psiFile); + for (PsiField psiField : map.keySet()) { + final PsiClass containingClass = psiField.getContainingClass(); + final String fieldName = psiField.getName(); + for (PsiReference reference : map.get(psiField)) { + bindReference(psiFile, psiField, containingClass, fieldName, reference, project); + } + } + } + + for (PsiJavaCodeReferenceElement referenceElement : refs2Unimplement) { + referenceElement.delete(); + } + } + }); + + final Map redundant = new HashMap(); + final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); + if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable(){ + @Override + public void run() { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + for (PsiFile psiFile : refs.keySet()) { + if (psiFile instanceof PsiJavaFile) { + final PsiImportList prepared = codeStyleManager.prepareOptimizeImportsResult((PsiJavaFile)psiFile); + if (prepared != null) { + redundant.put((PsiJavaFile)psiFile, prepared); + } + } + } + } + }); + } + }, "Optimize Imports...", true, project)) return; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + for (PsiJavaFile file : redundant.keySet()) { + final PsiImportList importList = redundant.get(file); + if (importList != null) { + final PsiImportList list = file.getImportList(); + if (list != null) { + list.replace(importList); + } + } + } + } + }); } private static boolean encodeQualifier(PsiClass containingClass, PsiReference reference, PsiClass targetClass) { diff --git a/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/GuavaFluentIterableInspection.java b/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/GuavaFluentIterableInspection.java index 21eeb7a9d6b2..0492fed9e417 100644 --- a/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/GuavaFluentIterableInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/GuavaFluentIterableInspection.java @@ -28,6 +28,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; @@ -57,6 +58,9 @@ public class GuavaFluentIterableInspection extends BaseJavaBatchLocalInspectionT @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { + if (!PsiUtil.isLanguageLevel8OrHigher(holder.getFile())) { + return PsiElementVisitor.EMPTY_VISITOR; + } final PsiClass fluentIterable = JavaPsiFacade.getInstance(holder.getProject()) .findClass(GUAVA_FLUENT_ITERABLE, GlobalSearchScope.allScope(holder.getProject())); if (fluentIterable == null) { diff --git a/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/PseudoLambdaReplaceTemplate.java b/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/PseudoLambdaReplaceTemplate.java index 425f1424837e..838032b0638e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/PseudoLambdaReplaceTemplate.java +++ b/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/PseudoLambdaReplaceTemplate.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.PsiDiamondTypeUtil; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.*; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -103,14 +104,47 @@ class PseudoLambdaReplaceTemplate { }); final PsiType returnType = method.getReturnType(); - if (returnType instanceof PsiClassType) { - final PsiClass resolvedReturnTypeClass = ((PsiClassType)returnType).resolve(); - if (!InheritanceUtil.isInheritor(resolvedReturnTypeClass, CommonClassNames.JAVA_LANG_ITERABLE)) { + if (StreamApiConstants.FAKE_FIND_MATCHED.equals(myStreamApiMethodName)) { + if (!PsiType.BOOLEAN.equals(returnType)) { return null; } - } else if (!(returnType instanceof PsiArrayType)) { - return null; + } else { + final PsiClass stream = + JavaPsiFacade.getInstance(method.getProject()).findClass(StreamApiConstants.JAVA_UTIL_STREAM_STREAM, method.getResolveScope()); + if (stream == null) { + return null; + } + final PsiMethod[] methods = stream.findMethodsByName(myStreamApiMethodName, false); + LOG.assertTrue(methods.length != 0); + PsiMethod representative = methods[0]; + final PsiType expectedReturnType = representative.getReturnType(); + if (expectedReturnType instanceof PsiClassType) { + final PsiClass resolvedClass = ((PsiClassType)expectedReturnType).resolve(); + if (resolvedClass == null) { + return null; + } else { + if (StreamApiConstants.JAVA_UTIL_STREAM_STREAM.equals(resolvedClass.getQualifiedName())) { + if (!(returnType instanceof PsiArrayType)) { + if (!(returnType instanceof PsiClassType)) { + return null; + } + final PsiClass methodReturnType = ((PsiClassType)returnType).resolve(); + if (methodReturnType == null || + (!InheritanceUtil.isInheritor(methodReturnType, CommonClassNames.JAVA_LANG_ITERABLE) && + !InheritanceUtil.isInheritor(methodReturnType, CommonClassNames.JAVA_LANG_ITERABLE))) { + return null; + } + } + } + } + } + else if (PsiType.BOOLEAN.equals(expectedReturnType)) { + if (!PsiType.BOOLEAN.equals(returnType)) { + return null; + } + } } + return validate(parameterTypes, returnType, null, method); } diff --git a/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/StaticPseudoFunctionalStyleMethodOptions.java b/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/StaticPseudoFunctionalStyleMethodOptions.java index 9787c394b997..e4842067e3bb 100644 --- a/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/StaticPseudoFunctionalStyleMethodOptions.java +++ b/java/java-impl/src/com/intellij/codeInspection/java18StreamApi/StaticPseudoFunctionalStyleMethodOptions.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.EditableModel; import com.intellij.util.ui.UIUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -119,9 +120,7 @@ public class StaticPseudoFunctionalStyleMethodOptions { } public JComponent createPanel() { - final JBList list = new JBList(); - list.setModel(new SettingsListModel()); - + final JBList list = new JBList(myElements); list.setCellRenderer(new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(JList list, PipelineElement element, int index, boolean selected, boolean hasFocus) { @@ -152,26 +151,19 @@ public class StaticPseudoFunctionalStyleMethodOptions { return; } myElements.add(newElement); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - list.revalidate(); - list.updateUI(); - } - }); + ((DefaultListModel)list.getModel()).addElement(newElement); } } }).setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { - myElements.remove(list.getSelectedIndex()); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - list.revalidate(); - list.updateUI(); - } - }); + final int[] indices = list.getSelectedIndices(); + final List toRemove = new ArrayList(indices.length); + for (int idx : indices) { + toRemove.add(myElements.get(idx)); + } + myElements.removeAll(toRemove); + ListUtil.removeSelectedItems(list); } }).createPanel(); } @@ -223,26 +215,4 @@ public class StaticPseudoFunctionalStyleMethodOptions { return result; } } - - private class SettingsListModel implements ListModel { - @Override - public int getSize() { - return myElements.size(); - } - - @Override - public PipelineElement getElementAt(int index) { - return myElements.get(index); - } - - @Override - public void addListDataListener(ListDataListener l) { - - } - - @Override - public void removeListDataListener(ListDataListener l) { - - } - } } diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java index 29e21845a7ad..8ee442b77e10 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -142,7 +142,7 @@ public class JavaDocReferenceInspection extends JavaDocReferenceInspectionBase { if (index < 0) return; new WriteCommandAction(project, element.getContainingFile()){ @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { final PsiClass psiClass = originalClasses.get(index); if (psiClass.isValid()) { PsiDocumentManager.getInstance(project).commitAllDocuments(); diff --git a/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java b/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java index c7b4d908ec53..a4ca39131218 100644 --- a/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java +++ b/java/java-impl/src/com/intellij/internal/GenerateVisitorByHierarchyAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -215,7 +215,7 @@ public class GenerateVisitorByHierarchyAction extends AnAction { } final int finalDetectedPrefix = detectClassPrefix(classes.keySet()).length(); new WriteCommandAction(project, PsiUtilCore.toPsiFileArray(psiFiles)) { - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { if (visitorClass == null) { final String shortClassName = PsiNameHelper.getShortClassName(visitorName); if (directory != null) { diff --git a/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java b/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java index b5f94aafb788..293819bf63be 100644 --- a/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java +++ b/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -206,7 +206,7 @@ public class UsedIconsListingAction extends AnAction { if (useScope.contains(file.getVirtualFile())) { new WriteCommandAction(project, file) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { att.setValue(replacement); } }.execute(); @@ -226,7 +226,7 @@ public class UsedIconsListingAction extends AnAction { if (useScope.contains(file.getVirtualFile())) { new WriteCommandAction(project, file) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { if (call instanceof PsiLiteralExpression) { call.replace(factory.createExpressionFromText("\"" + replacement + "\"", call)); } @@ -255,7 +255,7 @@ public class UsedIconsListingAction extends AnAction { if (useScope.contains(file.getVirtualFile())) { new WriteCommandAction(project, file) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { annotation.getNode(); annotation.setDeclaredAttributeValue( "icon", diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java index eba4ae956627..483afe0f5644 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -187,7 +187,7 @@ public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetec final int parameterIndex = method.getParameterList().getParameterIndex(parameter); new WriteCommandAction(element.getProject(), MOVE_PARAMETER){ @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final PsiParameterList parameterList = method.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); final int deltaOffset = editor.getCaretModel().getOffset() - parameter.getTextRange().getStartOffset(); diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java index 7be6c5431a5e..07de9a3ddbad 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSignatureSuggester.java @@ -380,6 +380,7 @@ public class ExtractMethodSignatureSuggester { myDuplicatesNumber = duplicatesNumber; setTitle("Extract Parameters to Replace Duplicates"); setOKButtonText("Accept Signature Change"); + setCancelButtonText("Keep Original Signature"); init(); } diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java index f9956486b053..03d4f641bf73 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java @@ -139,7 +139,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor { } myClass = new WriteCommandAction(myProject, getCommandName()){ @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { result.setResult(buildClass()); } }.execute().getResultObject(); diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java index 442a065c9673..014318867ad5 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -41,6 +41,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.InlineUtil; import com.intellij.refactoring.util.RefactoringMessageDialog; import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -135,7 +136,7 @@ public class InlineParameterHandler extends JavaInlineActionHandler { if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs, def) == null) { new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { for (final PsiElement ref : refs) { InlineUtil.inlineVariable(psiParameter, rExpr, (PsiJavaCodeReferenceElement)ref); } diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java index 41173c93c870..276d6e6365af 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineStaticImportHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -25,6 +25,7 @@ import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.listeners.RefactoringEventListener; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -59,7 +60,7 @@ public class InlineStaticImportHandler extends JavaInlineActionHandler { new WriteCommandAction(project, REFACTORING_NAME){ @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { replaceAllAndDeleteImport(referenceElements, null, staticStatement); } }.execute(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index 862cd019fc48..2f940fc2575a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -53,6 +53,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.util.FileTypeUtils; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilCore; @@ -61,11 +62,13 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; import com.intellij.refactoring.rename.RenameJavaVariableProcessor; -import com.intellij.refactoring.util.*; +import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.refactoring.util.EnumConstantsUtil; +import com.intellij.refactoring.util.RefactoringChangeUtil; +import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.occurrences.OccurrenceManager; import com.intellij.util.IncorrectOperationException; import com.intellij.util.VisibilityUtil; -import com.intellij.psi.util.FileTypeUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -209,7 +212,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase new WriteCommandAction(project, getRefactoringName()){ @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { runnable.run(); } }.execute(); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java index ac2c06c28f0f..fcdf3042a255 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceConstantPopup.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -248,7 +248,7 @@ public class InplaceIntroduceConstantPopup extends AbstractInplaceIntroduceField myParentClass, false, false); new WriteCommandAction(myProject, getCommandName(), getCommandName()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { if (getLocalVariable() != null) { final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = new LocalToFieldHandler.IntroduceFieldRunnable(false, (PsiLocalVariable)getLocalVariable(), myParentClass, settings, true, diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java index 1ad65a6b1b44..1a12431325d3 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/InplaceIntroduceFieldPopup.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -223,7 +223,7 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop myParentClass, false, false); new WriteCommandAction(myProject, getCommandName(), getCommandName()){ @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { if (getLocalVariable() != null) { final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable = new LocalToFieldHandler.IntroduceFieldRunnable(false, (PsiLocalVariable)getLocalVariable(), myParentClass, settings, myStatic, myOccurrences); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java index 7f446347c425..d54711369b6e 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java @@ -246,7 +246,7 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer public void actionPerformed(ActionEvent e) { new WriteCommandAction(myProject, getCommandName(), getCommandName()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument()); final PsiVariable variable = getVariable(); if (variable != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java index 080024807d11..25bf567dd14a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/ReassignVariableUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ package com.intellij.refactoring.introduceVariable; import com.google.common.annotations.VisibleForTesting; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; -import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.ui.ListCellRendererWrapper; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; @@ -30,11 +28,13 @@ import com.intellij.openapi.util.Key; import com.intellij.psi.*; import com.intellij.psi.scope.processor.VariablesProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; -import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.rename.inplace.InplaceRefactoring; +import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBList; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -138,7 +138,7 @@ public class ReassignVariableUtil { final PsiExpression initializer = var.getInitializer(); new WriteCommandAction(declaration.getProject()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(variable.getProject()); final String chosenVariableName = variable.getName(); //would generate red code for final variables diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java index 6875287390e6..935c3d11d96d 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -89,7 +89,7 @@ public class JavaMoveFilesOrDirectoriesHandler extends MoveFilesOrDirectoriesHan public PsiElement[] fun(final PsiElement[] elements) { return new WriteCommandAction(project, "Regrouping ...") { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final List adjustedElements = new ArrayList(); for (int i = 0, length = elements.length; i < length; i++) { PsiElement element = elements[i]; diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameWrongRefHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameWrongRefHandler.java index 1fdce6c4a0c4..b2434684fc44 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/RenameWrongRefHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameWrongRefHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,14 @@ package com.intellij.refactoring.rename; import com.intellij.codeInsight.daemon.impl.quickfix.RenameWrongRefFix; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceExpression; import org.jetbrains.annotations.NotNull; public class RenameWrongRefHandler implements RenameHandler { @@ -53,7 +54,7 @@ public class RenameWrongRefHandler implements RenameHandler { if (reference instanceof PsiReferenceExpression) { new WriteCommandAction(project){ @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { new RenameWrongRefFix((PsiReferenceExpression)reference).invoke(project, editor, file); } }.execute(); diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java index 38c798b5549d..72604a3b202b 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -137,7 +137,7 @@ public class DuplicatesImpl { new WriteCommandAction(project, MethodDuplicatesHandler.REFACTORING_NAME, MethodDuplicatesHandler.REFACTORING_NAME) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { try { provider.processMatch(match); } diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java index 7f8ad6acc3b4..951aefb6c425 100644 --- a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java +++ b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -345,13 +345,14 @@ public class CreateTestDialog extends DialogWrapper { } } }); + final boolean hasTestRoots = !ModuleRootManager.getInstance(myTargetModule).getSourceRoots(JavaModuleSourceRootTypes.TESTS).isEmpty(); final List attachedLibraries = new ArrayList(); final String defaultLibrary = getDefaultLibraryName(); TestFramework defaultDescriptor = null; final DefaultComboBoxModel model = (DefaultComboBoxModel)myLibrariesCombo.getModel(); for (final TestFramework descriptor : Extensions.getExtensions(TestFramework.EXTENSION_NAME)) { model.addElement(descriptor); - if (descriptor.isLibraryAttached(myTargetModule)) { + if (hasTestRoots && descriptor.isLibraryAttached(myTargetModule)) { attachedLibraries.add(descriptor); } @@ -480,7 +481,7 @@ public class CreateTestDialog extends DialogWrapper { final PackageWrapper targetPackage = new PackageWrapper(PsiManager.getInstance(myProject), packageName); final VirtualFile selectedRoot = new ReadAction() { - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final HashSet testFolders = new HashSet(); CreateTestAction.checkForTestRoots(myTargetModule, testFolders); List roots; @@ -504,7 +505,7 @@ public class CreateTestDialog extends DialogWrapper { if (selectedRoot == null) return null; return new WriteCommandAction(myProject, CodeInsightBundle.message("create.directory.command")) { - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { result.setResult(RefactoringUtil.createPackageDirectoryInSourceRoot(targetPackage, selectedRoot)); } }.execute().getResultObject(); diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java index 87cc8e38cb2f..f8b6aa3e5f35 100644 --- a/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java +++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java @@ -16,84 +16,24 @@ package com.intellij.psi.search.searches; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressIndicatorProvider; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; -import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.PsiSearchScopeUtil; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; +import com.intellij.psi.PsiClass; import com.intellij.psi.search.SearchScope; -import com.intellij.psi.util.PsiUtilCore; -import com.intellij.reference.SoftReference; -import com.intellij.util.Processor; import com.intellij.util.Query; import com.intellij.util.QueryExecutor; -import com.intellij.util.containers.Stack; -import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.lang.ref.Reference; -import java.util.Set; /** * @author max */ public class ClassInheritorsSearch extends ExtensibleQueryFactory { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.classInheritorsSearch"); - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.search.searches.ClassInheritorsSearch"); - public static final ClassInheritorsSearch INSTANCE = new ClassInheritorsSearch(); - static { - INSTANCE.registerExecutor(new QueryExecutor() { - @Override - public boolean execute(@NotNull final SearchParameters parameters, @NotNull final Processor consumer) { - final PsiClass baseClass = parameters.getClassToProcess(); - final SearchScope searchScope = parameters.getScope(); - - LOG.assertTrue(searchScope != null); - - ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); - if (progress != null) { - progress.pushState(); - String className = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return baseClass.getName(); - } - }); - progress.setText(className != null ? - PsiBundle.message("psi.search.inheritors.of.class.progress", className) : - PsiBundle.message("psi.search.inheritors.progress")); - } - - boolean result = processInheritors(consumer, baseClass, searchScope, parameters); - - if (progress != null) { - progress.popState(); - } - - return result; - } - }); - } - - public interface InheritanceChecker { - boolean checkInheritance(@NotNull PsiClass subClass, @NotNull PsiClass parentClass); - - InheritanceChecker DEFAULT = new InheritanceChecker() { - @Override - public boolean checkInheritance(@NotNull PsiClass subClass, @NotNull PsiClass parentClass) { - return subClass.isInheritor(parentClass, false); - } - }; - } - public static class SearchParameters { private final PsiClass myClass; private final SearchScope myScope; @@ -101,7 +41,6 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory myNameCondition; - private final InheritanceChecker myInheritanceChecker; public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance, boolean includeAnonymous) { this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, Conditions.alwaysTrue()); @@ -109,18 +48,12 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory nameCondition) { - this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, nameCondition, InheritanceChecker.DEFAULT); - } - - public SearchParameters(@NotNull final PsiClass aClass, @NotNull SearchScope scope, final boolean checkDeep, final boolean checkInheritance, - boolean includeAnonymous, @NotNull final Condition nameCondition, @NotNull InheritanceChecker inheritanceChecker) { myClass = aClass; myScope = scope; myCheckDeep = checkDeep; myCheckInheritance = checkInheritance; myIncludeAnonymous = includeAnonymous; myNameCondition = nameCondition; - myInheritanceChecker = inheritanceChecker; } @NotNull @@ -183,127 +116,4 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory consumer, - @NotNull final PsiClass baseClass, - @NotNull final SearchScope searchScope, - @NotNull final SearchParameters parameters) { - if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) return true; - - final String qname = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return baseClass.getQualifiedName(); - } - }); - if (CommonClassNames.JAVA_LANG_OBJECT.equals(qname)) { - Project project = PsiUtilCore.getProjectInReadAction(baseClass); - return AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor() { - @Override - public boolean process(final PsiClass aClass) { - ProgressIndicatorProvider.checkCanceled(); - final String qname1 = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - @Nullable - public String compute() { - return aClass.getQualifiedName(); - } - }); - return CommonClassNames.JAVA_LANG_OBJECT.equals(qname1) || consumer.process(aClass); - } - }); - } - - final Ref currentBase = Ref.create(null); - final Stack, String>> stack = new Stack, String>>(); - // there are two sets for memory optimization: it's cheaper to hold FQN than PsiClass - final Set processedFqns = new THashSet(); // FQN of processed classes if the class has one - final Set processed = new THashSet(); // processed classes without FQN (e.g. anonymous) - - final Processor processor = new Processor() { - @Override - public boolean process(final PsiClass candidate) { - ProgressIndicatorProvider.checkCanceled(); - - final Ref result = new Ref(); - final String[] fqn = new String[1]; - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - fqn[0] = candidate.getQualifiedName(); - if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) { - if (!parameters.myInheritanceChecker.checkInheritance(candidate, currentBase.get())) { - result.set(true); - return; - } - } - - if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { - if (candidate instanceof PsiAnonymousClass) { - result.set(consumer.process(candidate)); - } - else { - final String name = candidate.getName(); - if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) result.set(false); - } - } - } - }); - if (!result.isNull()) return result.get().booleanValue(); - - if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) { - Reference ref = fqn[0] == null ? createHardReference(candidate) : new SoftReference(candidate); - stack.push(Pair.create(ref, fqn[0])); - } - - return true; - } - }; - stack.push(Pair.create(createHardReference(baseClass), qname)); - final GlobalSearchScope projectScope = GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(baseClass)); - final JavaPsiFacade facade = JavaPsiFacade.getInstance(projectScope.getProject()); - while (!stack.isEmpty()) { - ProgressIndicatorProvider.checkCanceled(); - - Pair, String> pair = stack.pop(); - PsiClass psiClass = pair.getFirst().get(); - final String fqn = pair.getSecond(); - if (psiClass == null) { - psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiClass compute() { - return facade.findClass(fqn, projectScope); - } - }); - if (psiClass == null) continue; - } - if (fqn == null) { - if (!processed.add(psiClass)) continue; - } - else { - if (!processedFqns.add(fqn)) continue; - } - - currentBase.set(psiClass); - if (!DirectClassInheritorsSearch.search(psiClass, projectScope, parameters.isIncludeAnonymous(), false).forEach(processor)) return false; - } - return true; - } - - private static Reference createHardReference(final PsiClass candidate) { - return new SoftReference(candidate){ - @Override - public PsiClass get() { - return candidate; - } - }; - } - - private static boolean isFinal(@NotNull final PsiClass baseClass) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return Boolean.valueOf(baseClass.hasModifierProperty(PsiModifier.FINAL)); - } - }).booleanValue(); - } } diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java new file mode 100644 index 000000000000..7846f74651e2 --- /dev/null +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java @@ -0,0 +1,169 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.search; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.QueryExecutorBase; +import com.intellij.openapi.application.ReadActionProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiSearchScopeUtil; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.searches.AllClassesSearch; +import com.intellij.psi.search.searches.ClassInheritorsSearch; +import com.intellij.psi.search.searches.DirectClassInheritorsSearch; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.Processor; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Stack; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +public class JavaClassInheritorsSearcher extends QueryExecutorBase { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.JavaClassInheritorsSearcher"); + + @Override + public void processQuery(@NotNull ClassInheritorsSearch.SearchParameters parameters, @NotNull Processor consumer) { + final PsiClass baseClass = parameters.getClassToProcess(); + final SearchScope searchScope = parameters.getScope(); + + LOG.assertTrue(searchScope != null); + + ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); + if (progress != null) { + progress.pushState(); + String className = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + return baseClass.getName(); + } + }); + progress.setText(className != null ? + PsiBundle.message("psi.search.inheritors.of.class.progress", className) : + PsiBundle.message("psi.search.inheritors.progress")); + } + + processInheritors(consumer, baseClass, searchScope, parameters); + + if (progress != null) { + progress.popState(); + } + } + + private static void processInheritors(@NotNull final Processor consumer, + @NotNull final PsiClass baseClass, + @NotNull final SearchScope searchScope, + @NotNull final ClassInheritorsSearch.SearchParameters parameters) { + if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) return; + + Project project = PsiUtilCore.getProjectInReadAction(baseClass); + if (isJavaLangObject(baseClass)) { + AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor() { + @Override + public boolean process(final PsiClass aClass) { + ProgressIndicatorProvider.checkCanceled(); + return isJavaLangObject(aClass) || consumer.process(aClass); + } + }); + return; + } + + final Ref currentBase = Ref.create(null); + final Stack stack = new Stack(); + final Set processed = ContainerUtil.newTroveSet(); + + final Processor processor = new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiClass candidate) { + ProgressIndicatorProvider.checkCanceled(); + + if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) { + if (!candidate.isInheritor(currentBase.get(), false)) { + return true; + } + } + + if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { + if (candidate instanceof PsiAnonymousClass) { + return consumer.process(candidate); + } + + final String name = candidate.getName(); + if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) { + return false; + } + } + + if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) { + stack.push(PsiAnchor.create(candidate)); + } + return true; + } + }; + + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + stack.push(PsiAnchor.create(baseClass)); + } + }); + final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project); + + while (!stack.isEmpty()) { + ProgressIndicatorProvider.checkCanceled(); + + final PsiAnchor anchor = stack.pop(); + if (!processed.add(anchor)) continue; + + PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiClass compute() { + return (PsiClass)anchor.retrieve(); + } + }); + if (psiClass == null) continue; + + currentBase.set(psiClass); + if (!DirectClassInheritorsSearch.search(psiClass, projectScope, parameters.isIncludeAnonymous(), false).forEach(processor)) return; + } + } + + private static boolean isJavaLangObject(@NotNull final PsiClass baseClass) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + return baseClass.isValid() && CommonClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName()); + } + }); + } + + private static boolean isFinal(@NotNull final PsiClass baseClass) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + return Boolean.valueOf(baseClass.hasModifierProperty(PsiModifier.FINAL)); + } + }).booleanValue(); + } + +} diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java index 8ce1add395f4..94ba3199fa09 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SPIReferencesSearcher.java @@ -73,7 +73,12 @@ public class SPIReferencesSearcher extends QueryExecutorBase() { + @Override + public String[] compute() { + return FilenameIndex.getAllFilenames(project); + } + }); for (final String filename : filenames) { if (filename.startsWith(qualifiedName + ".")) { final PsiFile[] files = ApplicationManager.getApplication().runReadAction(new Computable() { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index 8906acd20834..2674f9e49b78 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -233,7 +233,14 @@ public class InferenceSession { private static PsiType getParameterType(PsiParameter[] parameters, int i, @Nullable PsiSubstitutor substitutor, boolean varargs) { if (substitutor == null) return null; - PsiType parameterType = substitutor.substitute(parameters[i < parameters.length ? i : parameters.length - 1].getType()); + + final PsiParameter parameter = parameters[i < parameters.length ? i : parameters.length - 1]; + final PsiType type = parameter.getType(); + if (!type.isValid()) { + PsiUtil.ensureValidType(type, "Invalid type of parameter " + parameter + " of " + parameter.getClass()); + } + + PsiType parameterType = substitutor.substitute(type); if (parameterType instanceof PsiEllipsisType && varargs) { parameterType = ((PsiEllipsisType)parameterType).getComponentType(); } @@ -1231,7 +1238,9 @@ public class InferenceSession { final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(reference); final PsiClass containingClass = qualifierResolveResult.getContainingClass(); - LOG.assertTrue(containingClass != null, myContext); + if (containingClass == null) { + return resolveSubset(myInferenceVariables, mySiteSubstitutor); + } final PsiParameter[] functionalMethodParameters = interfaceMethod.getParameterList().getParameters(); final PsiParameter[] parameters = method.getParameterList().getParameters(); diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index 75438aaa7322..450320748097 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -11,7 +11,7 @@ annotation.not.applicable=''@{0}'' not applicable to {1} annotation.non.constant.attribute.value=Attribute value must be constant annotation.non.class.literal.attribute.value=Attribute value must be a class literal annotation.non.enum.constant.attribute.value=Attribute value must be an enum constant -annotation.invalid.annotation.member.type=Invalid type for annotation member +annotation.invalid.annotation.member.type=Invalid type ''{0}'' for annotation member annotation.cyclic.element.type=Cyclic annotation element type annotation.annotation.type.expected=Annotation type expected annotation.members.may.not.have.throws.list=@interface members may not have throws list diff --git a/java/java-runtime/src/com/intellij/execution/TestDiscoveryListener.java b/java/java-runtime/src/com/intellij/execution/TestDiscoveryListener.java index 25641ff9fbca..7d33ce1ec650 100644 --- a/java/java-runtime/src/com/intellij/execution/TestDiscoveryListener.java +++ b/java/java-runtime/src/com/intellij/execution/TestDiscoveryListener.java @@ -17,10 +17,11 @@ package com.intellij.execution; import java.lang.reflect.Method; -public class TestDiscoveryListener { +public abstract class TestDiscoveryListener { + public abstract String getFrameworkId(); public void testStarted(String className, String methodName) { - final Object data = getData(); try { + final Object data = getData(); Method testStarted = data.getClass().getMethod("testStarted", new Class[] {String.class}); testStarted.invoke(data, new Object[] {className + "-" + methodName}); } catch (Throwable t) { @@ -29,23 +30,22 @@ public class TestDiscoveryListener { } public void testFinished(String className, String methodName) { - final Object data = getData(); try { + final Object data = getData(); Method testEnded = data.getClass().getMethod("testEnded", new Class[] {String.class}); - testEnded.invoke(data, new Object[] {className + "-" + methodName}); + testEnded.invoke(data, new Object[] {getFrameworkId() + className + "-" + methodName}); } catch (Throwable t) { t.printStackTrace(); } } - protected Object getData() { - try { - return Class.forName("org.jetbrains.testme.instrumentation.ProjectData") + protected Object getData() throws Exception { + return Class.forName("org.jetbrains.testme.instrumentation.ProjectData") .getMethod("getProjectData", new Class[0]) .invoke(null, new Object[0]); - - } catch (Exception e) { - return null; //should not happen - } } + + public void testRunStarted(String name) {} + + public void testRunFinished(String name) {} } diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java index 72791579a996..5645ec5ae162 100644 --- a/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java +++ b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java @@ -67,13 +67,14 @@ public class ComparisonFailureData { Map attrs, Throwable throwable) { + final int failureIdx = failureMessage != null ? trace.indexOf(failureMessage) : -1; + final int failureMessageLength = failureMessage != null ? failureMessage.length() : 0; + attrs.put("details", failureIdx > -1 ? trace.substring(failureIdx + failureMessageLength) : trace); + if (notification != null) { attrs.put("expected", notification.getExpected()); attrs.put("actual", notification.getActual()); - final int failureIdx = failureMessage != null ? trace.indexOf(failureMessage) : -1; - final int failureMessageLength = failureMessage != null ? failureMessage.length() : 0; - attrs.put("details", failureIdx > -1 ? trace.substring(failureIdx + failureMessageLength) : trace); final String filePath = notification.getFilePath(); if (filePath != null) { attrs.put("expectedFile", filePath); @@ -89,8 +90,6 @@ public class ComparisonFailureData { attrs.put("message", comparisonFailureMessage); } else { - attrs.put("details", trace); - Throwable throwableCause = null; try { throwableCause = throwable.getCause(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/clashMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/clashMethods.java index e15d63d6d873..e2a9126a01f1 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/clashMethods.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/clashMethods.java @@ -3,7 +3,7 @@ Class annotationType(); int value(); boolean equals(); - void finalize(); - void registerNatives(); + void finalize(); + void registerNatives(); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/invalidType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/invalidType.java index c3915c6f69d6..5920a906e2c1 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/invalidType.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/invalidType.java @@ -1,8 +1,9 @@ class Clazz {} @interface Ann { - Clazz i (); + Clazz i (); Ann j (); - void f(); + void f(); + int[] intDblArray()[]; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IncompleteCodeWithMethodReferenceOverLambdaParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IncompleteCodeWithMethodReferenceOverLambdaParameter.java new file mode 100644 index 000000000000..9f7e191ecd6f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/IncompleteCodeWithMethodReferenceOverLambdaParameter.java @@ -0,0 +1,12 @@ + +import java.util.function.Function; +class Test { + { + foo(s -> { + foo(s::concat); + return s; + }); + } + + void foo(Function f){} +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java index 671ef78fb08b..fda1f1cc4eb4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/AddAnnotationFixTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -45,7 +45,6 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.testFramework.IdeaTestCase; import com.intellij.testFramework.PsiTestUtil; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; @@ -201,7 +200,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListening(expectedSequence); new WriteCommandAction(myProject){ @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { fix.invoke(myProject, editor, file); } }.execute(); @@ -271,7 +270,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListening(container, AnnotationUtil.NOT_NULL, true); new WriteCommandAction(myProject){ @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { ExternalAnnotationsManager.getInstance(myProject).deannotate(container, AnnotationUtil.NOT_NULL); } }.execute(); @@ -319,7 +318,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListening(method, AnnotationUtil.NULLABLE, true); new WriteCommandAction(myProject) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { manager.editExternalAnnotation(method, AnnotationUtil.NULLABLE, annotationFromText.getParameterList().getAttributes()); } }.execute(); @@ -328,7 +327,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListening(parameter, AnnotationUtil.NOT_NULL, true); new WriteCommandAction(myProject) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { manager.editExternalAnnotation(parameter, AnnotationUtil.NOT_NULL, annotationFromText.getParameterList().getAttributes()); } }.execute(); @@ -350,7 +349,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListening(method, AnnotationUtil.NOT_NULL, false); new WriteCommandAction(myProject){ @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { ExternalAnnotationsManager.getInstance(myProject).annotateExternally(method, AnnotationUtil.NOT_NULL, myFixture.getFile(), null); } }.execute(); @@ -359,7 +358,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListening(method, AnnotationUtil.NOT_NULL, false); new WriteCommandAction(myProject){ @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { ExternalAnnotationsManager.getInstance(myProject).editExternalAnnotation(method, AnnotationUtil.NOT_NULL, null); } }.execute(); @@ -368,7 +367,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListening(method, AnnotationUtil.NOT_NULL, false); new WriteCommandAction(myProject){ @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { ExternalAnnotationsManager.getInstance(myProject).deannotate(method, AnnotationUtil.NOT_NULL); } }.execute(); @@ -385,7 +384,7 @@ public class AddAnnotationFixTest extends UsefulTestCase { startListeningForExternalChanges(); new WriteCommandAction(myProject){ @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { VirtualFile file = LocalFileSystem.getInstance().findFileByPath(myFixture.getTempDirPath() + "/content/anno/p/annotations.xml"); assert file != null; String newText = " " + StreamUtil.readText(file.getInputStream()) + " "; // adding newspace to the beginning and end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index 05e475a286a7..00c60425f436 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -418,6 +418,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIncompleteCodeWithMethodReferenceOverLambdaParameter() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromUsageTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromUsageTest.java index 0f0138a0804a..35ffeb5a4990 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromUsageTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromUsageTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import org.jetbrains.annotations.NotNull; /** * @author ven @@ -56,7 +57,7 @@ public class CreateFieldFromUsageTest extends LightQuickFixTestCase { public void testSortByRelevance() throws Exception { new WriteCommandAction(getProject()) { @Override - protected void run(Result result) throws Exception { + protected void run(@NotNull Result result) throws Exception { VirtualFile foo = getSourceRoot().createChildDirectory(this, "foo").createChildData(this, "Foo.java"); VfsUtil.saveText(foo, "package foo; public class Foo { public void put(Object key, Object value) {} }"); PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); diff --git a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/JavaFileTemplatesTest.java b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/JavaFileTemplatesTest.java index 65f4a60a983a..a11fab663abb 100644 --- a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/JavaFileTemplatesTest.java +++ b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/JavaFileTemplatesTest.java @@ -15,8 +15,10 @@ */ package com.intellij.ide.fileTemplates; +import com.intellij.ide.IdeBundle; import com.intellij.ide.fileTemplates.actions.CreateFromTemplateAction; import com.intellij.ide.fileTemplates.actions.CreateFromTemplateGroup; +import com.intellij.ide.fileTemplates.impl.FileTemplateManagerImpl; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.util.Condition; import com.intellij.testFramework.TestActionEvent; @@ -24,6 +26,8 @@ import com.intellij.testFramework.TestDataProvider; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import com.intellij.util.containers.ContainerUtil; +import java.util.Arrays; + public class JavaFileTemplatesTest extends LightCodeInsightFixtureTestCase { public void testCreateFromTemplateGroup() throws Exception { @@ -43,4 +47,23 @@ public class JavaFileTemplatesTest extends LightCodeInsightFixtureTestCase { } })); } + + @SuppressWarnings("ConstantConditions") + public void testManyTemplates() throws Exception { + FileTemplateManagerImpl templateManager = (FileTemplateManagerImpl)FileTemplateManager.getInstance(getProject()); + templateManager.getState().RECENT_TEMPLATES.clear(); + FileTemplate[] before = templateManager.getAllTemplates(); + try { + for (int i = 0; i < 30; i++) { + templateManager.addTemplate("foo" + i, "java"); + } + AnAction[] children = new CreateFromTemplateGroup().getChildren(new TestActionEvent(new TestDataProvider(getProject()))); + assertEquals(3, children.length); + assertTrue(IdeBundle.message("action.from.file.template").equals(children[0].getTemplatePresentation().getText())); + } + finally { + templateManager.setTemplates(FileTemplateManager.DEFAULT_TEMPLATES_CATEGORY, Arrays.asList(before)); + templateManager.getState().RECENT_TEMPLATES.clear(); + } + } } diff --git a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java index e9d74ecc0587..27cc8e39550d 100644 --- a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -107,7 +107,7 @@ public class PsiConcurrencyStressTest extends DaemonAnalyzerTestCase { Thread.sleep(100); new WriteCommandAction(myProject, myFile) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { writeActionInProgress = true; documentManager.commitAllDocuments(); writeStep(random); diff --git a/java/java-tests/testSrc/com/intellij/psi/search/FindUsagesTest.java b/java/java-tests/testSrc/com/intellij/psi/search/FindUsagesTest.java index d6e5e9d8fd8a..4928562f5356 100644 --- a/java/java-tests/testSrc/com/intellij/psi/search/FindUsagesTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/search/FindUsagesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ import com.intellij.testFramework.fixtures.TempDirTestFixture; import com.intellij.usageView.UsageInfo; import com.intellij.util.Processor; import com.intellij.util.containers.IntArrayList; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; @@ -133,7 +134,7 @@ public class FindUsagesTest extends PsiTestCase{ try { new WriteCommandAction(getProject()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { final ModifiableModuleModel moduleModel = ModuleManager.getInstance(getProject()).getModifiableModel(); moduleModel.newModule("independent/independent.iml", StdModuleTypes.JAVA.getId()); moduleModel.commit(); diff --git a/java/java-tests/testSrc/com/intellij/psi/search/PlainTextUsagesTest.java b/java/java-tests/testSrc/com/intellij/psi/search/PlainTextUsagesTest.java index 03ebf7740629..0819a2bbad49 100644 --- a/java/java-tests/testSrc/com/intellij/psi/search/PlainTextUsagesTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/search/PlainTextUsagesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; @@ -30,6 +29,7 @@ import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.PsiTestCase; import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.containers.IntArrayList; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -53,7 +53,7 @@ public class PlainTextUsagesTest extends PsiTestCase { assertNotNull(resourcesDir); new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { final Module module = createModule("res"); PsiTestUtil.addContentRoot(module, resourcesDir); final VirtualFile child = resourcesDir.findChild("Test.xml"); diff --git a/java/java-tests/testSrc/com/intellij/psi/util/proximity/ProximityTest.java b/java/java-tests/testSrc/com/intellij/psi/util/proximity/ProximityTest.java index 1bef1c5ffc52..6ec524986aeb 100644 --- a/java/java-tests/testSrc/com/intellij/psi/util/proximity/ProximityTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/util/proximity/ProximityTest.java @@ -1,6 +1,17 @@ /* - * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved. - * Use is subject to license terms. + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.intellij.psi.util.proximity; @@ -11,6 +22,7 @@ import com.intellij.testFramework.PsiTestUtil; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; import com.intellij.testFramework.fixtures.TempDirTestFixture; +import org.jetbrains.annotations.NotNull; /** * @author peter @@ -27,7 +39,7 @@ public class ProximityTest extends JavaCodeInsightFixtureTestCase { try { new WriteCommandAction(getProject()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { PsiTestUtil.addSourceContentToRoots(myModule, root1.getFile("")); PsiTestUtil.addSourceContentToRoots(myModule, root2.getFile("")); } diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java index 34690fe90c48..e1ceedfb3c06 100644 --- a/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java +++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -25,12 +25,10 @@ import org.jetbrains.annotations.Nullable; * @author nik */ public abstract class ConfigFileFactory { - public static ConfigFileFactory getInstance() { return ServiceManager.getService(ConfigFileFactory.class); } - public abstract ConfigFileMetaDataProvider createMetaDataProvider(ConfigFileMetaData... metaDatas); public abstract ConfigFileInfoSet createConfigFileInfoSet(ConfigFileMetaDataProvider metaDataProvider); diff --git a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java index 2f3539faa7f3..73613644878f 100644 --- a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java +++ b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java @@ -22,7 +22,6 @@ import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.ComponentsPackage; -import com.intellij.openapi.components.impl.stores.ComponentStoreImpl; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; @@ -32,6 +31,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ModuleRootModificationUtil; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -75,13 +75,13 @@ public class CompilerTestUtil { private static void doSaveComponent(Object appComponent) { //noinspection TestOnlyProblems - ((ComponentStoreImpl)ComponentsPackage.getStateStore(ApplicationManager.getApplication())).saveApplicationComponent(appComponent); + ComponentsPackage.getStateStore(ApplicationManager.getApplication()).saveApplicationComponent(appComponent); } public static void enableExternalCompiler() { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { ApplicationManagerEx.getApplicationEx().doNotSave(false); JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); table.addJdk(table.getInternalJdk()); @@ -92,7 +92,7 @@ public class CompilerTestUtil { public static void disableExternalCompiler(final Project project) { new WriteAction() { @Override - protected void run(final Result result) { + protected void run(@NotNull final Result result) { ApplicationManagerEx.getApplicationEx().doNotSave(true); Module[] modules = ModuleManager.getInstance(project).getModules(); JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx(); diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java index 5c63d391d11b..d082f3578137 100644 --- a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,17 @@ package com.intellij.testFramework; import com.intellij.ide.highlighter.ModuleFileType; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.components.ComponentsPackage; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.StdModuleTypes; import com.intellij.openapi.module.impl.ModuleImpl; +import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.project.impl.ProjectImpl; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Computable; @@ -151,20 +155,21 @@ public abstract class ModuleTestCase extends IdeaTestCase { return result.get(); } - protected void readJdomExternalizables(final ModuleImpl module) { + protected void readJdomExternalizables(@NotNull Module module) { loadModuleComponentState(module, ModuleRootManager.getInstance(module)); } - protected final void loadModuleComponentState(final Module module, final Object component) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - final ProjectImpl project = (ProjectImpl)myProject; - project.setOptimiseTestLoadSpeed(false); - ((ModuleImpl)module).getStateStore().initComponent(component, false); - project.setOptimiseTestLoadSpeed(true); - } - }); + protected final void loadModuleComponentState(@NotNull Module module, @NotNull Object component) { + AccessToken token = WriteAction.start(); + try { + ProjectEx project = (ProjectEx)myProject; + project.setOptimiseTestLoadSpeed(false); + ComponentsPackage.getStateStore(module).initComponent(component, false); + project.setOptimiseTestLoadSpeed(true); + } + finally { + token.finish(); + } } protected Module createModuleFromTestData(final String dirInTestData, final String newModuleFileName, final ModuleType moduleType, diff --git a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java index 4015fb4b3ce8..d78c00776528 100644 --- a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java @@ -93,7 +93,7 @@ public abstract class PsiTestCase extends ModuleTestCase { protected PsiFile createFile(@NotNull final Module module, @NotNull final VirtualFile vDir, @NotNull final String fileName, @NotNull final String text) throws IOException { return new WriteAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { if (!ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(vDir)) { addSourceContentToRoots(module, vDir); } diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java index dbb5502e84df..a0c1e003cbe8 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -39,7 +39,7 @@ public class JavaCodeInsightTestUtil { fixture.configureByFile(before); new WriteCommandAction(fixture.getProject()) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { final Editor editor = fixture.getEditor(); final PsiElement element = TargetElementUtil.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS); assert element instanceof PsiLocalVariable : element; @@ -54,7 +54,7 @@ public class JavaCodeInsightTestUtil { fixture.configureByFile(before); new WriteCommandAction(fixture.getProject()) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { final Editor editor = fixture.getEditor(); final PsiElement element = TargetElementUtil.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS); assert element instanceof PsiParameter : element; @@ -69,7 +69,7 @@ public class JavaCodeInsightTestUtil { fixture.configureByFile(before); new WriteCommandAction(fixture.getProject()) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { final Editor editor = fixture.getEditor(); final PsiElement element = TargetElementUtil.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS); assert element instanceof PsiMethod : element; @@ -90,7 +90,7 @@ public class JavaCodeInsightTestUtil { fixture.configureByFile(before); new WriteCommandAction(fixture.getProject()) { @Override - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { final Editor editor = fixture.getEditor(); final PsiElement element = TargetElementUtil.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS); assert element instanceof PsiField : element; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index 4fa3ac3d83bb..98b7f30e788a 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. diff --git a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java index 8421a523a799..6c9cda8d3384 100644 --- a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java +++ b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java @@ -15,6 +15,7 @@ */ package org.jetbrains.jps.build; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.ParameterizedRunnable; import com.sampullara.cli.Args; @@ -88,7 +89,8 @@ public class Standalone { printUsageAndExit(); } - instance.loadAndRunBuild(projectPaths.get(0)); + final String projectPath = (new File(projectPaths.get(0))).getAbsolutePath(); + instance.loadAndRunBuild(FileUtil.toCanonicalPath(projectPath)); System.exit(0); } diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/export/HTMLExporter.java b/platform/analysis-impl/src/com/intellij/codeInspection/export/HTMLExporter.java index f136632d0f76..896d22588afe 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/export/HTMLExporter.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/export/HTMLExporter.java @@ -59,9 +59,10 @@ public class HTMLExporter { public void createPage(RefEntity element) throws IOException { final String currentFileName = fileNameForElement(element); - StringBuffer buf = new StringBuffer(); + StringBuffer buf = new StringBuffer(""); appendNavBar(buf, element); myComposer.composeWithExporter(buf, element, this); + buf.append(""); writeFileImpl(myRootFolder, currentFileName, buf); myGeneratedPages.add(element); } diff --git a/platform/bootstrap/src/com/intellij/idea/Main.java b/platform/bootstrap/src/com/intellij/idea/Main.java index 8055b51ad16a..6e45261447ec 100644 --- a/platform/bootstrap/src/com/intellij/idea/Main.java +++ b/platform/bootstrap/src/com/intellij/idea/Main.java @@ -148,7 +148,7 @@ public class Main { try { Process process = Runtime.getRuntime().exec(command); String line = (new BufferedReader(new InputStreamReader(process.getErrorStream()))).readLine(); - if (line != null && (line.startsWith("java version") || (line.startsWith("Openjdk version")))){ + if (line != null && (line.toLowerCase().startsWith("java version") || (line.toLowerCase().startsWith("openjdk version")))){ String[] javaVersion = line.split("\\."); int i = 1; if (javaVersion.length > i && Integer.parseInt(javaVersion[i]) > 5) { @@ -161,23 +161,17 @@ public class Main { return false; } - private static String getBundledJava(String javaHome) throws IOException { - boolean clear = true; String javaHomeCopy = System.getProperty("user.home") + "/." + System.getProperty("idea.paths.selector") + "/restart/jre"; File javaCopy = SystemInfoRt.isWindows ? new File(javaHomeCopy + "/bin/java.exe") : new File(javaHomeCopy + "/bin/java"); - if (javaCopy != null && javaCopy.exists()) { - if (checkBundledJava(javaCopy)) { - javaHome = javaHomeCopy; - } - } - else { - clear = false; + if (javaCopy != null && javaCopy.isFile() && checkBundledJava(javaCopy)) { + javaHome = javaHomeCopy; } if (javaHome != javaHomeCopy) { - if (clear) FileUtil.delete(new File(javaHomeCopy)); - System.out.println("Updater: java copy: " + javaHome + " to " + javaHomeCopy); - FileUtil.copyDir(new File(javaHome), new File(javaHomeCopy)); + File javaHomeCopyDir = new File(javaHomeCopy); + if (javaHomeCopyDir.exists()) FileUtil.delete(javaHomeCopyDir); + System.out.println("Updater: java: " + javaHome + " copied to " + javaHomeCopy); + FileUtil.copyDir(new File(javaHome), javaHomeCopyDir); javaHome = javaHomeCopy; } return javaHome; @@ -186,7 +180,7 @@ public class Main { private static String getJava() throws IOException { String javaHome = System.getProperty("java.home"); if (javaHome.toLowerCase().startsWith(PathManager.getHomePath().toLowerCase())) { - System.out.println("bundled java."); + System.out.println("Updater: uses bundled java."); javaHome = getBundledJava(javaHome); } return javaHome + "/bin/java"; diff --git a/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java index 7b9203e131cf..0c23e2e774c4 100644 --- a/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java @@ -28,7 +28,7 @@ import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ApplicationStoreImpl extends ComponentStoreImpl { +class ApplicationStoreImpl extends ComponentStoreImpl { private static final Logger LOG = Logger.getInstance(ApplicationStoreImpl.class); private static final String DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + DirectoryStorageData.DEFAULT_EXT; diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java similarity index 95% rename from platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java rename to platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java index 202b214d012b..26aa6c54eb4c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java @@ -91,18 +91,11 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl { } } - @NotNull - protected abstract XmlElementStorage getMainStorage(); - @Nullable static List getConversionProblemsStorage() { return ourConversionProblemsStorage; } - public BaseStorageData getMainStorageData() { - return (BaseStorageData)getMainStorage().getStorageData(); - } - @NotNull @Override protected final PathMacroManager getPathMacroManagerForDefaults() { diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java similarity index 80% rename from platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java rename to platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java index faf27e90cd38..7a43c36265c9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java @@ -26,15 +26,12 @@ import com.intellij.openapi.components.store.ReadOnlyModificationException; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.util.ArrayUtilRt; import com.intellij.util.ReflectionUtil; import com.intellij.util.SmartList; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.SmartHashSet; import com.intellij.util.lang.CompoundRuntimeException; @@ -71,11 +68,24 @@ public abstract class ComponentStoreImpl implements IComponentStore { AccessToken token = ReadAction.start(); try { + String componentNameIfStateExists; if (component instanceof PersistentStateComponent) { - initPersistentComponent((PersistentStateComponent)component, null, false); + componentNameIfStateExists = initPersistentComponent((PersistentStateComponent)component, null, false); } else { - initJdomExternalizable((JDOMExternalizable)component); + componentNameIfStateExists = initJdomExternalizable((JDOMExternalizable)component); + } + + // if not service, so, component manager will check it later for all components + if (componentNameIfStateExists != null && service) { + Project project = getProject(); + Application app = ApplicationManager.getApplication(); + if (project != null && !app.isHeadlessEnvironment() && !app.isUnitTestMode() && project.isInitialized()) { + TrackingPathMacroSubstitutor substitutor = getStateStorageManager().getMacroSubstitutor(); + if (substitutor != null) { + StorageUtil.notifyUnknownMacros(substitutor, project, componentNameIfStateExists); + } + } } } catch (StateStorageException e) { @@ -121,6 +131,7 @@ public abstract class ComponentStoreImpl implements IComponentStore { } @TestOnly + @Override public void saveApplicationComponent(@NotNull Object component) { StateStorageManager.ExternalizationSession externalizationSession = getStateStorageManager().startExternalization(); if (externalizationSession == null) { @@ -210,28 +221,29 @@ public abstract class ComponentStoreImpl implements IComponentStore { T state = component.getState(); if (state != null) { Storage[] storageSpecs = getComponentStorageSpecs(component, StoreUtil.getStateSpec(component), StateStorageOperation.WRITE); - session.setState(storageSpecs, component, componentName == null ? getComponentName(component) : componentName, state); + session.setState(storageSpecs, component, componentName == null ? StoreUtil.getComponentName(component) : componentName, state); } } - private void initJdomExternalizable(@NotNull JDOMExternalizable component) { + @Nullable + private String initJdomExternalizable(@NotNull JDOMExternalizable component) { String componentName = ComponentManagerImpl.getComponentName(component); doAddComponent(componentName, component); if (optimizeTestLoading()) { - return; + return null; } loadJdomDefaults(component, componentName); StateStorage stateStorage = getStateStorageManager().getOldStorage(component, componentName, StateStorageOperation.READ); if (stateStorage == null) { - return; + return null; } Element element = stateStorage.getState(component, componentName, Element.class, null); if (element == null) { - return; + return null; } try { @@ -242,10 +254,10 @@ public abstract class ComponentStoreImpl implements IComponentStore { } catch (InvalidDataException e) { LOG.error(e); - return; + return null; } - validateUnusedMacros(componentName, true); + return componentName; } private void doAddComponent(String componentName, Object component) { @@ -273,20 +285,7 @@ public abstract class ComponentStoreImpl implements IComponentStore { return null; } - private void validateUnusedMacros(@Nullable final String componentName, final boolean service) { - final Project project = getProject(); - if (project == null) return; - - if (!ApplicationManager.getApplication().isHeadlessEnvironment() && !ApplicationManager.getApplication().isUnitTestMode()) { - if (service && componentName != null && project.isInitialized()) { - final TrackingPathMacroSubstitutor substitutor = getStateStorageManager().getMacroSubstitutor(); - if (substitutor != null) { - StorageUtil.notifyUnknownMacros(substitutor, project, componentName); - } - } - } - } - + @Nullable private String initPersistentComponent(@NotNull PersistentStateComponent component, @Nullable Set changedStorages, boolean reloadData) { State stateSpec = StoreUtil.getStateSpec(component); String name = stateSpec.name(); @@ -294,7 +293,7 @@ public abstract class ComponentStoreImpl implements IComponentStore { doAddComponent(name, component); } if (optimizeTestLoading()) { - return name; + return null; } Class stateClass = ComponentSerializationUtil.getStateClass(component.getClass()); @@ -329,8 +328,6 @@ public abstract class ComponentStoreImpl implements IComponentStore { component.loadState(state); } - validateUnusedMacros(name, true); - return name; } @@ -364,11 +361,6 @@ public abstract class ComponentStoreImpl implements IComponentStore { } } - @NotNull - public static String getComponentName(@NotNull PersistentStateComponent persistentStateComponent) { - return StoreUtil.getStateSpec(persistentStateComponent).name(); - } - @NotNull protected Storage[] getComponentStorageSpecs(@NotNull PersistentStateComponent component, @NotNull State stateSpec, @@ -534,89 +526,4 @@ public abstract class ComponentStoreImpl implements IComponentStore { messageBus.syncPublisher(BatchUpdateListener.TOPIC).onBatchUpdateFinished(); } } - - public enum ReloadComponentStoreStatus { - RESTART_AGREED, - RESTART_CANCELLED, - ERROR, - SUCCESS, - } - - @NotNull - public static ReloadComponentStoreStatus reloadStore(@NotNull MultiMap changes, @NotNull IComponentStore store) { - Collection notReloadableComponents; - boolean willBeReloaded = false; - try { - AccessToken token = WriteAction.start(); - try { - notReloadableComponents = store.reload(changes); - } - catch (Throwable e) { - Messages.showWarningDialog(ProjectBundle.message("project.reload.failed", e.getMessage()), - ProjectBundle.message("project.reload.failed.title")); - return ReloadComponentStoreStatus.ERROR; - } - finally { - token.finish(); - } - - if (ContainerUtil.isEmpty(notReloadableComponents)) { - return ReloadComponentStoreStatus.SUCCESS; - } - - willBeReloaded = askToRestart(store, notReloadableComponents, changes); - return willBeReloaded ? ReloadComponentStoreStatus.RESTART_AGREED : ReloadComponentStoreStatus.RESTART_CANCELLED; - } - finally { - if (!willBeReloaded) { - for (StateStorage storage : changes.keySet()) { - if (storage instanceof StateStorageBase) { - ((StateStorageBase)storage).enableSaving(); - } - } - } - } - } - - // used in settings repository plugin - public static boolean askToRestart(@NotNull IComponentStore store, - @NotNull Collection notReloadableComponents, - @Nullable MultiMap changedStorages) { - StringBuilder message = new StringBuilder(); - String storeName = store instanceof IProjectStore ? "Project" : "Application"; - message.append(storeName).append(' '); - message.append("components were changed externally and cannot be reloaded:\n\n"); - int count = 0; - for (String component : notReloadableComponents) { - if (count == 10) { - message.append('\n').append("and ").append(notReloadableComponents.size() - count).append(" more").append('\n'); - } - else { - message.append(component).append('\n'); - count++; - } - } - - message.append("\nWould you like to "); - if (store instanceof IProjectStore) { - message.append("reload project?"); - } - else { - message.append(ApplicationManager.getApplication().isRestartCapable() ? "restart" : "shutdown").append(' '); - message.append(ApplicationNamesInfo.getInstance().getProductName()).append('?'); - } - - if (Messages.showYesNoDialog(message.toString(), - storeName + " Files Changed", Messages.getQuestionIcon()) == Messages.YES) { - if (changedStorages != null) { - for (StateStorage storage : changedStorages.keySet()) { - if (storage instanceof StateStorageBase) { - ((StateStorageBase)storage).disableSaving(); - } - } - } - return true; - } - return false; - } } diff --git a/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleFileData.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleFileData.java new file mode 100644 index 000000000000..76a997237e37 --- /dev/null +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleFileData.java @@ -0,0 +1,121 @@ +/* + * Copyright 2000-2015 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.openapi.components.impl.stores; + +import com.intellij.openapi.components.PathMacroSubstitutor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.OptionManager; +import com.intellij.openapi.util.text.StringUtil; +import org.jdom.Attribute; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; +import java.util.TreeMap; + +final class ModuleFileData extends BaseFileConfigurableStoreImpl.BaseStorageData implements OptionManager { + private TreeMap options; + private final Module myModule; + + private boolean dirty = true; + + public ModuleFileData(@NotNull String rootElementName, @NotNull Module module) { + super(rootElementName); + + myModule = module; + options = new TreeMap(); + } + + @Override + public boolean isDirty() { + return dirty; + } + + private ModuleFileData(@NotNull ModuleFileData storageData) { + super(storageData); + + myModule = storageData.myModule; + dirty = storageData.dirty; + options = new TreeMap(storageData.options); + } + + @Override + public void load(@NotNull Element rootElement, @Nullable PathMacroSubstitutor pathMacroSubstitutor, boolean intern) { + super.load(rootElement, pathMacroSubstitutor, intern); + + for (Attribute attribute : rootElement.getAttributes()) { + String name = attribute.getName(); + if (!name.equals(BaseFileConfigurableStoreImpl.VERSION_OPTION) && !StringUtil.isEmpty(name)) { + options.put(name, attribute.getValue()); + } + } + + dirty = false; + } + + @Override + protected void writeOptions(@NotNull Element root, @NotNull String versionString) { + if (!options.isEmpty()) { + for (String key : options.keySet()) { + String value = options.get(key); + if (value != null) { + root.setAttribute(key, value); + } + } + } + // need be last for compat reasons + super.writeOptions(root, versionString); + + dirty = false; + } + + @Override + public StorageData clone() { + return new ModuleFileData(this); + } + + @Nullable + @Override + public Set getChangedComponentNames(@NotNull StorageData newStorageData, @Nullable PathMacroSubstitutor substitutor) { + final ModuleFileData data = (ModuleFileData)newStorageData; + if (!options.equals(data.options)) { + return null; + } + + return super.getChangedComponentNames(newStorageData, substitutor); + } + + @Override + public void setOption(@NotNull String key, @NotNull String value) { + if (!value.equals(options.put(key, value))) { + dirty = true; + } + } + + @Override + public void clearOption(@NotNull String key) { + if (options.remove(key) != null) { + dirty = true; + } + } + + @Override + @Nullable + public String getOptionValue(@NotNull String key) { + return options.get(key); + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java similarity index 71% rename from platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java rename to platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java index 688a81e60bf7..8fe6c9f15444 100644 --- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java @@ -15,22 +15,21 @@ */ package com.intellij.openapi.components.impl.stores; -import com.intellij.openapi.components.StateStorage; -import com.intellij.openapi.components.StateStorageOperation; -import com.intellij.openapi.components.StoragePathMacros; -import com.intellij.openapi.components.TrackingPathMacroSubstitutor; -import com.intellij.openapi.module.impl.ModuleImpl; +import com.intellij.openapi.components.*; +import com.intellij.openapi.module.Module; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; -public class ModuleStateStorageManager extends StateStorageManagerImpl { +class ModuleStateStorageManager extends StateStorageManagerImpl { @NonNls private static final String ROOT_TAG_NAME = "module"; - private final ModuleImpl myModule; + private final Module myModule; - public ModuleStateStorageManager(@NotNull TrackingPathMacroSubstitutor pathMacroManager, @NotNull ModuleImpl module) { + public ModuleStateStorageManager(@NotNull TrackingPathMacroSubstitutor pathMacroManager, @NotNull Module module) { super(pathMacroManager, ROOT_TAG_NAME, module, module.getPicoContainer()); myModule = module; @@ -39,7 +38,7 @@ public class ModuleStateStorageManager extends StateStorageManagerImpl { @NotNull @Override protected StorageData createStorageData(@NotNull String fileSpec, @NotNull String filePath) { - return new ModuleStoreImpl.ModuleFileData(ROOT_TAG_NAME, myModule); + return new ModuleFileData(ROOT_TAG_NAME, myModule); } @NotNull @@ -49,9 +48,11 @@ public class ModuleStateStorageManager extends StateStorageManagerImpl { @NotNull @Override public List createSaveSessions() { - if (myModule.getStateStore().getMainStorageData().isDirty()) { + StateStorageManagerImpl storageManager = (StateStorageManagerImpl)ComponentsPackage.getStateStore(myModule).getStateStorageManager(); + FileBasedStorage storage = ContainerUtil.getFirstItem(storageManager.getCachedFileStorages(Collections.singletonList(StoragePathMacros.MODULE_FILE))); + if (storage != null && storage.getStorageData().isDirty()) { // force XmlElementStorageSaveSession creation - getExternalizationSession(myModule.getStateStore().getMainStorage()); + getExternalizationSession(storage); } return super.createSaveSessions(); } diff --git a/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java new file mode 100644 index 000000000000..62429b486ad0 --- /dev/null +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2015 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.openapi.components.impl.stores; + +import com.intellij.openapi.components.PathMacroManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.util.messages.MessageBus; +import org.jetbrains.annotations.NotNull; + +final class ModuleStoreImpl extends BaseFileConfigurableStoreImpl { + private final Module myModule; + + public ModuleStoreImpl(@NotNull Module module, @NotNull PathMacroManager pathMacroManager) { + super(pathMacroManager); + + myModule = module; + } + + @Override + protected Project getProject() { + return myModule.getProject(); + } + + @Override + protected boolean optimizeTestLoading() { + return ((ProjectEx)myModule.getProject()).isOptimiseTestLoadSpeed(); + } + + @NotNull + @Override + protected MessageBus getMessageBus() { + return myModule.getMessageBus(); + } + + @NotNull + @Override + protected StateStorageManager createStateStorageManager() { + return new ModuleStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myModule); + } +} diff --git a/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java index 7e7426069712..b8638ab5059f 100644 --- a/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java @@ -384,12 +384,6 @@ public class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements I } } - @NotNull - @Override - protected XmlElementStorage getMainStorage() { - return getProjectFileStorage(); - } - @NotNull @Override protected StateStorageManager createStateStorageManager() { @@ -452,7 +446,8 @@ public class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements I super.load(rootElement, pathMacroSubstitutor, intern); } - protected void convert(final Element root, final int originalVersion) { + @SuppressWarnings("UnusedParameters") + protected void convert(Element root, int originalVersion) { } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java similarity index 97% rename from platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java rename to platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java index 1b7e84cecbf4..af2a65e6550f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java +++ b/platform/configuration-store-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java @@ -135,7 +135,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di } @NotNull - private Collection getCachedFileStorages(@NotNull Collection fileSpecs) { + public Collection getCachedFileStorages(@NotNull Collection fileSpecs) { if (fileSpecs.isEmpty()) { return Collections.emptyList(); } @@ -175,14 +175,13 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di ((MutablePicoContainer)myPicoContainer).registerComponentImplementation(key, storageClass); return (StateStorage)myPicoContainer.getComponentInstance(key); } - final String filePath = expandMacros(fileSpec); - File file = new File(filePath).getAbsoluteFile(); + + String filePath = expandMacros(fileSpec); + File file = new File(filePath); //noinspection deprecation if (!stateSplitter.equals(StateSplitter.class) && !stateSplitter.equals(StateSplitterEx.class)) { - @SuppressWarnings("deprecation") - StateSplitter splitter = ReflectionUtil.newInstance(stateSplitter); - return new DirectoryBasedStorage(myPathMacroSubstitutor, file, splitter, this, createStorageTopicListener()); + return new DirectoryBasedStorage(myPathMacroSubstitutor, file, ReflectionUtil.newInstance(stateSplitter), this, createStorageTopicListener()); } if (!ApplicationManager.getApplication().isHeadlessEnvironment() && PathUtilRt.getFileName(filePath).lastIndexOf('.') < 0) { diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java b/platform/configuration-store-impl/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java similarity index 100% rename from platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java rename to platform/configuration-store-impl/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java diff --git a/platform/core-api/src/com/intellij/lang/Language.java b/platform/core-api/src/com/intellij/lang/Language.java index 411523d7e6af..d941110520dc 100644 --- a/platform/core-api/src/com/intellij/lang/Language.java +++ b/platform/core-api/src/com/intellij/lang/Language.java @@ -56,6 +56,12 @@ public abstract class Language extends UserDataHolderBase { //noinspection HardCodedStringLiteral return "Language: ANY"; } + + @Nullable + @Override + public LanguageFileType getAssociatedFileType() { + return null; + } }; protected Language(@NotNull @NonNls String ID) { diff --git a/platform/core-api/src/com/intellij/openapi/command/undo/UndoUtil.java b/platform/core-api/src/com/intellij/openapi/command/undo/UndoUtil.java index e42d56cf58c3..316652f14f51 100644 --- a/platform/core-api/src/com/intellij/openapi/command/undo/UndoUtil.java +++ b/platform/core-api/src/com/intellij/openapi/command/undo/UndoUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,4 +49,8 @@ public class UndoUtil { public static void markVirtualFileForUndo(@NotNull Project project, @NotNull VirtualFile file) { CommandProcessor.getInstance().addAffectedFiles(project, file); } + + public static void disableUndoFor(@NotNull Document document) { + document.putUserData(UndoConstants.DONT_RECORD_UNDO, Boolean.TRUE); + } } diff --git a/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java b/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java index ead00534b0f8..6d51f846adc5 100644 --- a/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java +++ b/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.components; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -46,8 +47,15 @@ public class ServiceManager { if (instance == null) { instance = componentManager.getComponent(serviceClass); if (instance != null) { - LOG.warn(serviceClass.getName() + " requested as a service, but it is a component - convert it to a service or change call to " + - (componentManager == ApplicationManager.getApplication() ? "ApplicationManager.getApplication().getComponent()" : "project.getComponent()")); + Application app = ApplicationManager.getApplication(); + String message = serviceClass.getName() + " requested as a service, but it is a component - convert it to a service or change call to " + + (componentManager == app ? "ApplicationManager.getApplication().getComponent()" : "project.getComponent()"); + if (app.isUnitTestMode()) { + LOG.error(message); + } + else { + LOG.warn(message); + } } } return instance; diff --git a/platform/core-api/src/com/intellij/openapi/module/Module.java b/platform/core-api/src/com/intellij/openapi/module/Module.java index 6120cb0d49d3..a4b103af3815 100644 --- a/platform/core-api/src/com/intellij/openapi/module/Module.java +++ b/platform/core-api/src/com/intellij/openapi/module/Module.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ import org.jetbrains.annotations.Nullable; * @see ModuleManager#getModules() * @see ModuleComponent */ -public interface Module extends ComponentManager, AreaInstance, Disposable { +public interface Module extends ComponentManager, AreaInstance, Disposable, OptionManager { /** * The empty array of modules which cab be reused to avoid unnecessary allocations. */ @@ -78,30 +78,6 @@ public interface Module extends ComponentManager, AreaInstance, Disposable { boolean isLoaded(); - /** - * Sets a custom option for this module. - * - * @param optionName the name of the custom option. - * @param optionValue the value of the custom option. - */ - void setOption(@NotNull String optionName, @NotNull String optionValue); - - /** - * Removes a custom option from this module. - * - * @param optionName the name of the custom option. - */ - void clearOption(@NotNull String optionName); - - /** - * Gets the value of a custom option for this module. - * - * @param optionName the name of the custom option. - * @return the value of the custom option, or null if no value has been set. - */ - @Nullable - String getOptionValue(@NotNull String optionName); - /** * Returns module scope including sources and tests, excluding libraries and dependencies. * diff --git a/platform/core-api/src/com/intellij/openapi/module/ModuleServiceManager.java b/platform/core-api/src/com/intellij/openapi/module/ModuleServiceManager.java index 1c32e0eaec7f..ab234bacd290 100644 --- a/platform/core-api/src/com/intellij/openapi/module/ModuleServiceManager.java +++ b/platform/core-api/src/com/intellij/openapi/module/ModuleServiceManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,6 +17,7 @@ package com.intellij.openapi.module; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author yole @@ -25,7 +26,9 @@ public class ModuleServiceManager { private ModuleServiceManager() { } + @Nullable public static T getService(@NotNull Module module, @NotNull Class serviceClass) { - return (T)module.getPicoContainer().getComponentInstance(serviceClass); + //noinspection unchecked + return (T)module.getPicoContainer().getComponentInstance(serviceClass.getName()); } } \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/openapi/module/OptionManager.java b/platform/core-api/src/com/intellij/openapi/module/OptionManager.java new file mode 100644 index 000000000000..9beb80685b7a --- /dev/null +++ b/platform/core-api/src/com/intellij/openapi/module/OptionManager.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2015 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.openapi.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface OptionManager { + /** + * Removes a custom option from this module. + * + * @param key the name of the custom option. + */ + void clearOption(@NotNull String key); + + /** + * Sets a custom option for this module. + * + * @param key the name of the custom option. + * @param value the value of the custom option. + */ + void setOption(@NotNull String key, @NotNull String value); + + /** + * Gets the value of a custom option for this module. + * + * @param key the name of the custom option. + * @return the value of the custom option, or null if no value has been set. + */ + @Nullable + String getOptionValue(@NotNull String key); +} diff --git a/platform/core-api/src/com/intellij/openapi/project/DumbService.java b/platform/core-api/src/com/intellij/openapi/project/DumbService.java index efd18fbf8805..aa899f1c6674 100644 --- a/platform/core-api/src/com/intellij/openapi/project/DumbService.java +++ b/platform/core-api/src/com/intellij/openapi/project/DumbService.java @@ -265,6 +265,27 @@ public abstract class DumbService { */ public abstract boolean isAlternativeResolveEnabled(); + /** + * By default, dumb mode tasks (including indexing) are allowed in non-modal state only. The reason is that + * when some code shows a dialog, it probably does't expect that after the dialog is closed the dumb mode will be on. + * Therefore any dumb mode started within a dialog is considered a mistake, performed under modal progress and reported as an exception.

+ * + * If the dialog (e.g. Project Structure) starting background dumb mode is an expected situation, the dumb mode should be started inside the runnable + * passed to this method. This will suppress the exception and allow either modal or background indexing. Note that this will only affect the invocation time + * modality state, so showing other dialogs from within the runnable and starting dumb mode from them would still result in an assertion failure. + */ + public abstract void allowStartingDumbModeInside(@NotNull DumbModePermission permission, @NotNull Runnable runnable); + + /** + * Permits the dumb mode to start at a specific moment, either modally or in background. + * @see #allowStartingDumbModeInside(DumbModePermission, Runnable) + */ + public enum DumbModePermission { + MAY_START_MODAL, + MAY_START_BACKGROUND + } + + /** * @see #DUMB_MODE */ diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index 4a5cf11176a5..90785380f2f7 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -1183,8 +1183,9 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { MyTreeStructure treeStructure = new MyTreeStructure(newRoot, null); ShallowNodeComparator comparator = new MyComparator(getUserDataUnprotected(CUSTOM_COMPARATOR), treeStructure); - final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); - BlockSupportImpl.diffTrees(oldRoot, builder, comparator, treeStructure, indicator == null ? new EmptyProgressIndicator() : indicator); + ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); + BlockSupportImpl.diffTrees(oldRoot, builder, comparator, treeStructure, indicator == null ? new EmptyProgressIndicator() : indicator, + oldRoot.getText()); return diffLog; } diff --git a/platform/core-impl/src/com/intellij/mock/MockDumbService.java b/platform/core-impl/src/com/intellij/mock/MockDumbService.java index e97a9f64c7f3..12a1afa24b34 100644 --- a/platform/core-impl/src/com/intellij/mock/MockDumbService.java +++ b/platform/core-impl/src/com/intellij/mock/MockDumbService.java @@ -90,6 +90,11 @@ public class MockDumbService extends DumbService { return false; } + @Override + public void allowStartingDumbModeInside(@NotNull DumbModePermission permission, @NotNull Runnable runnable) { + runnable.run(); + } + public void smartInvokeLater(@NotNull final Runnable runnable) { runnable.run(); } diff --git a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java index 2bec610ebb76..d16019714a17 100644 --- a/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java @@ -43,26 +43,28 @@ import org.jetbrains.annotations.TestOnly; import org.picocontainer.*; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; -/** - * @author mike - */ public abstract class ComponentManagerImpl extends UserDataHolderBase implements ComponentManagerEx, Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.components.ComponentManager"); - private boolean myComponentsCreated; - private volatile MutablePicoContainer myPicoContainer; private volatile boolean myDisposed; private volatile boolean myDisposeCompleted; private MessageBus myMessageBus; + private final Map myNameToComponent = new THashMap(); + + @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") + private int myComponentConfigCount; + @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") + private int myInstantiatedComponentCount = -1; + + private final List myBaseComponents = new ArrayList(); + private final ComponentManager myParentComponentManager; - private ComponentsRegistry myComponentsRegistry; private final Condition myDisposedCondition = new Condition() { @Override public boolean value(final Object o) { @@ -85,29 +87,30 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements } protected final void init(@Nullable ProgressIndicator indicator, @Nullable Runnable componentsRegistered) { - try { - ArrayList componentConfigs = new ArrayList(); - registerComponents(componentConfigs); - myComponentsRegistry = new ComponentsRegistry(componentConfigs); - - if (componentsRegistered != null) { - componentsRegistered.run(); - } - - if (indicator != null) { - indicator.setIndeterminate(false); - } - createComponents(indicator); + List componentConfigs = getComponentConfigs(); + for (ComponentConfig config : componentConfigs) { + registerComponents(config); } - finally { - myComponentsCreated = true; + myComponentConfigCount = componentConfigs.size(); + + if (componentsRegistered != null) { + componentsRegistered.run(); } + + if (indicator != null) { + indicator.setIndeterminate(false); + } + createComponents(indicator); } protected void setProgressDuringInit(@NotNull ProgressIndicator indicator) { indicator.setFraction(getPercentageOfComponentsLoaded()); } + protected final double getPercentageOfComponentsLoaded() { + return ((double)myInstantiatedComponentCount) / myComponentConfigCount; + } + protected void createComponents(@Nullable ProgressIndicator indicator) { DefaultPicoContainer picoContainer = (DefaultPicoContainer)getPicoContainer(); for (ComponentAdapter componentAdapter : picoContainer.getComponentAdapters()) { @@ -131,8 +134,8 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return myMessageBus; } - public boolean isComponentsCreated() { - return myComponentsCreated; + public final boolean isComponentsCreated() { + return myComponentConfigCount != -1; } protected synchronized final void disposeComponents() { @@ -140,7 +143,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements myDisposed = true; // we cannot use list of component adapters because we must dispose in reverse order of creation - List components = myComponentsRegistry == null ? Collections.emptyList() : myComponentsRegistry.myBaseComponents; + List components = myBaseComponents; for (int i = components.size() - 1; i >= 0; i--) { try { components.get(i).disposeComponent(); @@ -150,7 +153,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements } } - myComponentsCreated = false; + myComponentConfigCount = -1; } @Nullable @@ -188,10 +191,6 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return ProgressManager.getInstance().getProgressIndicator(); } - protected final double getPercentageOfComponentsLoaded() { - return myComponentsRegistry.getPercentageOfComponentsLoaded(); - } - @Override public void initializeComponent(@NotNull Object component, boolean service) { } @@ -213,19 +212,12 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements public synchronized T registerComponentInstance(@NotNull Class componentKey, @NotNull T componentImplementation) { MutablePicoContainer picoContainer = getPicoContainer(); ComponentAdapter adapter = picoContainer.getComponentAdapter(componentKey); - if (adapter instanceof ComponentConfigComponentAdapter) { - ComponentConfigComponentAdapter componentAdapter = (ComponentConfigComponentAdapter)adapter; - Object oldInstance = componentAdapter.myInitializedComponentInstance; - // we don't update pluginId - method is test only - componentAdapter.myInitializedComponentInstance = componentImplementation; - return (T)oldInstance; - } - else { - // todo it seems, it is unrealistic (illegal) case - component must have our adapter - picoContainer.unregisterComponent(componentKey); - picoContainer.registerComponentInstance(componentKey, componentImplementation); - return null; - } + LOG.assertTrue(adapter instanceof ComponentConfigComponentAdapter); + ComponentConfigComponentAdapter componentAdapter = (ComponentConfigComponentAdapter)adapter; + Object oldInstance = componentAdapter.myInitializedComponentInstance; + // we don't update pluginId - method is test only + componentAdapter.myInitializedComponentInstance = componentImplementation; + return (T)oldInstance; } @Override @@ -275,11 +267,6 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return myParentComponentManager == null ? new DefaultPicoContainer() : new DefaultPicoContainer(myParentComponentManager.getPicoContainer()); } - @Override - public synchronized BaseComponent getComponent(@NotNull String name) { - return myComponentsRegistry.getComponentByName(name); - } - protected boolean isComponentSuitable(@Nullable Map options) { return options == null || (isComponentSuitableForOs(options.get("os")) && (!Boolean.parseBoolean(options.get("internal")) || ApplicationManager.getApplication().isInternal())); } @@ -311,7 +298,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements } @Override - public synchronized void dispose() { + public void dispose() { ApplicationManager.getApplication().assertIsDispatchThread(); myDisposeCompleted = true; @@ -320,7 +307,6 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements myMessageBus = null; } - myComponentsRegistry = null; myPicoContainer = null; } @@ -329,7 +315,9 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return myDisposed; } - private void registerComponents(@NotNull ArrayList componentConfigs) { + @NotNull + private List getComponentConfigs() { + ArrayList componentConfigs = new ArrayList(); boolean isDefaultProject = this instanceof Project && ((Project)this).isDefault(); boolean headless = ApplicationManager.getApplication().isHeadlessEnvironment(); for (IdeaPluginDescriptor plugin : PluginManagerCore.getPlugins()) { @@ -346,28 +334,29 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements } } } + return componentConfigs; } - @NotNull // used in upsource + // used in upsource + @NotNull public ComponentConfig[] getMyComponentConfigsFromDescriptor(@NotNull IdeaPluginDescriptor plugin) { return plugin.getAppComponents(); } protected void bootstrapPicoContainer(@NotNull String name) { - myPicoContainer = createPicoContainer(); + MutablePicoContainer picoContainer = createPicoContainer(); + myPicoContainer = picoContainer; myMessageBus = MessageBusFactory.newMessageBus(name, myParentComponentManager == null ? null : myParentComponentManager.getMessageBus()); - final MutablePicoContainer picoContainer = getPicoContainer(); picoContainer.registerComponentInstance(MessageBus.class, myMessageBus); } - - protected ComponentManager getParentComponentManager() { + protected final ComponentManager getParentComponentManager() { return myParentComponentManager; } - protected final int getComponentConfigurationsSize() { - return myComponentsRegistry.myComponentConfigCount; + protected final int getComponentConfigCount() { + return myComponentConfigCount; } @Nullable @@ -393,7 +382,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements @Override @NotNull - public Condition getDisposed() { + public final Condition getDisposed() { return myDisposedCondition; } @@ -409,81 +398,66 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements return LOG.isDebugEnabled(); } - private class ComponentsRegistry { - private final Map myNameToComponent = new THashMap(); - private final int myComponentConfigCount; - private int myInstantiatedComponentCount; - private final List myBaseComponents = new ArrayList(); - - public ComponentsRegistry(@NotNull List componentConfigs) { - for (ComponentConfig config : componentConfigs) { - registerComponents(config); - } - myComponentConfigCount = componentConfigs.size(); - } - - private void registerComponents(@NotNull ComponentConfig config) { - ClassLoader loader = config.getClassLoader(); - - try { - final Class interfaceClass = Class.forName(config.getInterfaceClass(), true, loader); - final Class implementationClass = Comparing.equal(config.getInterfaceClass(), config.getImplementationClass()) ? - interfaceClass : StringUtil.isEmpty(config.getImplementationClass()) ? null : Class.forName(config.getImplementationClass(), true, loader); - MutablePicoContainer picoContainer = getPicoContainer(); - if (config.options != null && Boolean.parseBoolean(config.options.get("overrides"))) { - ComponentAdapter oldAdapter = picoContainer.getComponentAdapterOfType(interfaceClass); - if (oldAdapter == null) { - throw new RuntimeException(config + " does not override anything"); - } - picoContainer.unregisterComponent(oldAdapter.getComponentKey()); - } - // implementationClass == null means we want to unregister this component - if (implementationClass != null) { - picoContainer.registerComponent(new ComponentConfigComponentAdapter(interfaceClass, implementationClass, config.getPluginId(), config.options != null && Boolean.parseBoolean(config.options.get("workspace")))); + private void registerComponents(@NotNull ComponentConfig config) { + ClassLoader loader = config.getClassLoader(); + try { + final Class interfaceClass = Class.forName(config.getInterfaceClass(), true, loader); + final Class implementationClass = Comparing.equal(config.getInterfaceClass(), config.getImplementationClass()) + ? + interfaceClass + : StringUtil.isEmpty(config.getImplementationClass()) ? null : Class.forName(config.getImplementationClass(), true, loader); + MutablePicoContainer picoContainer = getPicoContainer(); + if (config.options != null && Boolean.parseBoolean(config.options.get("overrides"))) { + ComponentAdapter oldAdapter = picoContainer.getComponentAdapterOfType(interfaceClass); + if (oldAdapter == null) { + throw new RuntimeException(config + " does not override anything"); } + picoContainer.unregisterComponent(oldAdapter.getComponentKey()); } - catch (Throwable t) { - handleInitComponentError(t, null, config.getPluginId()); + // implementationClass == null means we want to unregister this component + if (implementationClass != null) { + picoContainer.registerComponent(new ComponentConfigComponentAdapter(interfaceClass, implementationClass, config.getPluginId(), + config.options != null && Boolean.parseBoolean(config.options.get("workspace")))); } } - - private double getPercentageOfComponentsLoaded() { - return ((double)myInstantiatedComponentCount) / myComponentConfigCount; - } - - private void registerComponentInstance(@NotNull Object instance) { - myInstantiatedComponentCount++; - - if (instance instanceof com.intellij.openapi.Disposable) { - Disposer.register(ComponentManagerImpl.this, (com.intellij.openapi.Disposable)instance); - } - - if (!(instance instanceof BaseComponent)) { - return; - } - - BaseComponent baseComponent = (BaseComponent)instance; - String componentName = baseComponent.getComponentName(); - if (myNameToComponent.containsKey(componentName)) { - BaseComponent loadedComponent = myNameToComponent.get(componentName); - // component may have been already loaded by PicoContainer, so fire error only if components are really different - if (!instance.equals(loadedComponent)) { - LOG.error("Component name collision: " + componentName + " " + loadedComponent.getClass() + " and " + instance.getClass()); - } - } - else { - myNameToComponent.put(componentName, baseComponent); - } - - myBaseComponents.add(baseComponent); - } - - private BaseComponent getComponentByName(final String name) { - return myNameToComponent.get(name); + catch (Throwable t) { + handleInitComponentError(t, null, config.getPluginId()); } } - private class ComponentConfigComponentAdapter extends ConstructorInjectionComponentAdapter { + private void registerComponentInstance(@NotNull Object instance) { + myInstantiatedComponentCount++; + + if (instance instanceof com.intellij.openapi.Disposable) { + Disposer.register(this, (com.intellij.openapi.Disposable)instance); + } + + if (!(instance instanceof BaseComponent)) { + return; + } + + BaseComponent baseComponent = (BaseComponent)instance; + String componentName = baseComponent.getComponentName(); + if (myNameToComponent.containsKey(componentName)) { + BaseComponent loadedComponent = myNameToComponent.get(componentName); + // component may have been already loaded by PicoContainer, so fire error only if components are really different + if (!instance.equals(loadedComponent)) { + LOG.error("Component name collision: " + componentName + " " + loadedComponent.getClass() + " and " + instance.getClass()); + } + } + else { + myNameToComponent.put(componentName, baseComponent); + } + + myBaseComponents.add(baseComponent); + } + + @Override + public synchronized BaseComponent getComponent(@NotNull String name) { + return myNameToComponent.get(name); + } + + private final class ComponentConfigComponentAdapter extends ConstructorInjectionComponentAdapter { private final PluginId myPluginId; private volatile Object myInitializedComponentInstance; private boolean myInitializing; @@ -528,7 +502,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements try { myInitializing = true; - myComponentsRegistry.registerComponentInstance(instance); + registerComponentInstance(instance); ProgressIndicator indicator = getProgressIndicator(); if (indicator != null) { diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index df2d220861fe..6aee3794da28 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -66,6 +66,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { private volatile LineSet myLineSet; private volatile ImmutableText myText; private volatile SoftReference myTextString; + private volatile FrozenDocument myFrozen; private boolean myIsReadOnly = false; private volatile boolean isStripTrailingSpacesEnabled = true; @@ -636,6 +637,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { @Override public void clearLineModificationFlags() { myLineSet = getLineSet().clearModificationFlags(); + myFrozen = null; } void clearLineModificationFlagsExcept(@NotNull int[] caretLines) { @@ -651,6 +653,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { lineSet = lineSet.setModified(modifiedLines.get(i)); } myLineSet = lineSet; + myFrozen = null; } private void updateText(@NotNull ImmutableText newText, @@ -730,6 +733,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { if (LOG.isDebugEnabled()) LOG.debug(event.toString()); myLineSet = getLineSet().update(prevText, event.getOffset(), event.getOffset() + event.getOldLength(), event.getNewFragment(), event.isWholeTextReplaced()); + myFrozen = null; if (myTabTrackingRequestors > 0) { updateMightContainTabs(event.getNewFragment()); } @@ -1069,4 +1073,19 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { myMightContainTabs = StringUtil.contains(text, 0, text.length(), '\t'); } } + + @NotNull + public FrozenDocument freeze() { + FrozenDocument frozen = myFrozen; + if (frozen == null) { + synchronized (myLineSetLock) { + frozen = myFrozen; + if (frozen == null) { + frozen = new FrozenDocument(myText, getLineSet(), myModificationStamp, SoftReference.dereference(myTextString)); + } + } + } + return frozen; + } + } diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/FrozenDocument.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/FrozenDocument.java new file mode 100644 index 000000000000..0da071977a5b --- /dev/null +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/FrozenDocument.java @@ -0,0 +1,352 @@ +/* + * Copyright 2000-2015 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.openapi.editor.impl; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.event.DocumentListener; +import com.intellij.openapi.editor.ex.DocumentEx; +import com.intellij.openapi.editor.ex.EditReadOnlyListener; +import com.intellij.openapi.editor.ex.LineIterator; +import com.intellij.openapi.editor.ex.RangeMarkerEx; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.reference.SoftReference; +import com.intellij.util.Processor; +import com.intellij.util.text.CharArrayUtil; +import com.intellij.util.text.ImmutableText; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.beans.PropertyChangeListener; +import java.util.Collections; +import java.util.List; + +/** + * @author peter + */ +public class FrozenDocument implements DocumentEx { + private final ImmutableText myText; + private final LineSet myLineSet; + private final long myStamp; + private volatile SoftReference myTextString; + + public FrozenDocument(@NotNull ImmutableText text, @NotNull LineSet lineSet, long stamp, @Nullable String textString) { + myText = text; + myLineSet = lineSet; + myStamp = stamp; + myTextString = textString == null ? null : new SoftReference(textString); + } + + @Override + public void setStripTrailingSpacesEnabled(boolean isEnabled) { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public LineIterator createLineIterator() { + return myLineSet.createIterator(); + } + + @Override + public void setModificationStamp(long modificationStamp) { + throw new UnsupportedOperationException(); + } + + @Override + public void addEditReadOnlyListener(@NotNull EditReadOnlyListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeEditReadOnlyListener(@NotNull EditReadOnlyListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void replaceText(@NotNull CharSequence chars, long newModificationStamp) { + throw new UnsupportedOperationException(); + } + + @Override + public void moveText(int srcStart, int srcEnd, int dstOffset) { + throw new UnsupportedOperationException(); + } + + @Override + public int getListenersCount() { + return 0; + } + + @Override + public void suppressGuardedExceptions() { + throw new UnsupportedOperationException(); + } + + @Override + public void unSuppressGuardedExceptions() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isInEventsHandling() { + return false; + } + + @Override + public void clearLineModificationFlags() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeRangeMarker(@NotNull RangeMarkerEx rangeMarker) { + throw new UnsupportedOperationException(); + } + + @Override + public void registerRangeMarker(@NotNull RangeMarkerEx rangeMarker, + int start, + int end, + boolean greedyToLeft, + boolean greedyToRight, + int layer) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isInBulkUpdate() { + return false; + } + + @Override + public void setInBulkUpdate(boolean value) { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public List getGuardedBlocks() { + return Collections.emptyList(); + } + + @Override + public boolean processRangeMarkers(@NotNull Processor processor) { + return true; + } + + @Override + public boolean processRangeMarkersOverlappingWith(int start, int end, @NotNull Processor processor) { + return true; + } + + @NotNull + @Override + public String getText() { + String s = SoftReference.dereference(myTextString); + if (s == null) { + myTextString = new SoftReference(s = myText.toString()); + } + return s; + } + + @NotNull + @Override + public String getText(@NotNull TextRange range) { + return myText.subSequence(range.getStartOffset(), range.getEndOffset()).toString(); + } + + @NotNull + @Override + public CharSequence getCharsSequence() { + return myText; + } + + @NotNull + @Override + public CharSequence getImmutableCharSequence() { + return myText; + } + + @NotNull + @Override + public char[] getChars() { + return CharArrayUtil.fromSequence(myText); + } + + @Override + public int getTextLength() { + return myText.length(); + } + + @Override + public int getLineCount() { + return myLineSet.getLineCount(); + } + + @Override + public int getLineNumber(int offset) { + return myLineSet.findLineIndex(offset); + } + + @Override + public int getLineStartOffset(int line) { + return myLineSet.getLineStart(line); + } + + @Override + public int getLineEndOffset(int line) { + return myLineSet.getLineEnd(line); + } + + @Override + public void insertString(int offset, @NotNull CharSequence s) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteString(int startOffset, int endOffset) { + throw new UnsupportedOperationException(); + } + + @Override + public void replaceString(int startOffset, int endOffset, @NotNull CharSequence s) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isWritable() { + return false; + } + + @Override + public long getModificationStamp() { + return myStamp; + } + + @Override + public void fireReadOnlyModificationAttempt() { + throw new UnsupportedOperationException(); + } + + @Override + public void addDocumentListener(@NotNull DocumentListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void addDocumentListener(@NotNull DocumentListener listener, @NotNull Disposable parentDisposable) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeDocumentListener(@NotNull DocumentListener listener) { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public RangeMarker createRangeMarker(int startOffset, int endOffset) { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public RangeMarker createRangeMarker(int startOffset, int endOffset, boolean surviveOnExternalChange) { + throw new UnsupportedOperationException(); + } + + @Override + public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void setReadOnly(boolean isReadOnly) { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public RangeMarker createGuardedBlock(int startOffset, int endOffset) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeGuardedBlock(@NotNull RangeMarker block) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public RangeMarker getOffsetGuard(int offset) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public RangeMarker getRangeGuard(int start, int end) { + throw new UnsupportedOperationException(); + } + + @Override + public void startGuardedBlockChecking() { + throw new UnsupportedOperationException(); + } + + @Override + public void stopGuardedBlockChecking() { + throw new UnsupportedOperationException(); + } + + @Override + public void setCyclicBufferSize(int bufferSize) { + throw new UnsupportedOperationException(); + } + + @Override + public void setText(@NotNull CharSequence text) { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public RangeMarker createRangeMarker(@NotNull TextRange textRange) { + throw new UnsupportedOperationException(); + } + + @Override + public int getLineSeparatorLength(int line) { + return myLineSet.getSeparatorLength(line); + } + + @Nullable + @Override + public T getUserData(@NotNull Key key) { + throw new UnsupportedOperationException(); + } + + @Override + public void putUserData(@NotNull Key key, @Nullable T value) { + throw new UnsupportedOperationException(); + } + +} diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java index fb1c7d06d5cb..7573217a5843 100644 --- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java +++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java @@ -283,7 +283,8 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { TextRange changedPsiRange = DocumentCommitProcessor.getChangedPsiRange(file, treeElement, newText); if (changedPsiRange == null) return; - final DiffLog log = BlockSupport.getInstance(myProject).reparseRange(file, changedPsiRange, newText, new EmptyProgressIndicator()); + final DiffLog log = BlockSupport.getInstance(myProject).reparseRange(file, changedPsiRange, newText, new EmptyProgressIndicator(), + treeElement.getText()); synchronizer.setIgnorePsiEvents(true); try { CodeStyleManager.getInstance(file.getProject()).performActionWithFormatterDisabled(new Runnable() { diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java index fed8191cd716..17a5c94f3c7d 100644 --- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java @@ -19,8 +19,11 @@ package com.intellij.psi; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.NullableComputable; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; @@ -34,6 +37,7 @@ import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubTree; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IStubFileElementType; +import com.intellij.psi.util.PsiModificationTracker; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -436,7 +440,8 @@ public abstract class PsiAnchor { private final int myIndex; private final Language myLanguage; private final IStubElementType myElementType; - private final int myCreationModCount; + private final short myCreationModCount; + private final short myCreationStamp; private StubIndexReference(@NotNull final PsiFile file, final int index, @NotNull Language language, IStubElementType elementType) { myLanguage = language; @@ -444,7 +449,16 @@ public abstract class PsiAnchor { myVirtualFile = file.getVirtualFile(); myProject = file.getProject(); myIndex = index; - myCreationModCount = (int)file.getManager().getModificationTracker().getModificationCount(); + myCreationModCount = getModCount(); + myCreationStamp = (short)file.getModificationStamp(); + } + + private short getModCount() { + final PsiModificationTracker tracker = PsiManager.getInstance(getProject()).getModificationTracker(); + if (myVirtualFile.getName().endsWith(".java")) { + return (short)tracker.getJavaStructureModificationCount(); + } + return (short)tracker.getModificationCount(); } @Override @@ -474,19 +488,35 @@ public abstract class PsiAnchor { } public String diagnoseNull() { + final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiFile compute() { + return getFile(); + } + }); try { PsiElement element = ApplicationManager.getApplication().runReadAction(new NullableComputable() { @Override public PsiElement compute() { - return restoreFromStubIndex((PsiFileWithStubSupport)getFile(), myIndex, myElementType, true); + return restoreFromStubIndex((PsiFileWithStubSupport)file, myIndex, myElementType, true); } }); return "No diagnostics, element=" + element + "@" + (element == null ? 0 : System.identityHashCode(element)); } catch (AssertionError e) { - return e.getMessage() + - "; current modCount=" + PsiManager.getInstance(getProject()).getModificationTracker().getModificationCount() + - "; creation modCount=" + myCreationModCount; + String msg = e.getMessage(); + msg += "\n current (java)modCount=" + getModCount() + "; creation (java)modCount=" + myCreationModCount; + if (file == null) { + msg += "\n no PSI file"; + } else { + msg += "\n current file stamp=" + (short)file.getModificationStamp() + "; creation file stamp=" + myCreationStamp; + } + final Document document = FileDocumentManager.getInstance().getCachedDocument(myVirtualFile); + if (document != null) { + msg += "\n committed=" + PsiDocumentManager.getInstance(myProject).isCommitted(document); + msg += "\n saved=" + !FileDocumentManager.getInstance().isDocumentUnsaved(document); + } + return msg; } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java index f7a02b786e54..de29abbbb4f1 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitProcessor.java @@ -62,6 +62,7 @@ public abstract class DocumentCommitProcessor { // when failed it's canceled @NotNull public final ProgressIndicator indicator; // progress to commit this doc under. @NotNull public final Object reason; + private final CharSequence myLastCommittedText; public boolean removed; // task marked as removed, should be ignored. public CommitTask(@NotNull Document document, @@ -72,6 +73,7 @@ public abstract class DocumentCommitProcessor { this.project = project; this.indicator = indicator; this.reason = reason; + myLastCommittedText = PsiDocumentManager.getInstance(project).getLastCommittedText(document); } @NonNls @@ -121,7 +123,7 @@ public abstract class DocumentCommitProcessor { } BlockSupport blockSupport = BlockSupport.getInstance(file.getProject()); - final DiffLog diffLog = blockSupport.reparseRange(file, changedPsiRange, chars, task.indicator); + final DiffLog diffLog = blockSupport.reparseRange(file, changedPsiRange, chars, task.indicator, task.myLastCommittedText); return new Processor() { @Override @@ -243,7 +245,8 @@ public abstract class DocumentCommitProcessor { file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE); try { BlockSupport blockSupport = BlockSupport.getInstance(file.getProject()); - final DiffLog diffLog = blockSupport.reparseRange(file, new TextRange(0, documentText.length()), documentText, createProgressIndicator()); + final DiffLog diffLog = blockSupport.reparseRange(file, new TextRange(0, documentText.length()), documentText, createProgressIndicator(), + myTreeElementBeingReparsedSoItWontBeCollected.getText()); doActualPsiChange(file, diffLog); if (myTreeElementBeingReparsedSoItWontBeCollected.getTextLength() != document.getTextLength()) { diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java index bcefda23af62..3c39840c8500 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/BlockSupportImpl.java @@ -79,12 +79,13 @@ public class BlockSupportImpl extends BlockSupport { public DiffLog reparseRange(@NotNull final PsiFile file, @NotNull TextRange changedPsiRange, @NotNull final CharSequence newFileText, - @NotNull final ProgressIndicator indicator) { + @NotNull final ProgressIndicator indicator, + @NotNull CharSequence lastCommittedText) { final PsiFileImpl fileImpl = (PsiFileImpl)file; final Couple reparseableRoots = findReparseableRoots(fileImpl, changedPsiRange, newFileText); return reparseableRoots != null - ? mergeTrees(fileImpl, reparseableRoots.first, reparseableRoots.second, indicator) + ? mergeTrees(fileImpl, reparseableRoots.first, reparseableRoots.second, indicator, lastCommittedText) : makeFullParse(fileImpl.getTreeElement(), newFileText, newFileText.length(), fileImpl, indicator); } @@ -205,7 +206,7 @@ public class BlockSupportImpl extends BlockSupport { final FileElement newFileElement = (FileElement)newFile.getNode(); final FileElement oldFileElement = (FileElement)fileImpl.getNode(); - DiffLog diffLog = mergeTrees(fileImpl, oldFileElement, newFileElement, indicator); + DiffLog diffLog = mergeTrees(fileImpl, oldFileElement, newFileElement, indicator, oldFileElement.getText()); ((PsiManagerEx)fileImpl.getManager()).getFileManager().setViewProvider(lightFile, null); return diffLog; @@ -258,7 +259,8 @@ public class BlockSupportImpl extends BlockSupport { public static DiffLog mergeTrees(@NotNull final PsiFileImpl fileImpl, @NotNull final ASTNode oldRoot, @NotNull final ASTNode newRoot, - @NotNull ProgressIndicator indicator) { + @NotNull ProgressIndicator indicator, + @NotNull CharSequence lastCommittedText) { if (newRoot instanceof FileElement) { ((FileElement)newRoot).setCharTable(fileImpl.getTreeElement().getCharTable()); } @@ -285,7 +287,7 @@ public class BlockSupportImpl extends BlockSupport { final ASTStructure treeStructure = createInterruptibleASTStructure(newRoot, indicator); DiffLog diffLog = new DiffLog(); - diffTrees(oldRoot, diffLog, comparator, treeStructure, indicator); + diffTrees(oldRoot, diffLog, comparator, treeStructure, indicator, lastCommittedText); return diffLog; } @@ -293,9 +295,10 @@ public class BlockSupportImpl extends BlockSupport { @NotNull final DiffTreeChangeBuilder builder, @NotNull final ShallowNodeComparator comparator, @NotNull final FlyweightCapableTreeStructure newTreeStructure, - @NotNull ProgressIndicator indicator) { + @NotNull ProgressIndicator indicator, + @NotNull CharSequence lastCommittedText) { TreeUtil.ensureParsedRecursivelyCheckingProgress(oldRoot, indicator); - DiffTree.diff(createInterruptibleASTStructure(oldRoot, indicator), newTreeStructure, comparator, builder); + DiffTree.diff(createInterruptibleASTStructure(oldRoot, indicator), newTreeStructure, comparator, builder, lastCommittedText); } private static ASTStructure createInterruptibleASTStructure(@NotNull final ASTNode oldRoot, @NotNull final ProgressIndicator indicator) { diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java index 67add6d2a0a2..cabed42bb69d 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java @@ -33,7 +33,6 @@ import com.intellij.util.diff.DiffTreeChangeBuilder; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -175,7 +174,7 @@ public class DiffLog implements DiffTreeChangeBuilder { private InsertEntry(@NotNull ASTNode oldParent, @NotNull ASTNode newNode, int pos) { assert oldParent instanceof CompositeElement : oldParent; assert pos>=0 : pos; - assert pos<=oldParent.getChildren(null).length : pos + " "+ Arrays.toString(oldParent.getChildren(null)); + //assert pos<=oldParent.getChildren(null).length : pos + " "+ Arrays.toString(oldParent.getChildren(null)); myOldParent = oldParent; myNewNode = newNode; myPos = pos; diff --git a/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java b/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java index 581352cea35f..213b617ad297 100644 --- a/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java +++ b/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -41,7 +41,8 @@ public abstract class BlockSupport { public abstract DiffLog reparseRange(@NotNull PsiFile file, @NotNull TextRange changedPsiRange, @NotNull CharSequence newText, - @NotNull ProgressIndicator progressIndicator) throws IncorrectOperationException; + @NotNull ProgressIndicator progressIndicator, + @NotNull CharSequence lastCommittedText) throws IncorrectOperationException; public static final Key DO_NOT_REPARSE_INCREMENTALLY = Key.create("DO_NOT_REPARSE_INCREMENTALLY"); public static final Key TREE_TO_BE_REPARSED = Key.create("TREE_TO_BE_REPARSED"); diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties index bd6a05ce4668..bc068a158b75 100644 --- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties +++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties @@ -2,7 +2,7 @@ import.title=Import {0} Projects module.type.title={0} Module module.type.description={0} modules are used for developing JVM-based applications with dependencies managed by {0} -orphan.modules.text=The modules below are not backed by {0} anymore.
Check those to be removed from the ide project too: +orphan.modules.text=The modules below are not imported from {0} anymore.
Check those to be removed from the ide project too: # Settings. setting.type.location.deduced={0} location is deduced diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java index 4d4245648c15..df5401bfeaae 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java index 15854c86b644..bba9f84b0cb1 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -56,7 +56,6 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java index b02ae52faf34..932fbfb95d57 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java @@ -1,9 +1,10 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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 diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/ExternalSystemOpenProjectStructureAction.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/ExternalSystemSelectProjectDataToImportAction.java similarity index 76% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/ExternalSystemOpenProjectStructureAction.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/ExternalSystemSelectProjectDataToImportAction.java index 9c83c49c2463..0528ca44fe40 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/ExternalSystemOpenProjectStructureAction.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/action/ExternalSystemSelectProjectDataToImportAction.java @@ -21,7 +21,7 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.project.ProjectData; import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager; -import com.intellij.openapi.externalSystem.service.ui.ExternalProjectStructureDialog; +import com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelectorDialog; import com.intellij.openapi.externalSystem.view.ExternalSystemNode; import com.intellij.openapi.externalSystem.view.ProjectNode; import com.intellij.openapi.project.Project; @@ -33,14 +33,7 @@ import java.util.List; * @author Vladislav.Soroka * @since 5/12/2015 */ -public class ExternalSystemOpenProjectStructureAction extends ExternalSystemAction { - - public ExternalSystemOpenProjectStructureAction() { - //super(AbstractExternalEntityData.class); - //getTemplatePresentation().setText(ExternalSystemBundle.message("action.detach.external.project.text", "external")); - //getTemplatePresentation().setDescription(ExternalSystemBundle.message("action.detach.external.project.description")); - //getTemplatePresentation().setIcon(SystemInfoRt.isMac ? AllIcons.ToolbarDecorator.Mac.Remove : AllIcons.ToolbarDecorator.Remove); - } +public class ExternalSystemSelectProjectDataToImportAction extends ExternalSystemAction { @Override public void actionPerformed(AnActionEvent e) { @@ -65,9 +58,9 @@ public class ExternalSystemOpenProjectStructureAction extends ExternalSystemActi ProjectDataManager.getInstance().getExternalProjectData(project, projectSystemId, projectData.getLinkedExternalProjectPath()); } - final ExternalProjectStructureDialog dialog; + final ExternalProjectDataSelectorDialog dialog; if (projectInfo != null) { - dialog = new ExternalProjectStructureDialog(project, projectInfo, externalSystemNode != null ? externalSystemNode.getData() : null); + dialog = new ExternalProjectDataSelectorDialog(project, projectInfo, externalSystemNode != null ? externalSystemNode.getData() : null); dialog.showAndGet(); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemBeforeRunTaskProvider.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemBeforeRunTaskProvider.java index f3ad64c7b08b..9394a8d636a1 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemBeforeRunTaskProvider.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemBeforeRunTaskProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/PlatformFacadeImpl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/PlatformFacadeImpl.java index 65b60a42625d..f84010a8d729 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/PlatformFacadeImpl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/PlatformFacadeImpl.java @@ -65,7 +65,10 @@ public class PlatformFacadeImpl implements PlatformFacade { @Override public Module newModule(Project project, @NotNull @NonNls String filePath, String moduleTypeId) { final ModuleManager moduleManager = ModuleManager.getInstance(project); - return moduleManager.newModule(filePath, moduleTypeId); + Module module = moduleManager.newModule(filePath, moduleTypeId); + // set module type id explicitly otherwise it can not be set if there is an existing module (with the same filePath) and w/o 'type' attribute + module.setOption(Module.ELEMENT_TYPE, moduleTypeId); + return module; } @Override diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java index 7e04d02d4055..68fc46b8d802 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java index a5024b071f03..8f63cd1237c1 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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.openapi.externalSystem.service.project.manage; import com.intellij.openapi.application.Application; @@ -19,9 +34,7 @@ import com.intellij.openapi.roots.*; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CheckBoxList; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.components.JBScrollPane; @@ -38,14 +51,13 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; -import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; /** - * Encapsulates functionality of importing gradle module to the intellij project. + * Encapsulates functionality of importing external system module to the intellij project. * * @author Denis Zhdanov * @since 2/7/12 2:49 PM @@ -103,10 +115,9 @@ public class ModuleDataService extends AbstractProjectDataService> toCreate, - @NotNull final Project project, - @NotNull final PlatformFacade platformFacade) { - removeExistingModulesConfigs(toCreate, project); + private static void createModules(@NotNull final Collection> toCreate, + @NotNull final Project project, + @NotNull final PlatformFacade platformFacade) { Application application = ApplicationManager.getApplication(); final Map, Module> moduleMappings = ContainerUtilRt.newHashMap(); application.runWriteAction(new Runnable() { @@ -170,31 +181,6 @@ public class ModuleDataService extends AbstractProjectDataService> nodes, @NotNull final Project project) { - if (nodes.isEmpty()) { - return; - } - ExternalSystemApiUtil.executeProjectChangeAction(true, new DisposeAwareProjectChange(project) { - @Override - public void execute() { - LocalFileSystem fileSystem = LocalFileSystem.getInstance(); - for (DataNode node : nodes) { - // Remove existing '*.iml' file if necessary. - ModuleData data = node.getData(); - VirtualFile file = fileSystem.refreshAndFindFileByPath(data.getModuleFilePath()); - if (file != null) { - try { - file.delete(this); - } - catch (IOException e) { - LOG.warn("Can't remove existing module config file at '" + data.getModuleFilePath() + "'"); - } - } - } - } - }); - } - private static void syncPaths(@NotNull Module module, @NotNull PlatformFacade platformFacade, @NotNull ModuleData data) { ModifiableRootModel modifiableModel = platformFacade.getModuleModifiableModel(module); CompilerModuleExtension extension = modifiableModel.getModuleExtension(CompilerModuleExtension.class); @@ -370,6 +356,11 @@ public class ModuleDataService extends AbstractProjectDataService -

+ diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectStructureDialog.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectDataSelectorDialog.java similarity index 95% rename from platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectStructureDialog.java rename to platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectDataSelectorDialog.java index 907cec5d8512..0257a368513d 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectStructureDialog.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ui/ExternalProjectDataSelectorDialog.java @@ -33,7 +33,7 @@ import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataMan import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange; import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; -import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.ui.DialogWrapper; @@ -69,7 +69,7 @@ import java.util.Set; * @author Vladislav.Soroka * @since 5/12/2015 */ -public class ExternalProjectStructureDialog extends DialogWrapper { +public class ExternalProjectDataSelectorDialog extends DialogWrapper { private static final int MAX_PATH_LENGTH = 50; private static final Set> DATA_KEYS = ContainerUtil.set(ProjectKeys.PROJECT, ProjectKeys.MODULE); @@ -107,14 +107,14 @@ public class ExternalProjectStructureDialog extends DialogWrapper { private boolean myShowSelectedRowsOnly; private int myModulesCount; - public ExternalProjectStructureDialog(@NotNull Project project, - @NotNull ExternalProjectInfo projectInfo) { + public ExternalProjectDataSelectorDialog(@NotNull Project project, + @NotNull ExternalProjectInfo projectInfo) { this(project, projectInfo, null); } - public ExternalProjectStructureDialog(@NotNull Project project, - @NotNull ExternalProjectInfo projectInfo, - @Nullable Object preselectedNodeDataObject) { + public ExternalProjectDataSelectorDialog(@NotNull Project project, + @NotNull ExternalProjectInfo projectInfo, + @Nullable Object preselectedNodeDataObject) { super(project, true); myProject = project; myIgnorableKeys = getIgnorableKeys(); @@ -212,15 +212,19 @@ public class ExternalProjectStructureDialog extends DialogWrapper { ExternalSystemApiUtil.executeProjectChangeAction(true, new DisposeAwareProjectChange(myProject) { @Override public void execute() { - ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() { - @Override - public void run() { - ServiceManager.getService(ProjectDataManager.class).importData(projectStructure, myProject, true); - } - }); + DumbService.getInstance(myProject).allowStartingDumbModeInside( + DumbService.DumbModePermission.MAY_START_BACKGROUND, new Runnable() { + public void run() { + ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() { + @Override + public void run() { + ServiceManager.getService(ProjectDataManager.class).importData(projectStructure, myProject, true); + } + }); + } + }); } }); - //ExternalSystemUtil.scheduleExternalViewStructureUpdate(myProject, myProjectInfo.getProjectSystemId()); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index 85f9f9cf8d2d..625238744756 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -53,7 +53,6 @@ import com.intellij.openapi.externalSystem.service.project.PlatformFacade; import com.intellij.openapi.externalSystem.service.project.ProjectStructureHelper; import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager; import com.intellij.openapi.externalSystem.service.project.manage.ExternalSystemTaskActivator; -import com.intellij.openapi.externalSystem.service.project.manage.ModuleDataService; import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager; import com.intellij.openapi.externalSystem.service.settings.ExternalSystemConfigLocator; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; @@ -70,8 +69,10 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.StandardFileSystems; @@ -82,28 +83,22 @@ import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.openapi.wm.ex.ToolWindowManagerEx; import com.intellij.openapi.wm.impl.ToolWindowImpl; -import com.intellij.ui.CheckBoxList; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.components.JBScrollPane; import com.intellij.util.Consumer; import com.intellij.util.DisposeAwareRunnable; -import com.intellij.util.Function; -import com.intellij.util.SmartList; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; -import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.UIUtil; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; -import java.awt.*; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Set; import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.executeOnEdtUnderWriteAction; diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java index 58a4ac8bdef2..a49845557889 100644 --- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java +++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -44,7 +44,10 @@ import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.impl.compiler.ArtifactCompileScope; -import com.intellij.testFramework.*; +import com.intellij.testFramework.CompilerTester; +import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.PsiTestUtil; +import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import com.intellij.util.ArrayUtil; @@ -310,7 +313,7 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase { protected Module createModule(final String name, final ModuleType type) throws IOException { return new WriteCommandAction(myProject) { @Override - protected void run(Result moduleResult) throws Throwable { + protected void run(@NotNull Result moduleResult) throws Throwable { VirtualFile f = createProjectSubFile(name + "/" + name + ".iml"); Module module = ModuleManager.getInstance(myProject).newModule(f.getPath(), type.getId()); PsiTestUtil.addContentRoot(module, f.getParent()); @@ -329,7 +332,7 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase { if (f == null) { f = new WriteAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { VirtualFile res = dir.createChildData(null, configFileName); result.setResult(res); } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java index cfc2e27a8179..d8f61a9535a7 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionService.java @@ -20,12 +20,12 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.util.Key; import com.intellij.psi.Weigher; import com.intellij.util.Consumer; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; /** * For completion FAQ, see {@link CompletionContributor}. @@ -103,11 +103,9 @@ public abstract class CompletionService { * The main method that is invoked to collect all the completion variants * @param parameters Parameters specifying current completion environment * @param consumer This consumer will directly add lookup elements to the lookup - * @return all suitable lookup elements */ - @NotNull - public LookupElement[] performCompletion(final CompletionParameters parameters, final Consumer consumer) { - final Collection lookupSet = new LinkedHashSet(); + public void performCompletion(final CompletionParameters parameters, final Consumer consumer) { + final Set lookupSet = ContainerUtil.newConcurrentSet(); getVariantsFromContributors(parameters, null, new Consumer() { @Override @@ -117,7 +115,6 @@ public abstract class CompletionService { } } }); - return lookupSet.toArray(new LookupElement[lookupSet.size()]); } public abstract CompletionSorter defaultSorter(CompletionParameters parameters, PrefixMatcher matcher); diff --git a/platform/lang-api/src/com/intellij/ide/actions/ElementCreator.java b/platform/lang-api/src/com/intellij/ide/actions/ElementCreator.java index 9dc668b66dfc..6b561ff6974c 100644 --- a/platform/lang-api/src/com/intellij/ide/actions/ElementCreator.java +++ b/platform/lang-api/src/com/intellij/ide/actions/ElementCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,9 +23,9 @@ import com.intellij.ide.IdeBundle; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.UndoConfirmationPolicy; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.SmartPointerManager; import com.intellij.psi.SmartPsiElementPointer; @@ -65,7 +65,7 @@ public abstract class ElementCreator { final String commandName = getActionName(inputString); new WriteCommandAction(myProject, commandName) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { LocalHistoryAction action = LocalHistoryAction.NULL; try { action = LocalHistory.getInstance().startAction(commandName); diff --git a/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java b/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java index 0a00f0e77b4c..215c80285bf5 100644 --- a/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java +++ b/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -111,6 +111,11 @@ public abstract class ModuleType { return true; } + public static boolean is(@NotNull Module module, @NotNull ModuleType moduleType) { + return moduleType.getId().equals(module.getOptionValue(Module.ELEMENT_TYPE)); + } + + @NotNull public static ModuleType get(@NotNull Module module) { final ModuleTypeManager instance = ModuleTypeManager.getInstance(); if (instance == null) { diff --git a/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java b/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java index f79128db39fd..54a87b825afe 100644 --- a/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java +++ b/platform/lang-api/src/com/intellij/openapi/module/ModuleUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,9 @@ */ package com.intellij.openapi.module; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Key; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.ParameterizedCachedValue; @@ -105,7 +100,6 @@ public class ModuleUtil extends ModuleUtilCore { @Nullable public static ModuleType getModuleType(@NotNull Module module) { - String type = module.getOptionValue(Module.ELEMENT_TYPE); - return ModuleTypeManager.getInstance().findByID(type); + return ModuleType.get(module); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java index ae57a1a6b77d..6ee63b1b4a47 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -140,7 +140,7 @@ public class FormatChangedTextUtil { public static boolean hasChanges(@NotNull final Project project) { final ModifiableModuleModel moduleModel = new ReadAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { result.setResult(ModuleManager.getInstance(project).getModifiableModel()); } }.execute().getResultObject(); 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 a8e13c97b80b..2943c4751911 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -609,6 +609,7 @@ public class CodeCompletionHandlerBase { final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(editor); final PsiFile originalFile = indicator.getParameters().getOriginalFile(); final PsiFile hostFile = InjectedLanguageUtil.getTopLevelFile(originalFile); + assert hostFile != null; final OffsetMap hostMap = translateOffsetMapToHost(originalFile, hostFile, hostEditor, indicator.getOffsetMap()); hostEditor.getCaretModel().runForEachCaret(new CaretAction() { @Override @@ -618,9 +619,13 @@ public class CodeCompletionHandlerBase { Editor targetEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(hostEditor, targetFile); int targetCaretOffset = targetEditor.getCaretModel().getOffset(); OffsetMap injectedMap = translateOffsetMapToInjected(hostMap, targetEditor.getDocument()); + int idEnd = targetCaretOffset + idEndOffsetDelta; + if (idEnd > targetEditor.getDocument().getTextLength()) { + idEnd = targetCaretOffset; // no replacement by Tab when offsets gone wrong for some reason + } CompletionAssertions.WatchingInsertionContext currentContext = insertItem(indicator, item, completionChar, items, update, targetEditor, targetFile == null ? hostFile : targetFile, - targetCaretOffset, targetCaretOffset + idEndOffsetDelta, + targetCaretOffset, idEnd, injectedMap); contexts.add(currentContext); } @@ -691,7 +696,7 @@ public class CodeCompletionHandlerBase { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - if (caretOffset != idEndOffset && completionChar == Lookup.REPLACE_SELECT_CHAR) { + if (caretOffset < idEndOffset && completionChar == Lookup.REPLACE_SELECT_CHAR) { editor.getDocument().deleteString(caretOffset, idEndOffset); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index f2f5c6640d7a..8b40766a4244 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -40,6 +40,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Caret; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProcessCanceledException; @@ -56,6 +57,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.ElementPattern; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.ReferenceRange; @@ -130,7 +132,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement private volatile boolean myHasPsiElements; private boolean myLookupUpdated; private final ConcurrentMap myItemSorters = - ContainerUtil.newConcurrentMap(ContainerUtil.identityStrategy()); + ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); private final PropertyChangeListener myLookupManagerListener; private final Queue myAdvertiserChanges = new ConcurrentLinkedQueue(); private final List myDelayedMiddleMatches = ContainerUtil.newArrayList(); @@ -229,7 +231,16 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement final int selectionEndOffset = initContext.getSelectionEndOffset(); final PsiReference reference = TargetElementUtil.findReference(myEditor, selectionEndOffset); if (reference != null) { - initContext.setReplacementOffset(findReplacementOffset(selectionEndOffset, reference)); + final int replacementOffset = findReplacementOffset(selectionEndOffset, reference); + final Document document = initContext.getEditor().getDocument(); + if (replacementOffset > document.getTextLength()) { + LOG.error("Invalid replacementOffset: " + replacementOffset + " returned by reference " + reference + " of " + reference.getClass() + + "; doc=" + document + + "; doc actual=" + (document == initContext.getFile().getViewProvider().getDocument()) + + "; doc committed=" + PsiDocumentManager.getInstance(getProject()).isCommitted(document)); + } else { + initContext.setReplacementOffset(replacementOffset); + } } } catch (IndexNotReadyException ignored) { @@ -818,17 +829,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement strategy.startThread(this, new CalculateItems()); } - private LookupElement[] calculateItems(CompletionInitializationContext initContext, WeighingDelegate weigher) { + private void calculateItems(CompletionInitializationContext initContext, WeighingDelegate weigher) { duringCompletion(initContext); ProgressManager.checkCanceled(); - LookupElement[] result = CompletionService.getCompletionService().performCompletion(myParameters, weigher); + CompletionService.getCompletionService().performCompletion(myParameters, weigher); ProgressManager.checkCanceled(); weigher.waitFor(); ProgressManager.checkCanceled(); - - return result; } public void addAdvertisement(@NotNull final String text, @Nullable final Color bgColor) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java index 96864d039d73..a0874a670de5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/BetterPrefixMatcher.java @@ -16,11 +16,10 @@ package com.intellij.codeInsight.completion.impl; import com.intellij.codeInsight.completion.CompletionResult; +import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.completion.PrefixMatcher; import org.jetbrains.annotations.NotNull; -import java.util.LinkedHashSet; - /** * @author peter */ @@ -33,16 +32,19 @@ public class BetterPrefixMatcher extends PrefixMatcher { myOriginal = original; myMinMatchingDegree = minMatchingDegree; } - - public static int getBestMatchingDegree(LinkedHashSet plainResults) { - int bestMatchingDegree = Integer.MIN_VALUE; - for (CompletionResult cr : plainResults) { - bestMatchingDegree = Math.max(bestMatchingDegree, RealPrefixMatchingWeigher - .getBestMatchingDegree(cr.getLookupElement(), cr.getPrefixMatcher())); - } - return bestMatchingDegree; + + public BetterPrefixMatcher(CompletionResultSet set) { + this(set.getPrefixMatcher(), Integer.MIN_VALUE); } + @NotNull + public BetterPrefixMatcher improve(CompletionResult result) { + int degree = RealPrefixMatchingWeigher.getBestMatchingDegree(result.getLookupElement(), result.getPrefixMatcher()); + if (degree <= myMinMatchingDegree) return this; + + return new BetterPrefixMatcher(myOriginal, degree); + } + @Override public boolean prefixMatches(@NotNull String name) { if (!myOriginal.prefixMatches(name) || !myOriginal.isStartMatch(name)) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java index c92dfef95618..d4ac9891c71d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameFileFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -71,7 +71,7 @@ public class RenameFileFix implements IntentionAction, LocalQuickFix { if (isAvailable(project, null, file)) { new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { invoke(project, null, file); } }.execute(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFileFix.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFileFix.java index ccdd54ce36b9..e7e5f7f3edbc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFileFix.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateFileFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -106,7 +106,7 @@ public class CreateFileFix extends LocalQuickFixAndIntentionActionOnPsiElement { if (isAvailable(project, null, file)) { new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { invoke(project, myDirectory); } }.execute(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/RenameFileReferenceIntentionAction.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/RenameFileReferenceIntentionAction.java index 2f2ce95d6880..b55ae6d0dc98 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/RenameFileReferenceIntentionAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/quickFix/RenameFileReferenceIntentionAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -64,7 +64,7 @@ class RenameFileReferenceIntentionAction implements IntentionAction, LocalQuickF if (isAvailable(project, null, null)) { new WriteCommandAction(project) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { invoke(project, null, descriptor.getPsiElement().getContainingFile()); } }.execute(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java index adfe43f65c30..38f41f7d79c5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java @@ -36,14 +36,15 @@ import com.intellij.ui.components.JBList; import com.intellij.ui.speedSearch.SpeedSearchUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FList; -import com.intellij.util.ui.*; +import com.intellij.util.ui.EmptyIcon; +import com.intellij.util.ui.GraphicsUtil; +import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; -import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -483,18 +484,17 @@ public class LookupCellRenderer implements ListCellRenderer { @Override public void paint(Graphics g){ + super.paint(g); if (!myLookup.isFocused() && myLookup.isCompletion()) { - ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f)); - - // sub-pixel antialiasing does not work with alpha composite, so we workaround this by painting to RGB image first - BufferedImage image = UIUtil.createImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); - Graphics2D imageGraphics = image.createGraphics(); - super.paint(imageGraphics); - imageGraphics.dispose(); - UIUtil.drawImage(g, image, 0, 0, null); - } - else { - super.paint(g); + g = g.create(); + try { + g.setColor(ColorUtil.withAlpha(BACKGROUND_COLOR, .4)); + Rectangle r = new Rectangle(getSize()); + g.fillRect(r.x, r.y, r.width, r.height); + } + finally { + g.dispose(); + } } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 63196a62a837..c6ef64c7083a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -116,7 +116,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable, private volatile LookupArranger myArranger; private LookupArranger myPresentableArranger; private final Map myMatchers = - ContainerUtil.newConcurrentMap(ContainerUtil.identityStrategy()); + ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy()); private final Map myCustomFonts = ContainerUtil.createConcurrentWeakMap(10, 0.75f, Runtime.getRuntime().availableProcessors(), ContainerUtil.identityStrategy()); private boolean myStartCompletionWhenNothingMatches; @@ -536,7 +536,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable, public void perform(Caret caret) { EditorModificationUtil.deleteSelectedText(hostEditor); final int caretOffset = hostEditor.getCaretModel().getOffset(); - int lookupStart = Math.max(caretOffset - prefix, 0); + int lookupStart = Math.min(caretOffset, Math.max(caretOffset - prefix, 0)); int len = hostEditor.getDocument().getTextLength(); LOG.assertTrue(lookupStart >= 0 && lookupStart <= len, diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java index ea96905f470d..3e93f02fc39f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java @@ -35,6 +35,7 @@ import com.intellij.openapi.actionSystem.impl.ActionButton; import com.intellij.openapi.actionSystem.impl.PresentationFactory; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.AbstractProjectComponent; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; @@ -102,6 +103,7 @@ import java.util.EventObject; import java.util.List; public class CtrlMouseHandler extends AbstractProjectComponent { + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.navigation.CtrlMouseHandler"); private static final AbstractDocumentationTooltipAction[] ourTooltipActions = {new ShowQuickDocAtPinnedWindowFromTooltipAction()}; private final EditorColorsManager myEditorColorsManager; @@ -382,8 +384,19 @@ public class CtrlMouseHandler extends AbstractProjectComponent { } public Info(@NotNull PsiElement elementAtPointer) { - this(elementAtPointer, Collections.singletonList(new TextRange(elementAtPointer.getTextOffset(), - elementAtPointer.getTextOffset() + elementAtPointer.getTextLength()))); + this(elementAtPointer, Collections.singletonList(getReferenceRange(elementAtPointer))); + } + + @NotNull + private static TextRange getReferenceRange(@NotNull PsiElement elementAtPointer) { + int textOffset = elementAtPointer.getTextOffset(); + final TextRange range = elementAtPointer.getTextRange(); + if (textOffset < range.getStartOffset() || textOffset < 0) { + LOG.error("Invalid text offset " + textOffset + " of element " + elementAtPointer + " of " + elementAtPointer.getClass()); + textOffset = range.getStartOffset(); + } + + return new TextRange(textOffset, range.getEndOffset()); } boolean isSimilarTo(@NotNull Info that) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java index 664b51dfce30..dd53e5aab241 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateExpressionLookupElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -33,6 +33,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -64,7 +65,7 @@ class TemplateExpressionLookupElement extends LookupElementDecorator> myCursorPositions = new Stack>(); @@ -352,6 +353,7 @@ public class SearchResults implements DocumentListener { notifyCursorMoved(); } dumpIfNeeded(); + myDocumentTimestamp = myEditor.getDocument().getModificationStamp(); } private void dumpIfNeeded() { @@ -629,4 +631,8 @@ public class SearchResults implements DocumentListener { listener.cursorMoved(); } } + + public boolean isUpToDate() { + return myDocumentTimestamp == myEditor.getDocument().getModificationStamp(); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index 6f968e381b58..516c309e9fa6 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -1518,7 +1518,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } private synchronized void buildFiles(final String pattern) { - final SearchResult files = getFiles(pattern, MAX_FILES, myFileChooseByName); + final SearchResult files = getFiles(pattern, showAll.get(), MAX_FILES, myFileChooseByName); check(); @@ -1704,6 +1704,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA return !symbols.needMore; } }); + + if (!includeLibs && symbols.isEmpty()) { + return getSymbols(pattern, max, true, chooseByNamePopup); + } + return symbols; } @@ -1752,7 +1757,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA return classes; } - private SearchResult getFiles(final String pattern, final int max, ChooseByNamePopup chooseByNamePopup) { + private SearchResult getFiles(final String pattern, final boolean includeLibs, final int max, ChooseByNamePopup chooseByNamePopup) { final SearchResult files = new SearchResult(); if (chooseByNamePopup == null || !Registry.is("search.everywhere.files")) { return files; @@ -1772,7 +1777,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } if (file != null && !(pattern.indexOf(' ') != -1 && file.getName().indexOf(' ') == -1) - && (showAll.get() || scope.accept(file) + && (includeLibs || scope.accept(file) && !myListModel.contains(file) && !myAlreadyAddedFiles.contains(file)) && !files.contains(file)) { @@ -1785,6 +1790,10 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA return true; } }); + if (!includeLibs && files.isEmpty()) { + return getFiles(pattern, true, max, chooseByNamePopup); + } + return files; } @@ -2145,7 +2154,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA try { final SearchResult result = id == WidgetID.CLASSES ? getClasses(pattern, showAll.get(), DEFAULT_MORE_STEP_COUNT, myClassChooseByName) - : id == WidgetID.FILES ? getFiles(pattern, DEFAULT_MORE_STEP_COUNT, myFileChooseByName) + : id == WidgetID.FILES ? getFiles(pattern, showAll.get(), DEFAULT_MORE_STEP_COUNT, myFileChooseByName) : id == WidgetID.RUN_CONFIGURATIONS ? getConfigurations(pattern, DEFAULT_MORE_STEP_COUNT) : id == WidgetID.SYMBOLS ? getSymbols(pattern, DEFAULT_MORE_STEP_COUNT, showAll.get(), mySymbolsChooseByName) : id == WidgetID.ACTIONS ? getActionsOrSettings(pattern, DEFAULT_MORE_STEP_COUNT, true) diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java index 0ac61c17f613..9aaf58ba285e 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/actions/CreateFromTemplateGroup.java @@ -57,8 +57,9 @@ public class CreateFromTemplateGroup extends ActionGroup implements DumbAware { @Override @NotNull public AnAction[] getChildren(@Nullable AnActionEvent e){ - Project project; - if (e == null || (project = CommonDataKeys.PROJECT.getData(e.getDataContext())) == null) return EMPTY_ARRAY; + if (e == null) return EMPTY_ARRAY; + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + if (project == null) return EMPTY_ARRAY; FileTemplateManager manager = FileTemplateManager.getInstance(project); FileTemplate[] templates = manager.getAllTemplates(); @@ -106,7 +107,7 @@ public class CreateFromTemplateGroup extends ActionGroup implements DumbAware { } } - if (!result.isEmpty()) { + if (!result.isEmpty() || !showAll) { if (!showAll) { result.add(new CreateFromTemplatesAction(IdeBundle.message("action.from.file.template"))); } diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/IModuleStore.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/IModuleStore.java deleted file mode 100644 index 56e5d6386d10..000000000000 --- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/IModuleStore.java +++ /dev/null @@ -1,39 +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.openapi.components.impl.stores; - -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public interface IModuleStore extends IComponentStore { - void setModuleFilePath(@NotNull String filePath); - - @Nullable - VirtualFile getModuleFile(); - - @NotNull - String getModuleFilePath(); - - @NotNull - String getModuleFileName(); - - void setOption(@NotNull String optionName, @NotNull String optionValue); - - void clearOption(@NotNull String optionName); - - String getOptionValue(@NotNull String optionName); -} diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java deleted file mode 100644 index c936db0d8304..000000000000 --- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2000-2015 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.openapi.components.impl.stores; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.*; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleTypeManager; -import com.intellij.openapi.module.impl.ModuleImpl; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ex.ProjectEx; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.PathUtilRt; -import com.intellij.util.messages.MessageBus; -import org.jdom.Attribute; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IModuleStore { - private static final Logger LOG = Logger.getInstance(ModuleStoreImpl.class); - - private final ModuleImpl myModule; - - @SuppressWarnings({"UnusedDeclaration"}) - public ModuleStoreImpl(@NotNull ModuleImpl module, @NotNull PathMacroManager pathMacroManager) { - super(pathMacroManager); - - myModule = module; - } - - @NotNull - @Override - protected FileBasedStorage getMainStorage() { - FileBasedStorage storage = (FileBasedStorage)getStateStorageManager().getStateStorage(StoragePathMacros.MODULE_FILE, RoamingType.PER_USER); - assert storage != null; - return storage; - } - - @Override - protected Project getProject() { - return myModule.getProject(); - } - - public void load() { - String moduleTypeId = getMainStorageData().myOptions.get(Module.ELEMENT_TYPE); - myModule.setOption(Module.ELEMENT_TYPE, ModuleTypeManager.getInstance().findByID(moduleTypeId).getId()); - - if (ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode()) { - return; - } - - final TrackingPathMacroSubstitutor substitutor = getStateStorageManager().getMacroSubstitutor(); - if (substitutor != null) { - final Collection macros = substitutor.getUnknownMacros(null); - if (!macros.isEmpty()) { - final Project project = myModule.getProject(); - StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { - @Override - public void run() { - StorageUtil.notifyUnknownMacros(substitutor, project, null); - } - }); - } - } - } - - @Override - public ModuleFileData getMainStorageData() { - return (ModuleFileData)super.getMainStorageData(); - } - - static class ModuleFileData extends BaseStorageData { - private final Map myOptions; - private final Module myModule; - - private boolean dirty = true; - - public ModuleFileData(@NotNull String rootElementName, @NotNull Module module) { - super(rootElementName); - - myModule = module; - myOptions = new TreeMap(); - } - - @Override - public boolean isDirty() { - return dirty; - } - - private ModuleFileData(@NotNull ModuleFileData storageData) { - super(storageData); - - myModule = storageData.myModule; - dirty = storageData.dirty; - myOptions = new TreeMap(storageData.myOptions); - } - - @Override - public void load(@NotNull Element rootElement, @Nullable PathMacroSubstitutor pathMacroSubstitutor, boolean intern) { - super.load(rootElement, pathMacroSubstitutor, intern); - - for (Attribute attribute : rootElement.getAttributes()) { - if (!attribute.getName().equals(VERSION_OPTION)) { - myOptions.put(attribute.getName(), attribute.getValue()); - } - } - - dirty = false; - } - - @Override - protected void writeOptions(@NotNull Element root, @NotNull String versionString) { - if (!myOptions.isEmpty()) { - for (Map.Entry entry : myOptions.entrySet()) { - root.setAttribute(entry.getKey(), entry.getValue()); - } - } - // need be last for compat reasons - super.writeOptions(root, versionString); - - dirty = false; - } - - @Override - public StorageData clone() { - return new ModuleFileData(this); - } - - @Nullable - @Override - public Set getChangedComponentNames(@NotNull StorageData newStorageData, @Nullable PathMacroSubstitutor substitutor) { - final ModuleFileData data = (ModuleFileData)newStorageData; - if (!myOptions.equals(data.myOptions)) { - return null; - } - return super.getChangedComponentNames(newStorageData, substitutor); - } - - public void setOption(@NotNull String optionName, @NotNull String optionValue) { - if (!optionValue.equals(myOptions.put(optionName, optionValue))) { - dirty = true; - } - } - - public void clearOption(@NotNull String optionName) { - if (myOptions.remove(optionName) != null) { - dirty = true; - } - } - - @Nullable - public String getOptionValue(@NotNull String optionName) { - return myOptions.get(optionName); - } - } - - @Override - public void setModuleFilePath(@NotNull String filePath) { - final String path = filePath.replace(File.separatorChar, '/'); - LocalFileSystem.getInstance().refreshAndFindFileByPath(path); - final StateStorageManager storageManager = getStateStorageManager(); - storageManager.clearStateStorage(StoragePathMacros.MODULE_FILE); - storageManager.addMacro(StoragePathMacros.MODULE_FILE, path); - } - - @Override - @Nullable - public VirtualFile getModuleFile() { - return getMainStorage().getVirtualFile(); - } - - @Override - @NotNull - public String getModuleFilePath() { - return getMainStorage().getFilePath(); - } - - @Override - @NotNull - public String getModuleFileName() { - return PathUtilRt.getFileName(getMainStorage().getFilePath()); - } - - @Override - public void setOption(@NotNull String optionName, @NotNull String optionValue) { - try { - getMainStorageData().setOption(optionName, optionValue); - } - catch (StateStorageException e) { - LOG.error(e); - } - } - - @Override - public void clearOption(@NotNull String optionName) { - try { - getMainStorageData().clearOption(optionName); - } - catch (StateStorageException e) { - LOG.error(e); - } - } - - @Override - public String getOptionValue(@NotNull String optionName) { - try { - return getMainStorageData().getOptionValue(optionName); - } - catch (StateStorageException e) { - LOG.error(e); - return null; - } - } - - @Override - protected boolean optimizeTestLoading() { - return ((ProjectEx)myModule.getProject()).isOptimiseTestLoadSpeed(); - } - - @NotNull - @Override - protected MessageBus getMessageBus() { - return myModule.getMessageBus(); - } - - @NotNull - @Override - protected StateStorageManager createStateStorageManager() { - return new ModuleStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myModule); - } -} diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java index df6ae6482d0c..55c7019f6900 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java @@ -17,14 +17,13 @@ package com.intellij.openapi.module.impl; import com.intellij.ide.highlighter.ModuleFileType; import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.impl.ApplicationInfoImpl; -import com.intellij.openapi.components.ComponentConfig; -import com.intellij.openapi.components.ExtensionAreas; -import com.intellij.openapi.components.PathMacroManager; -import com.intellij.openapi.components.impl.ModulePathMacroManager; +import com.intellij.openapi.components.*; +import com.intellij.openapi.components.impl.ModuleServiceManagerImpl; import com.intellij.openapi.components.impl.PlatformComponentManagerImpl; -import com.intellij.openapi.components.impl.stores.IComponentStore; -import com.intellij.openapi.components.impl.stores.ModuleStoreImpl; +import com.intellij.openapi.components.impl.stores.FileBasedStorage; +import com.intellij.openapi.components.impl.stores.StateStorageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.AreaInstance; import com.intellij.openapi.extensions.ExtensionPointName; @@ -32,25 +31,25 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleComponent; +import com.intellij.openapi.module.OptionManager; import com.intellij.openapi.module.impl.scopes.ModuleScopeProviderImpl; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.impl.storage.ClasspathStorage; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.PathUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.picocontainer.MutablePicoContainer; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.List; +import java.util.Map; /** * @author max @@ -61,14 +60,10 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx @NotNull private final Project myProject; private boolean isModuleAdded; - @NonNls private static final String OPTION_WORKSPACE = "workspace"; - public static final Object MODULE_RENAMING_REQUESTOR = new Object(); private String myName; - private String myModuleType; - private final ModuleScopeProvider myModuleScopeProvider; public ModuleImpl(@NotNull String filePath, @NotNull Project project) { @@ -79,32 +74,46 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx myProject = project; myModuleScopeProvider = new ModuleScopeProviderImpl(this); - init(filePath); + myName = moduleNameByFileName(PathUtil.getFileName(filePath)); + + VirtualFileManager.getInstance().addVirtualFileListener(new MyVirtualFileListener(), this); + } + + private void setModuleFilePath(@NotNull String filePath) { + String path = filePath.replace(File.separatorChar, '/'); + LocalFileSystem.getInstance().refreshAndFindFileByPath(path); + StateStorageManager storageManager = ComponentsPackage.getStateStore(this).getStateStorageManager(); + storageManager.clearStateStorage(StoragePathMacros.MODULE_FILE); + storageManager.addMacro(StoragePathMacros.MODULE_FILE, path); } @Override protected void bootstrapPicoContainer(@NotNull String name) { Extensions.instantiateArea(ExtensionAreas.IDEA_MODULE, this, (AreaInstance)getParentComponentManager()); super.bootstrapPicoContainer(name); - getPicoContainer().registerComponentImplementation(IComponentStore.class, ModuleStoreImpl.class); - getPicoContainer().registerComponentImplementation(PathMacroManager.class, ModulePathMacroManager.class); } @NotNull - public ModuleStoreImpl getStateStore() { - return (ModuleStoreImpl)getPicoContainer().getComponentInstance(IComponentStore.class); - } - - private void init(String filePath) { - getStateStore().setModuleFilePath(filePath); - myName = moduleNameByFileName(PathUtil.getFileName(filePath)); - - VirtualFileManager.getInstance().addVirtualFileListener(new MyVirtualFileListener(), this); + private static FileBasedStorage getMainStorage(@NotNull Module module) { + FileBasedStorage storage = (FileBasedStorage)ComponentsPackage.getStateStore(module).getStateStorageManager().getStateStorage(StoragePathMacros.MODULE_FILE, RoamingType.PER_USER); + assert storage != null; + return storage; } @Override - public void init() { - init(ProgressManager.getInstance().getProgressIndicator()); + public void init(@NotNull final String path, @Nullable final Runnable beforeComponentCreation) { + init(ProgressManager.getInstance().getProgressIndicator(), new Runnable() { + @Override + public void run() { + // create ServiceManagerImpl at first to force extension classes registration + getPicoContainer().getComponentInstance(ModuleServiceManagerImpl.class); + ComponentsPackage.getStateStore(ModuleImpl.this).getStateStorageManager().addMacro(StoragePathMacros.MODULE_FILE, path); + + if (beforeComponentCreation != null) { + beforeComponentCreation.run(); + } + } + }); } @Override @@ -113,46 +122,54 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx } @Override - protected boolean isComponentSuitable(Map options) { - if (!super.isComponentSuitable(options)) return false; - if (options == null) return true; + protected boolean isComponentSuitable(@Nullable Map options) { + if (!super.isComponentSuitable(options)) { + return false; + } + if (options == null || options.isEmpty()) { + return true; + } - Set optionNames = options.keySet(); - for (String optionName : optionNames) { - if (Comparing.equal(OPTION_WORKSPACE, optionName)) continue; - if (!parseOptionValue(options.get(optionName)).contains(getOptionValue(optionName))) return false; + for (String optionName : options.keySet()) { + if ("workspace".equals(optionName)) { + continue; + } + + // we cannot filter using module options because at this moment module file data could be not loaded + String message = "Don't specify " + optionName + " in the component registration, transform component to service and implement your logic in your getInstance() method"; + if (ApplicationManager.getApplication().isUnitTestMode()) { + LOG.error(message); + } + else { + LOG.warn(message); + } } return true; } - private static List parseOptionValue(String optionValue) { - if (optionValue == null) return new ArrayList(0); - return Arrays.asList(optionValue.split(";")); - } - @Override @Nullable public VirtualFile getModuleFile() { - return getStateStore().getModuleFile(); + return getMainStorage(this).getVirtualFile(); } @Override public void rename(String newName) { myName = newName; - final VirtualFile file = getStateStore().getModuleFile(); + final VirtualFile file = getMainStorage(this).getVirtualFile(); try { if (file != null) { ClasspathStorage.moduleRenamed(this, newName); file.rename(MODULE_RENAMING_REQUESTOR, newName + ModuleFileType.DOT_DEFAULT_EXTENSION); - getStateStore().setModuleFilePath(VfsUtilCore.virtualToIoFile(file).getCanonicalPath()); + setModuleFilePath(VfsUtilCore.virtualToIoFile(file).getCanonicalPath()); return; } // [dsl] we get here if either old file didn't exist or renaming failed final File oldFile = new File(getModuleFilePath()); final File newFile = new File(oldFile.getParentFile(), newName + ModuleFileType.DOT_DEFAULT_EXTENSION); - getStateStore().setModuleFilePath(newFile.getCanonicalPath()); + setModuleFilePath(newFile.getCanonicalPath()); } catch (IOException e) { LOG.debug(e); @@ -162,7 +179,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx @Override @NotNull public String getModuleFilePath() { - return getStateStore().getModuleFilePath(); + return getMainStorage(this).getFilePath(); } @Override @@ -230,30 +247,36 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx } @Override - public void setOption(@NotNull String optionName, @NotNull String optionValue) { - if (ELEMENT_TYPE.equals(optionName)) { - myModuleType = optionValue; + public void setOption(@NotNull String key, @NotNull String value) { + OptionManager manager = getOptionManager(); + if (manager != null) { + manager.setOption(key, value); + } + } + + @Nullable + private OptionManager getOptionManager() { + try { + return (OptionManager)getMainStorage(this).getStorageData(); + } + catch (StateStorageException e) { + LOG.error(e); + return null; } - getStateStore().setOption(optionName, optionValue); } @Override - public void clearOption(@NotNull String optionName) { - if (ELEMENT_TYPE.equals(optionName)) { - myModuleType = null; + public void clearOption(@NotNull String key) { + OptionManager manager = getOptionManager(); + if (manager != null) { + manager.clearOption(key); } - getStateStore().clearOption(optionName); } @Override - public String getOptionValue(@NotNull String optionName) { - if (ELEMENT_TYPE.equals(optionName)) { - if (myModuleType == null) { - myModuleType = getStateStore().getOptionValue(optionName); - } - return myModuleType; - } - return getStateStore().getOptionValue(optionName); + public String getOptionValue(@NotNull String key) { + OptionManager manager = getOptionManager(); + return manager == null ? null : manager.getOptionValue(key); } @NotNull @@ -379,7 +402,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx modifiableModel.setModuleFilePath(ModuleImpl.this, moduleFilePath, newFilePath); modifiableModel.commit(); - getStateStore().setModuleFilePath(newFilePath); + ModuleImpl.this.setModuleFilePath(newFilePath); } @Override diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerComponent.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerComponent.java index eab9b48a10ec..235138b03d9d 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerComponent.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleManagerComponent.java @@ -25,6 +25,7 @@ import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.components.StoragePathMacros; import com.intellij.openapi.components.StorageScheme; +import com.intellij.openapi.components.impl.stores.StorageUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; @@ -120,7 +121,7 @@ public class ModuleManagerComponent extends ModuleManagerImpl { @Override protected ModuleEx createAndLoadModule(@NotNull String filePath) throws IOException { ModuleImpl module = new ModuleImpl(filePath, myProject); - module.getStateStore().load(); + StorageUtil.checkUnknownMacros(module, myProject); return module; } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java index d73c6d612f0c..45f2d7c71a9a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/OrderEntryUtil.java @@ -31,6 +31,9 @@ import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + public class OrderEntryUtil { private OrderEntryUtil() { } @@ -214,4 +217,19 @@ public class OrderEntryUtil { if (scope1 == DependencyScope.TEST || scope2 == DependencyScope.TEST) return DependencyScope.TEST; return scope1; } + + @NotNull + public static List getModuleLibraries(@NotNull ModuleRootModel model) { + OrderEntry[] orderEntries = model.getOrderEntries(); + List libraries = new ArrayList(); + for (OrderEntry orderEntry : orderEntries) { + if (orderEntry instanceof LibraryOrderEntry) { + final LibraryOrderEntry entry = (LibraryOrderEntry)orderEntry; + if (entry.isModuleLevel()) { + libraries.add(entry.getLibrary()); + } + } + } + return libraries; + } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java index 7c16888afe73..f1ab953b469f 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java @@ -17,7 +17,7 @@ package com.intellij.openapi.roots.impl.storage; import com.intellij.application.options.PathMacrosCollector; import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.components.impl.stores.IModuleStore; +import com.intellij.openapi.components.impl.stores.IComponentStore; import com.intellij.openapi.components.impl.stores.StateStorageBase; import com.intellij.openapi.components.impl.stores.StorageDataBase; import com.intellij.openapi.module.Module; @@ -52,7 +52,7 @@ public class ClasspathStorage extends StateStorageBase extends In if (astNode != null) { new WriteCommandAction(project, "Normalize declaration") { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { node.getTreeParent().addChild(astNode, node); } }.execute(); diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java index c941975d2141..dbd5a41dad39 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java @@ -53,7 +53,6 @@ import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.BalloonBuilder; @@ -336,7 +335,7 @@ public abstract class InplaceRefactoring { new WriteCommandAction(myProject, getCommandName()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { startTemplate(builder); } }.execute(); diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java index 9859a01ef5c4..635c9a694981 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java @@ -226,7 +226,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring { if (elementToRename != null) { new WriteCommandAction(myProject, getCommandName()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { renameSynthetic(newName); } }.execute(); @@ -279,7 +279,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring { }; final WriteCommandAction writeCommandAction = new WriteCommandAction(myProject, getCommandName()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { performAutomaticRename.run(); } }; diff --git a/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java b/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java index 68afc2b26b6b..3aca90930dd7 100644 --- a/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java +++ b/platform/lang-impl/src/com/intellij/ui/StringComboboxEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import com.intellij.openapi.util.Key; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -75,7 +76,7 @@ public class StringComboboxEditor extends EditorComboBoxEditor { final String s = (String)anObject; new WriteCommandAction(myProject) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { getDocument().setText(s); } }.execute(); 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 2861cb50a274..ddfed273d9be 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -1077,6 +1077,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { myContentlessIndicesUpdateQueue.signalUpdateStart(); myContentlessIndicesUpdateQueue.ensureUpToDate(); myProjectsBeingUpdated.add(project); + ++myFilesModCount; } void filesUpdateFinished(@NotNull Project project) { @@ -1787,7 +1788,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { IndexingStamp.setFileIndexedStateCurrent(fileId, indexId); } else { - IndexingStamp.setFileIndexedStateUnindexed(fileId, indexId); + IndexingStamp.setFileIndexedStateOutdated(fileId, indexId); } if (myNotRequiringContentIndices.contains(indexId)) IndexingStamp.flushCache(fileId); } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java index f340c3d301d1..1f2a40042bfd 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java @@ -40,6 +40,9 @@ import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @author Eugene Zhuravlev @@ -48,17 +51,16 @@ import java.util.concurrent.ConcurrentMap; * A file has three indexed states (per particular index): indexed (with particular index_stamp), outdated and (trivial) unindexed * if index version is advanced or we rebuild it then index_stamp is advanced, we rebuild everything * if we get remove file event -> we should remove all indexed state from indices data for it (if state is nontrivial) - * and set its indexed state to unindexed + * and set its indexed state to outdated * if we get other event we set indexed state to outdated * * Index stamp is file timestamp of the index directory, it is assumed that index stamps are monotonically increasing, but - * still << Long.MAX_VALUE: there are two negative special timestamps used for marking outdated / unindexed index state. + * still << Long.MAX_VALUE: there is one negative special timestamp used for marking outdated index state. * The code doesn't take overflow of real file timestaps (or their coincidence to negative special timestamps) into account because * it will happen (if time will go as forward as it does today) near year 292277094 (=new java.util.Date(Long.MAX_VALUE).getYear()). * At that time (if this code will be still actual) we can use positive small timestamps for special cases. */ public class IndexingStamp { - private static final long UNINDEXED_STAMP = -1L; // we don't store trivial "absent" state private static final long INDEX_DATA_OUTDATED_STAMP = -2L; private static final int VERSION = 14; @@ -157,10 +159,6 @@ public class IndexingStamp { update(fileId, id, getIndexCreationStamp(id)); } - public static void setFileIndexedStateUnindexed(int fileId, ID id) { - update(fileId, id, UNINDEXED_STAMP); - } - public static void setFileIndexedStateOutdated(int fileId, ID id) { update(fileId, id, INDEX_DATA_OUTDATED_STAMP); } @@ -281,11 +279,6 @@ public class IndexingStamp { private void set(ID id, long tmst) { try { - if (tmst == UNINDEXED_STAMP) { - if (myIndexStamps == null) return; - myIndexStamps.remove(id); - return; - } if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f); myIndexStamps.put(id, tmst); @@ -311,10 +304,14 @@ public class IndexingStamp { } public static long getIndexStamp(int fileId, ID indexName) { - synchronized (getStripedLock(fileId)) { + Lock readLock = getStripedLock(fileId).readLock(); + readLock.lock(); + try { Timestamps stamp = createOrGetTimeStamp(fileId); if (stamp != null) return stamp.get(indexName); return 0; + } finally { + readLock.unlock(); } } @@ -337,33 +334,40 @@ public class IndexingStamp { public static void update(int fileId, @NotNull ID indexName, final long indexCreationStamp) { if (fileId < 0 || fileId == INVALID_FILE_ID) return; - synchronized (getStripedLock(fileId)) { + Lock writeLock = getStripedLock(fileId).writeLock(); + writeLock.lock(); + try { Timestamps stamp = createOrGetTimeStamp(fileId); if (stamp != null) stamp.set(indexName, indexCreationStamp); + } finally { + writeLock.unlock(); } } @NotNull public static List> getNontrivialFileIndexedStates(int fileId) { if (fileId != INVALID_FILE_ID) { - synchronized (getStripedLock(fileId)) { - try { - Timestamps stamp = createOrGetTimeStamp(fileId); - if (stamp != null && stamp.myIndexStamps != null && !stamp.myIndexStamps.isEmpty()) { - final SmartList> retained = new SmartList>(); - stamp.myIndexStamps.forEach(new TObjectProcedure>() { - @Override - public boolean execute(ID object) { - retained.add(object); - return true; - } - }); - return retained; - } - } - catch (InvalidVirtualFileAccessException ignored /*ok to ignore it here*/) { + Lock readLock = getStripedLock(fileId).readLock(); + readLock.lock(); + try { + Timestamps stamp = createOrGetTimeStamp(fileId); + if (stamp != null && stamp.myIndexStamps != null && !stamp.myIndexStamps.isEmpty()) { + final SmartList> retained = new SmartList>(); + stamp.myIndexStamps.forEach(new TObjectProcedure>() { + @Override + public boolean execute(ID object) { + retained.add(object); + return true; + } + }); + return retained; } } + catch (InvalidVirtualFileAccessException ignored /*ok to ignore it here*/) { + } + finally { + readLock.unlock(); + } } return Collections.emptyList(); } @@ -381,19 +385,21 @@ public class IndexingStamp { if (!files.isEmpty()) { for (Integer file : files) { - synchronized (getStripedLock(file)) { + Lock writeLock = getStripedLock(file).writeLock(); + writeLock.lock(); + try { Timestamps timestamp = myTimestampsCache.remove(file); if (timestamp == null) continue; - try { - if (timestamp.isDirty() /*&& file.isValid()*/) { - final DataOutputStream sink = FSRecords.writeAttribute(file, Timestamps.PERSISTENCE); - timestamp.writeToStream(sink); - sink.close(); - } - } - catch (IOException e) { - throw new RuntimeException(e); + + if (timestamp.isDirty() /*&& file.isValid()*/) { + final DataOutputStream sink = FSRecords.writeAttribute(file, Timestamps.PERSISTENCE); + timestamp.writeToStream(sink); + sink.close(); } + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + writeLock.unlock(); } } } @@ -408,12 +414,12 @@ public class IndexingStamp { flushCache(finishedFile); } - private static final Object[] ourLocks = new Object[16]; + private static final ReadWriteLock[] ourLocks = new ReadWriteLock[16]; static { - for(int i = 0; i < ourLocks.length; ++i) ourLocks[i] = new Object(); + for(int i = 0; i < ourLocks.length; ++i) ourLocks[i] = new ReentrantReadWriteLock(); } - private static Object getStripedLock(int fileId) { + private static ReadWriteLock getStripedLock(int fileId) { if (fileId < 0) fileId = -fileId; return ourLocks[(fileId & 0xFF) % ourLocks.length]; } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/revertion/Reverter.java b/platform/lvcs-impl/src/com/intellij/history/integration/revertion/Reverter.java index eae2937a7c96..df04a11f0991 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/revertion/Reverter.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/revertion/Reverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.diff.FilesTooBigForDiffException; import com.intellij.util.text.DateFormatUtil; +import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.*; @@ -79,7 +80,7 @@ public abstract class Reverter { try { new WriteCommandAction(myProject, getCommandName()) { @Override - protected void run(Result objectResult) throws Throwable { + protected void run(@NotNull Result objectResult) throws Throwable { myGateway.saveAllUnsavedDocuments(); doRevert(); myGateway.saveAllUnsavedDocuments(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java b/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java index 733a84b81c4b..3c2efa26ebd9 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/LoadingDecorator.java @@ -30,7 +30,7 @@ import java.awt.image.BufferedImage; public class LoadingDecorator { - JLayeredPane myPane = new MyLayeredPane(); + JLayeredPane myPane; LoadingLayer myLoadingLayer; Animator myFadeOutAnimator; @@ -41,6 +41,11 @@ public class LoadingDecorator { public LoadingDecorator(JComponent content, Disposable parent, int startDelayMs) { + this(content, parent, startDelayMs, false); + } + + public LoadingDecorator(JComponent content, Disposable parent, int startDelayMs, boolean useMinimumSize) { + myPane = new MyLayeredPane(useMinimumSize ? content : null); myLoadingLayer = new LoadingLayer(); myDelay = startDelayMs; myStartAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, parent); @@ -226,6 +231,17 @@ public class LoadingDecorator { } private static class MyLayeredPane extends JBLayeredPane { + private final JComponent myContent; + + private MyLayeredPane(JComponent content) { + myContent = content; + } + + @Override + public Dimension getMinimumSize() { + return myContent != null ? myContent.getMinimumSize() : super.getMinimumSize(); + } + @Override public void doLayout() { super.doLayout(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java index de597929aa0b..c3a5b7835751 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java @@ -23,6 +23,8 @@ import com.intellij.openapi.wm.IdeGlassPane; import com.intellij.openapi.wm.IdeGlassPaneUtil; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; +import com.intellij.ui.OnePixelSplitter; +import com.intellij.util.Producer; import com.intellij.util.ui.JBUI; import javax.swing.*; @@ -52,11 +54,30 @@ public class OnePixelDivider extends Divider { mySwitchOrientationEnabled = false; setFocusable(false); enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); - //setOpaque(false); + setOpaque(false); setOrientation(vertical); setBackground(BACKGROUND); } + @Override + public void paint(Graphics g) { + final Rectangle bounds = g.getClipBounds(); + if (mySplitter instanceof OnePixelSplitter) { + final Producer blindZone = ((OnePixelSplitter)mySplitter).getBlindZone(); + if (blindZone != null) { + final Insets insets = blindZone.produce(); + if (insets != null) { + bounds.x += insets.left; + bounds.y += insets.top; + bounds.width -= insets.left + insets.right; + bounds.height -= insets.top + insets.bottom; + } + } + } + g.setColor(getBackground()); + g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); + } + @Override public void addNotify() { super.addNotify(); diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java index f3e631e77c7c..e98a7837fb56 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java @@ -425,7 +425,7 @@ public class VfsUtil extends VfsUtilCore { public static VirtualFile createDirectories(@NotNull final String directoryPath) throws IOException { return new WriteAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { VirtualFile res = createDirectoryIfMissing(directoryPath); result.setResult(res); } diff --git a/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java index 15dd5fdc2abb..0f21071bbb93 100644 --- a/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java +++ b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,12 +17,17 @@ package com.intellij.ui; import com.intellij.openapi.ui.Divider; import com.intellij.openapi.ui.OnePixelDivider; +import com.intellij.util.Producer; + +import java.awt.*; /** * @author Konstantin Bulenkov */ public class OnePixelSplitter extends JBSplitter { + private Producer myBlindZone; + public OnePixelSplitter() { super(); init(); @@ -56,4 +61,14 @@ public class OnePixelSplitter extends JBSplitter { protected Divider createDivider() { return new OnePixelDivider(isVertical(), this); } + + public void setBlindZone(Producer blindZone) { + myBlindZone = blindZone; + } + + public Producer getBlindZone() { + return myBlindZone; + } + + public enum BlindZone {TOP, BOTTOM, LEFT, RIGHT} } diff --git a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java index f760c0dfc0a6..261258a4d7b3 100644 --- a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java +++ b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java @@ -1,10 +1,28 @@ +/* + * Copyright 2000-2015 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.util.net.ssl; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.*; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.components.StoragePathMacros; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.io.FileUtil; @@ -14,6 +32,7 @@ import com.intellij.util.xmlb.XmlSerializerUtil; import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Tag; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,8 +53,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import static org.apache.http.conn.ssl.SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; - /** * {@code CertificateManager} is responsible for negotiation SSL connection with server * and deals with untrusted/self-singed/expired and other kinds of digital certificates. @@ -66,7 +83,7 @@ import static org.apache.http.conn.ssl.SSLConnectionSocketFactory.BROWSER_COMPAT name = "CertificateManager", storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml") ) -public class CertificateManager implements ApplicationComponent, PersistentStateComponent { +public class CertificateManager implements PersistentStateComponent { @NonNls public static final String COMPONENT_NAME = "Certificate Manager"; @NonNls private static final String DEFAULT_PATH = FileUtil.join(PathManager.getSystemPath(), "tasks", "cacerts"); @@ -78,7 +95,7 @@ public class CertificateManager implements ApplicationComponent, PersistentState * Special version of hostname verifier, that asks user whether he accepts certificate, which subject's common name * doesn't match requested hostname. */ - public static final HostnameVerifier HOSTNAME_VERIFIER = new ConfirmingHostnameVerifier(BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + public static final HostnameVerifier HOSTNAME_VERIFIER = new ConfirmingHostnameVerifier(SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); /** * Used to check whether dialog is visible to prevent possible deadlock, e.g. when some external resource is loaded by * {@link java.awt.MediaTracker}. @@ -86,7 +103,7 @@ public class CertificateManager implements ApplicationComponent, PersistentState static final long DIALOG_VISIBILITY_TIMEOUT = 5000; // ms public static CertificateManager getInstance() { - return (CertificateManager)ApplicationManager.getApplication().getComponent(COMPONENT_NAME); + return ApplicationManager.getApplication().getComponent(CertificateManager.class); } private final String myCacertsPath; @@ -108,10 +125,7 @@ public class CertificateManager implements ApplicationComponent, PersistentState myPassword = DEFAULT_PASSWORD; myConfig = new Config(); myTrustManager = ConfirmingTrustManager.createForStorage(myCacertsPath, myPassword); - } - @Override - public void initComponent() { try { // Don't do this: protocol created this way will ignore SSL tunnels. See IDEA-115708. // Protocol.registerProtocol("https", CertificateManager.createDefault().createProtocol()); @@ -125,17 +139,6 @@ public class CertificateManager implements ApplicationComponent, PersistentState } } - @Override - public void disposeComponent() { - // empty - } - - @NotNull - @Override - public String getComponentName() { - return COMPONENT_NAME; - } - /** * Creates special kind of {@code SSLContext}, which X509TrustManager first checks certificate presence in * in default system-wide trust store (usually located at {@code ${JAVA_HOME}/lib/security/cacerts} or specified by diff --git a/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java b/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java index ed7550fef669..1d223502dfee 100644 --- a/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java +++ b/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 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.util.net.ssl; import com.intellij.openapi.application.Application; @@ -127,8 +142,7 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager { LOG.debug("Image Fetcher thread is detected. Certificate check will be skipped."); return true; } - CertificateManager.Config config = CertificateManager.getInstance().getState(); - if (app.isUnitTestMode() || app.isHeadlessEnvironment() || config.ACCEPT_AUTOMATICALLY) { + if (app.isUnitTestMode() || app.isHeadlessEnvironment() || CertificateManager.getInstance().getState().ACCEPT_AUTOMATICALLY) { LOG.debug("Certificate will be accepted automatically"); if (addToKeyStore) { myCustomManager.addCertificate(endPoint); diff --git a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java index 7a1b2a1fe485..7373293b59ad 100644 --- a/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java +++ b/platform/platform-impl/src/com/intellij/ide/RecentProjectsManagerBase.java @@ -24,7 +24,7 @@ import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.project.ProjectManagerAdapter; import com.intellij.openapi.project.impl.ProjectImpl; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.IconLoader; @@ -42,6 +42,7 @@ import com.intellij.util.ImageLoader; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.EmptyIcon; import com.intellij.util.ui.ImageUtil; import com.intellij.util.ui.JBUI; @@ -64,7 +65,7 @@ import java.util.List; * @author yole * @author Konstantin Bulenkov */ -public abstract class RecentProjectsManagerBase extends RecentProjectsManager implements ProjectManagerListener, PersistentStateComponent { +public abstract class RecentProjectsManagerBase extends RecentProjectsManager implements PersistentStateComponent { private static final Map ourProjectIcons = new HashMap(); private static Icon ourSmallAppIcon; @@ -101,8 +102,12 @@ public abstract class RecentProjectsManagerBase extends RecentProjectsManager im private final Map myNameCache = Collections.synchronizedMap(new THashMap()); - protected RecentProjectsManagerBase(MessageBus messageBus) { - messageBus.connect().subscribe(AppLifecycleListener.TOPIC, new MyAppLifecycleListener()); + protected RecentProjectsManagerBase(@NotNull MessageBus messageBus) { + MessageBusConnection connection = messageBus.connect(); + connection.subscribe(AppLifecycleListener.TOPIC, new MyAppLifecycleListener()); + if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { + connection.subscribe(ProjectManager.TOPIC, new MyProjectListener()); + } } @Override @@ -451,37 +456,34 @@ public abstract class RecentProjectsManagerBase extends RecentProjectsManager im return file.exists() && (!file.isDirectory() || new File(file, Project.DIRECTORY_STORE_FOLDER).exists()); } - @Override - public void projectOpened(final Project project) { - String path = getProjectPath(project); - if (path != null) { - markPathRecent(path); - } - SystemDock.updateMenu(); - } - - @Override - public final boolean canCloseProject(Project project) { - return true; - } - - @Override - public void projectClosing(Project project) { - synchronized (myStateLock) { - myState.names.put(getProjectPath(project), getProjectDisplayName(project)); - } - } - - @Override - public void projectClosed(final Project project) { - Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); - if (openProjects.length > 0) { - String path = getProjectPath(openProjects[openProjects.length - 1]); + private class MyProjectListener extends ProjectManagerAdapter { + @Override + public void projectOpened(final Project project) { + String path = getProjectPath(project); if (path != null) { markPathRecent(path); } + SystemDock.updateMenu(); + } + + @Override + public void projectClosing(Project project) { + synchronized (myStateLock) { + myState.names.put(getProjectPath(project), getProjectDisplayName(project)); + } + } + + @Override + public void projectClosed(final Project project) { + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + if (openProjects.length > 0) { + String path = getProjectPath(openProjects[openProjects.length - 1]); + if (path != null) { + markPathRecent(path); + } + } + SystemDock.updateMenu(); } - SystemDock.updateMenu(); } @NotNull @@ -570,9 +572,6 @@ public abstract class RecentProjectsManagerBase extends RecentProjectsManager im private class MyAppLifecycleListener extends AppLifecycleListener.Adapter { @Override public void appFrameCreated(final String[] commandLineArgs, @NotNull final Ref willOpenProject) { - if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { - ProjectManager.getInstance().addProjectManagerListener(RecentProjectsManagerBase.this); - } if (willReopenProjectOnStart()) { willOpenProject.set(Boolean.TRUE); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseProjectAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseProjectAction.java index 00f62e8f9640..6739bdeedce9 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CloseProjectAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseProjectAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package com.intellij.ide.actions; -import com.intellij.ide.RecentProjectsManager; import com.intellij.ide.impl.ProjectUtil; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -34,7 +33,6 @@ public class CloseProjectAction extends AnAction implements DumbAware { assert project != null; ProjectUtil.closeAndDispose(project); - RecentProjectsManager.getInstance().updateLastProjectPath(); WelcomeFrame.showIfNoProjectOpened(); } diff --git a/platform/platform-impl/src/com/intellij/ide/diff/VirtualFileDiffElement.java b/platform/platform-impl/src/com/intellij/ide/diff/VirtualFileDiffElement.java index 13826a6ae112..8d6585f2b59b 100644 --- a/platform/platform-impl/src/com/intellij/ide/diff/VirtualFileDiffElement.java +++ b/platform/platform-impl/src/com/intellij/ide/diff/VirtualFileDiffElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -290,7 +290,7 @@ public class VirtualFileDiffElement extends DiffElement { if (!docsToSave.isEmpty()) { new WriteAction() { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { for (Document document : docsToSave) { manager.saveDocument(document); } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaProgressBarUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaProgressBarUI.java index ae81b3bcbffe..0d8a22372837 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaProgressBarUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaProgressBarUI.java @@ -41,10 +41,11 @@ public class DarculaProgressBarUI extends BasicProgressBarUI { protected volatile int offset = 0; @Override - protected void paintIndeterminate(Graphics g, JComponent c) { - if (!(g instanceof Graphics2D)) { + protected void paintIndeterminate(Graphics g2d, JComponent c) { + if (!(g2d instanceof Graphics2D)) { return; } + Graphics2D g = (Graphics2D)g2d; Insets b = progressBar.getInsets(); // area for border int barRectWidth = progressBar.getWidth() - (b.right + b.left); @@ -62,15 +63,14 @@ public class DarculaProgressBarUI extends BasicProgressBarUI { } g.setColor(new JBColor(Gray._165, Gray._88)); final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); - g.translate(0, (c.getHeight() - h) / 2); + g.translate(0f, (c.getHeight() - h) / 2f); int x = -offset; - final int R = JBUI.scale(8); - final int R2 = JBUI.scale(9); - final int off = JBUI.scale(1); - final Area aaa = new Area(new RoundRectangle2D.Double(off, off, w - 2*off, h - 2*off, R, R)); + final float R = JBUI.scale(8f); + final float R2 = JBUI.scale(9f); + final Area containingRoundRect = new Area(new RoundRectangle2D.Float(1f, 1f, w - 2f, h - 2f, R, R)); while (x < Math.max(c.getWidth(), c.getHeight())) { Path2D.Double path = new Path2D.Double(); - int ww = getPeriodLength() / 2; + float ww = getPeriodLength() / 2f; path.moveTo(x, 0); path.lineTo(x+ww, 0); path.lineTo(x+ww - h / 2, h); @@ -79,24 +79,24 @@ public class DarculaProgressBarUI extends BasicProgressBarUI { path.closePath(); final Area area = new Area(path); - area.intersect(aaa); - ((Graphics2D)g).fill(area); + area.intersect(containingRoundRect); + g.fill(area); x+= getPeriodLength(); } offset = (offset + 1) % getPeriodLength(); - Area area = new Area(new Rectangle2D.Double(0, 0, w, h)); - area.subtract(new Area(new RoundRectangle2D.Double(off, off, w - 2*off, h - 2*off, R, R))); - ((Graphics2D)g).setPaint(Gray._128); + Area area = new Area(new Rectangle2D.Float(0, 0, w, h)); + area.subtract(new Area(new RoundRectangle2D.Float(1f, 1f, w - 2f, h - 2f, R, R))); + g.setPaint(Gray._128); if (c.isOpaque()) { - ((Graphics2D)g).fill(area); + g.fill(area); } - area.subtract(new Area(new RoundRectangle2D.Double(0, 0, w, h, R2, R2))); - ((Graphics2D)g).setPaint(c.getParent().getBackground()); + area.subtract(new Area(new RoundRectangle2D.Float(0, 0, w, h, R2, R2))); + g.setPaint(c.getParent().getBackground()); if (c.isOpaque()) { - ((Graphics2D)g).fill(area); + g.fill(area); } - g.drawRoundRect(off, off, w - 2*off - 1, h - 2*off - 1, R, R); - g.translate(0, -(c.getHeight() - h)/2); + g.draw(new RoundRectangle2D.Float(1f, 1f, w - 2f - 1f, h - 2f -1f, R, R)); + g.translate(0f, -(c.getHeight() - h)/2f); // Deal with possible text painting if (progressBar.isStringPainted()) { @@ -139,18 +139,17 @@ public class DarculaProgressBarUI extends BasicProgressBarUI { g.fillRect(0, 0, w, h); } - final int R = JBUI.scale(8); - final int R2 = JBUI.scale(9); - final int off = JBUI.scale(1); - + final float R = JBUI.scale(8f); + final float R2 = JBUI.scale(9f); + final float off = JBUI.scale(1f); g2.translate(0, (c.getHeight() - h)/2); g2.setColor(progressBar.getForeground()); - g2.fill(new RoundRectangle2D.Double(0, 0, w - off, h - off, R2, R2)); + g2.fill(new RoundRectangle2D.Float(0, 0, w - off, h - off, R2, R2)); g2.setColor(c.getParent().getBackground()); - g2.fill(new RoundRectangle2D.Double(off, off, w - 2*off - off, h - 2*off - off, R, R)); + g2.fill(new RoundRectangle2D.Float(off, off, w - 2f*off - off, h - 2f*off - off, R, R)); g2.setColor(progressBar.getForeground()); - g2.fill(new RoundRectangle2D.Double(2*off,2*off, amountFull - JBUI.scale(5), h - JBUI.scale(5), JBUI.scale(7), JBUI.scale(7))); + g2.fill(new RoundRectangle2D.Float(2f*off,2f*off, amountFull - JBUI.scale(5f), h - JBUI.scale(5f), JBUI.scale(7f), JBUI.scale(7f))); g2.translate(0, -(c.getHeight() - h)/2); // Deal with possible text painting diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java index 56a05cd794b3..0945bb3f84a8 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java @@ -17,10 +17,7 @@ package com.intellij.idea; import com.intellij.ExtensionPoints; import com.intellij.Patches; -import com.intellij.ide.AppLifecycleListener; -import com.intellij.ide.CommandLineProcessor; -import com.intellij.ide.IdeEventQueue; -import com.intellij.ide.IdeRepaintManager; +import com.intellij.ide.*; import com.intellij.ide.plugins.PluginManager; import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.internal.statistic.UsageTrigger; @@ -298,6 +295,9 @@ public class IdeaApplication { public void main(String[] args) { SystemDock.updateMenu(); + // if OS has dock, RecentProjectsManager will be already created, but not all OS have dock, so, we trigger creation here to ensure that RecentProjectsManager app listener will be added + RecentProjectsManager.getInstance(); + // Event queue should not be changed during initialization of application components. // It also cannot be changed before initialization of application components because IdeEventQueue uses other // application components. So it is proper to perform replacement only here. diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 04dc2c0afc45..b6308e5354b3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -486,7 +486,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App } }); t = System.currentTimeMillis() - t; - LOG.info(getComponentConfigurationsSize() + " application components initialized in " + t + " ms"); + LOG.info(getComponentConfigCount() + " application components initialized in " + t + " ms"); } catch (StateStorageException e) { throw new IOException(e); diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java index f37c522c6463..160445220d24 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/IComponentStore.java @@ -21,6 +21,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import java.util.Collection; import java.util.List; @@ -59,4 +60,7 @@ public interface IComponentStore { */ @Nullable Collection reload(@NotNull MultiMap changedStorages); + + @TestOnly + void saveApplicationComponent(@NotNull Object component); } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java index 1929944edd62..030b39ac084c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java @@ -19,20 +19,15 @@ import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.notification.NotificationsManager; -import com.intellij.openapi.application.AccessToken; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.application.WriteAction; -import com.intellij.openapi.components.RoamingType; -import com.intellij.openapi.components.StateStorage; -import com.intellij.openapi.components.StoragePathMacros; -import com.intellij.openapi.components.TrackingPathMacroSubstitutor; +import com.intellij.openapi.application.*; +import com.intellij.openapi.components.*; import com.intellij.openapi.components.store.ReadOnlyModificationException; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.impl.LoadTextUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.project.ex.ProjectEx; +import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ThrowableComputable; @@ -80,6 +75,22 @@ public class StorageUtil { return event.getRequestor() instanceof StateStorage.SaveSession || event.getRequestor() instanceof StateStorage; } + public static void checkUnknownMacros(@NotNull final ComponentManager componentManager, @NotNull final Project project) { + Application application = ApplicationManager.getApplication(); + if (!application.isHeadlessEnvironment() && !application.isUnitTestMode()) { + // should be invoked last + StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { + @Override + public void run() { + TrackingPathMacroSubstitutor substitutor = ComponentsPackage.getStateStore(componentManager).getStateStorageManager().getMacroSubstitutor(); + if (substitutor != null) { + notifyUnknownMacros(substitutor, project, null); + } + } + }); + } + } + public static void notifyUnknownMacros(@NotNull TrackingPathMacroSubstitutor substitutor, @NotNull final Project project, @Nullable final String componentName) { diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StoreUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StoreUtil.java index 6d0910ca926e..e85271974df8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StoreUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StoreUtil.java @@ -20,23 +20,32 @@ import com.intellij.diagnostic.PluginException; import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; +import com.intellij.openapi.components.StateStorage; import com.intellij.openapi.components.StateStorage.SaveSession; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ShutDownTracker; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + public final class StoreUtil { private static final Logger LOG = Logger.getInstance(StoreUtil.class); @@ -109,4 +118,94 @@ public final class StoreUtil { while ((aClass = aClass.getSuperclass()) != null); return null; } + + @NotNull + public static String getComponentName(@NotNull PersistentStateComponent persistentStateComponent) { + return getStateSpec(persistentStateComponent).name(); + } + + public enum ReloadComponentStoreStatus { + RESTART_AGREED, + RESTART_CANCELLED, + ERROR, + SUCCESS, + } + + @NotNull + public static ReloadComponentStoreStatus reloadStore(@NotNull MultiMap changes, @NotNull IComponentStore store) { + Collection notReloadableComponents; + boolean willBeReloaded = false; + try { + AccessToken token = WriteAction.start(); + try { + notReloadableComponents = store.reload(changes); + } + catch (Throwable e) { + Messages.showWarningDialog(ProjectBundle.message("project.reload.failed", e.getMessage()), + ProjectBundle.message("project.reload.failed.title")); + return ReloadComponentStoreStatus.ERROR; + } + finally { + token.finish(); + } + + if (ContainerUtil.isEmpty(notReloadableComponents)) { + return ReloadComponentStoreStatus.SUCCESS; + } + + willBeReloaded = askToRestart(store, notReloadableComponents, changes); + return willBeReloaded ? ReloadComponentStoreStatus.RESTART_AGREED : ReloadComponentStoreStatus.RESTART_CANCELLED; + } + finally { + if (!willBeReloaded) { + for (StateStorage storage : changes.keySet()) { + if (storage instanceof StateStorageBase) { + ((StateStorageBase)storage).enableSaving(); + } + } + } + } + } + + // used in settings repository plugin + public static boolean askToRestart(@NotNull IComponentStore store, + @NotNull Collection notReloadableComponents, + @Nullable MultiMap changedStorages) { + StringBuilder message = new StringBuilder(); + String storeName = store instanceof IProjectStore ? "Project" : "Application"; + message.append(storeName).append(' '); + message.append("components were changed externally and cannot be reloaded:\n\n"); + int count = 0; + for (String component : notReloadableComponents) { + if (count == 10) { + message.append('\n').append("and ").append(notReloadableComponents.size() - count).append(" more").append('\n'); + } + else { + message.append(component).append('\n'); + count++; + } + } + + message.append("\nWould you like to "); + if (store instanceof IProjectStore) { + message.append("reload project?"); + } + else { + message.append(ApplicationManager.getApplication().isRestartCapable() ? "restart" : "shutdown").append(' '); + message.append(ApplicationNamesInfo.getInstance().getProductName()).append('?'); + } + + if (Messages.showYesNoDialog(message.toString(), + storeName + " Files Changed", Messages.getQuestionIcon()) == Messages.YES) { + if (changedStorages != null) { + for (StateStorage storage : changedStorages.keySet()) { + if (storage instanceof StateStorageBase) { + ((StateStorageBase)storage).disableSaving(); + } + } + } + return true; + } + return false; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/service.kt b/platform/platform-impl/src/com/intellij/openapi/components/service.kt index 247b0cf2d085..04b41a0a9029 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/service.kt +++ b/platform/platform-impl/src/com/intellij/openapi/components/service.kt @@ -24,6 +24,6 @@ public inline fun service(): T? = ServiceManager.getService(jav public inline fun Project.service(): T? = ServiceManager.getService(this, javaClass()) public val ComponentManager.stateStore: IComponentStore - get() = getPicoContainer().getComponentInstance(javaClass()) as IComponentStore + get() = if (this is Project) getPicoContainer().getComponentInstance(javaClass()) as IComponentStore else getPicoContainer().getComponentInstance(javaClass().getName()) as IComponentStore -public fun ComponentManager.getComponents(baseClass: Class): List = (this as ComponentManagerEx).getComponentInstancesOfType(baseClass) +public fun ComponentManager.getComponents(baseClass: Class): List = (this as ComponentManagerEx).getComponentInstancesOfType(baseClass) \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 7dbad595a8f9..30fd0297d9d8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -6114,7 +6114,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (myMousePressedEvent != null && myMousePressedEvent.getComponent() == e.getComponent()) { Point lastPoint = myMousePressedEvent.getPoint(); Point point = e.getPoint(); - int deadZone = Registry.intValue("editor.mouseSelectionStateResetDeadZone", 4); + int deadZone = Registry.intValue("editor.mouseSelectionStateResetDeadZone"); if (Math.abs(lastPoint.x - point.x) >= deadZone || Math.abs(lastPoint.y - point.y) >= deadZone) { resetMouseSelectionState(e); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java index cc9d978cde6d..931d829683b2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -86,9 +86,9 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent private static final Key DETECTED_FROM_CONTENT_FILE_TYPE_KEY = Key.create("DETECTED_FROM_CONTENT_FILE_TYPE_KEY"); private static final int DETECT_BUFFER_SIZE = 8192; // the number of bytes to read from the file to feed to the file type detector - @NonNls + // must be sorted private static final String DEFAULT_IGNORED = - "*.hprof;*.pyc;*.pyo;*.rbc;*~;.DS_Store;.git;.hg;.svn;CVS;RCS;SCCS;__pycache__;.tox;_svn;rcs;vssver.scc;vssver2.scc;"; + "*.hprof;*.pyc;*.pyo;*.rbc;*~;.DS_Store;.git;.hg;.svn;.tox;CVS;RCS;SCCS;__pycache__;_svn;rcs;vssver.scc;vssver2.scc;"; private static boolean RE_DETECT_ASYNC = !ApplicationManager.getApplication().isUnitTestMode(); private final Set myDefaultTypes = new THashSet(); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java index 2b24b65bef43..a42f55f9ca11 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java @@ -97,8 +97,10 @@ class ConfigurableEditor extends AbstractEditor implements AnActionListener, AWT add(BorderLayout.CENTER, myCardPanel); ActionManager.getInstance().addAnActionListener(this, this); getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.KEY_EVENT_MASK); - myConfigurable = configurable; - myCardPanel.select(configurable, true); + if (configurable != null) { + myConfigurable = configurable; + myCardPanel.select(configurable, true); + } updateCurrent(configurable, false); } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java index 075cc56bdcc1..68a924f6551e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java @@ -25,6 +25,7 @@ import com.intellij.openapi.options.ex.ConfigurableVisitor; import com.intellij.openapi.options.ex.ConfigurableWrapper; import com.intellij.openapi.options.ex.Settings; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.LoadingDecorator; import com.intellij.openapi.ui.OnePixelDivider; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; @@ -61,6 +62,7 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { private final ConfigurableEditor myEditor; private final OnePixelSplitter mySplitter; private final SpotlightPainter mySpotlightPainter; + private final LoadingDecorator myLoadingDecorator; private final Banner myBanner; SettingsEditor(Disposable parent, Project project, ConfigurableGroup[] groups, Configurable configurable, final String filter) { @@ -110,9 +112,17 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { public ActionCallback onSelected(@Nullable Configurable configurable, Configurable oldConfigurable) { if (configurable != null) { myProperties.setValue(SELECTED_CONFIGURABLE, ConfigurableVisitor.ByID.getID(configurable)); + myLoadingDecorator.startLoading(false); } checkModified(oldConfigurable); - return myEditor.select(configurable); + ActionCallback result = myEditor.select(configurable); + result.doWhenDone(new Runnable() { + @Override + public void run() { + myLoadingDecorator.stopLoading(); + } + }); + return result; } @Override @@ -181,10 +191,11 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { mySettings.select(configurable); } }; + myLoadingDecorator = new LoadingDecorator(myEditor, this, 10, true); myBanner = new Banner(myEditor.getResetAction()); mySearchPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JComponent left = myTreeView; - JComponent right = myEditor; + JComponent right = myLoadingDecorator.getComponent(); if (Registry.is("ide.settings.old.style")) { myBanner.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10)); mySearch.setBackground(UIUtil.SIDE_PANEL_BACKGROUND); @@ -206,7 +217,7 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { right = new JPanel(new BorderLayout()); right.add(BorderLayout.NORTH, myBanner); - right.add(BorderLayout.CENTER, myEditor); + right.add(BorderLayout.CENTER, myLoadingDecorator.getComponent()); } else { myBanner.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java index c9246376689d..a4f2cb6aba8e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java @@ -299,7 +299,7 @@ public class AbstractProgressIndicatorExBase extends AbstractProgressIndicatorBa } } - private void delegateProgressChange(@NotNull IndicatorAction action) { + protected void delegateProgressChange(@NotNull IndicatorAction action) { delegate(action); onProgressChange(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java index 948d347913da..28c0cef35537 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java @@ -16,11 +16,9 @@ package com.intellij.openapi.project; import com.intellij.ide.IdeBundle; +import com.intellij.ide.startup.StartupManagerEx; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.AccessToken; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.progress.*; @@ -63,6 +61,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica private final Queue myRunWhenSmartQueue = new Queue(5); private final Project myProject; private final ThreadLocal myAlternativeResolution = new ThreadLocal(); + private final Map myPermissions = ContainerUtil.newHashMap(); public DumbServiceImpl(Project project) { myProject = project; @@ -109,6 +108,23 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica return myAlternativeResolution.get() != null; } + @Override + public void allowStartingDumbModeInside(@NotNull DumbModePermission permission, @NotNull Runnable runnable) { + ApplicationManager.getApplication().assertIsDispatchThread(); + ModalityState modality = ModalityState.current(); + DumbModePermission prev = myPermissions.put(modality, permission); + try { + runnable.run(); + } + finally { + if (prev == null) { + myPermissions.remove(modality); + } else { + myPermissions.put(modality, prev); + } + } + } + @Override public void setAlternativeResolveEnabled(boolean enabled) { Integer oldValue = myAlternativeResolution.get(); @@ -151,7 +167,8 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica } private void scheduleCacheUpdate(@NotNull final DumbModeTask task, boolean forceDumbMode) { - if (LOG.isDebugEnabled()) LOG.debug("Scheduling task " + task, new Throwable()); + final Throwable trace = new Throwable(); + if (LOG.isDebugEnabled()) LOG.debug("Scheduling task " + task, trace); final Application application = ApplicationManager.getApplication(); if (application.isUnitTestMode() || @@ -181,13 +198,14 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica if (myProject.isDisposed()) { return; } - final ProgressIndicatorBase indicator = new ProgressIndicatorBase() { - @Override - protected void delegateRunningChange(@NotNull AbstractProgressIndicatorExBase.IndicatorAction action) { - // don't delegate lifecycle events to the global indicator as several independent tasks may run under it sequentially - } - }; - myProgresses.put(task, indicator); + + ModalityState modality = ModalityState.current(); + final DumbModePermission permission = getDumbModePermission(modality); + if (permission == null) { + LOG.error("Dumb mode not permitted in modal envirnonment; please use DumbService.allowStartingDumbModeInside in your dialog or invokeLater(..., NON_MODAL)", trace); + } + + myProgresses.put(task, new ProgressIndicatorBase()); Disposer.register(task, new Disposable() { @Override public void dispose() { @@ -200,37 +218,60 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica if (!myDumb) { // always change dumb status inside write action. // This will ensure all active read actions are completed before the app goes dumb - boolean startSuccess = - application.runWriteAction(new Computable() { - @Override - public Boolean compute() { - myDumb = true; - myModificationCount++; - try { - myPublisher.enteredDumbMode(); - } - catch (Throwable e) { - LOG.error(e); - } - - try { - startBackgroundProcess(); - } - catch (Throwable e) { - LOG.error("Failed to start background index update task", e); - return false; - } - return true; + application.runWriteAction(new Runnable() { + @Override + public void run() { + myDumb = true; + myModificationCount++; + try { + myPublisher.enteredDumbMode(); } - }); - if (!startSuccess) { - updateFinished(); - } + catch (Throwable e) { + LOG.error(e); + } + } + }); + + // later because we're likely in a write action and can't start a modal progress immediately + // and for a background progress, it doesn't matter if it starts several milliseconds later; dumb mode is already on + application.invokeLater(new Runnable() { + @Override + public void run() { + boolean modal = permission != DumbModePermission.MAY_START_BACKGROUND; + boolean shouldFinish = modal; + try { + startBackgroundProcess(modal); + } + catch (Throwable e) { + shouldFinish = true; + LOG.error("Failed to start background index update task", e); + } + finally { + if (shouldFinish) { + updateFinished(); + } + } + } + }, modality, myProject.getDisposed()); } } }); } + @Nullable + private DumbModePermission getDumbModePermission(ModalityState modality) { + DumbModePermission permission = myPermissions.get(modality); + if (permission != null) { + return permission; + } + + if (modality == ModalityState.NON_MODAL || !StartupManagerEx.getInstanceEx(myProject).postStartupActivityPassed()) { + return DumbModePermission.MAY_START_BACKGROUND; + } + + return null; + } + private void updateFinished() { myDumb = false; myModificationCount++; @@ -349,7 +390,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica }, modalityState, myProject.getDisposed()); } - private void startBackgroundProcess() { + private void startBackgroundProcess(final boolean modal) { ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) { @Override @@ -372,7 +413,13 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica task = pair.first; ProgressIndicatorEx taskIndicator = pair.second; if (visibleIndicator instanceof ProgressIndicatorEx) { - taskIndicator.addStateDelegate((ProgressIndicatorEx)visibleIndicator); + taskIndicator.addStateDelegate(new AbstractProgressIndicatorExBase() { + @Override + protected void delegateProgressChange(@NotNull IndicatorAction action) { + super.delegateProgressChange(action); + action.execute((ProgressIndicatorEx)visibleIndicator); + } + }); } runSingleTask(task, taskIndicator); } @@ -385,6 +432,15 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica token.finish(); } } + + public boolean isConditionalModal() { + return modal; + } + + @Override + public boolean shouldStartInBackground() { + return !modal; + } }); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java index f441b5cfcaf0..39ccdfc2b07c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java @@ -295,7 +295,7 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project } long time = System.currentTimeMillis() - start; - LOG.info(getComponentConfigurationsSize() + " project components initialized in " + time + " ms"); + LOG.info(getComponentConfigCount() + " project components initialized in " + time + " ms"); getMessageBus().syncPublisher(ProjectLifecycleListener.TOPIC).projectComponentsInitialized(this); diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index c4b3c5b71753..97208bb9feda 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -19,7 +19,6 @@ import com.intellij.CommonBundle; import com.intellij.conversion.ConversionResult; import com.intellij.conversion.ConversionService; import com.intellij.ide.AppLifecycleListener; -import com.intellij.ide.RecentProjectsManager; import com.intellij.ide.impl.ProjectUtil; import com.intellij.ide.plugins.PluginManager; import com.intellij.ide.startup.StartupManagerEx; @@ -33,7 +32,7 @@ import com.intellij.openapi.application.*; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.*; import com.intellij.openapi.components.impl.stores.*; -import com.intellij.openapi.components.impl.stores.ComponentStoreImpl.ReloadComponentStoreStatus; +import com.intellij.openapi.components.impl.stores.StoreUtil.ReloadComponentStoreStatus; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.*; @@ -118,10 +117,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt return array; } - /** @noinspection UnusedParameters*/ - public ProjectManagerImpl(@NotNull VirtualFileManager virtualFileManager, - RecentProjectsManager recentProjectsManager, - ProgressManager progressManager) { + public ProjectManagerImpl(@NotNull VirtualFileManager virtualFileManager, ProgressManager progressManager) { myProgressManager = progressManager; Application app = ApplicationManager.getApplication(); MessageBus messageBus = app.getMessageBus(); @@ -486,18 +482,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt return false; } - if (!application.isHeadlessEnvironment() && !application.isUnitTestMode()) { - // should be invoked last - startupManager.runWhenProjectIsInitialized(new Runnable() { - @Override - public void run() { - TrackingPathMacroSubstitutor substitutor = ((ProjectEx)project).getStateStore().getStateStorageManager().getMacroSubstitutor(); - if (substitutor != null) { - StorageUtil.notifyUnknownMacros(substitutor, project, null); - } - } - }); - } + StorageUtil.checkUnknownMacros(project, project); return true; } @@ -654,7 +639,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } CHANGED_FILES_KEY.set(project, null); - if (!changes.isEmpty() && ComponentStoreImpl.reloadStore(changes, ((ProjectEx)project).getStateStore()) == ReloadComponentStoreStatus.RESTART_AGREED) { + if (!changes.isEmpty() && StoreUtil.reloadStore(changes, ((ProjectEx)project).getStateStore()) == ReloadComponentStoreStatus.RESTART_AGREED) { projectsToReload.add(project); } } @@ -676,7 +661,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt changes.putAllValues(myChangedApplicationFiles); myChangedApplicationFiles.clear(); - ReloadComponentStoreStatus status = ComponentStoreImpl.reloadStore(changes, ComponentsPackage.getStateStore(ApplicationManager.getApplication())); + ReloadComponentStoreStatus status = StoreUtil.reloadStore(changes, ComponentsPackage.getStateStore(ApplicationManager.getApplication())); if (status == ReloadComponentStoreStatus.RESTART_AGREED) { ApplicationManagerEx.getApplicationEx().restart(true); return false; diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java index f77091c877bf..72b4763f9045 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java @@ -239,14 +239,8 @@ class UpdateInfoDialog extends AbstractUpdateDialog { } } - private String formatVersion(String version, String build) { - String[] parts = version.split("\\.", 3); - String major = parts.length > 0 ? parts[0] : "0"; - String minor = parts.length > 1 ? parts[1] : "0"; - String patch = parts.length > 2 ? parts[2] : "0"; - version = major + '.' + minor + '.' + patch; - - return IdeBundle.message("updates.version.info", version, build); + protected String formatVersion(String version, String build) { + return IdeBundle.message("updates.version.info", StringUtil.formatVersionToMajorMinorPatchString(version), build); } } } 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 d52fd21957a1..491c20689f86 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 @@ -35,9 +35,10 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.fileEditor.impl.EditorsSplitters; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; +import com.intellij.openapi.progress.util.ProgressIndicatorUtils; +import com.intellij.openapi.progress.util.ReadTask; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; @@ -488,22 +489,32 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements initToolWindow(bean); } else { - ProgressManager.getInstance().run( - new Task.Backgroundable(myProject, bean.id + " initialization", true) { + checkConditionInReadAction(bean, condition); + } + } + } + + private void checkConditionInReadAction(@NotNull final ToolWindowEP bean, @NotNull final Condition condition) { + ProgressIndicatorUtils.scheduleWithWriteActionPriority(new ReadTask() { + @Override + public void computeInReadAction(@NotNull ProgressIndicator indicator) throws ProcessCanceledException { + if (!myProject.isDisposed() && condition.value(myProject)) { + ApplicationManager.getApplication().invokeLater(new Runnable() { @Override - public void run(@NotNull ProgressIndicator indicator) { - if (condition.value(myProject)) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - initToolWindow(bean); - } - }); + public void run() { + if (!myProject.isDisposed()) { + initToolWindow(bean); } } }); + } } - } + + @Override + public void onCanceled(@NotNull ProgressIndicator indicator) { + checkConditionInReadAction(bean, condition); + } + }); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java index 3713625dcce9..74941d65a1a6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java @@ -236,7 +236,7 @@ public class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidge private void removeProgress(@NotNull InlineProgressIndicator progress) { synchronized (myOriginals) { - LOG.assertTrue(myInline2Original.containsKey(progress)); + if (!myInline2Original.containsKey(progress)) return; // already disposed final boolean last = myOriginals.size() == 1; final boolean beforeLast = myOriginals.size() == 2; diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 4dceab2e8552..c5fcd9447644 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -136,7 +136,7 @@ title.edit.file.template=Edit File Template checkbox.reformat.according.to.style=Reformat according to style label.description=Description item.file.templates=File templates -tab.filetemplates.templates=Templates +tab.filetemplates.templates=Files tab.filetemplates.includes=Includes tab.filetemplates.code=Code tab.filetemplates.j2ee=Other diff --git a/platform/platform-resources-en/src/messages/XmlBundle.properties b/platform/platform-resources-en/src/messages/XmlBundle.properties index aa754f09f720..d615cd88a6e6 100644 --- a/platform/platform-resources-en/src/messages/XmlBundle.properties +++ b/platform/platform-resources-en/src/messages/XmlBundle.properties @@ -26,7 +26,7 @@ html.inspections.check.image.size=Image size mismatch html.inspections.check.empty.tag=Empty tag html.inspections.check.valid.script.tag=Malformed content of