diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultManifestFileProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultManifestFileProvider.java new file mode 100644 index 000000000000..c80617b1553c --- /dev/null +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultManifestFileProvider.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2011 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.packaging.impl.artifacts; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.packaging.artifacts.ArtifactType; +import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.elements.ManifestFileProvider; +import com.intellij.packaging.elements.PackagingElementResolvingContext; +import com.intellij.packaging.impl.elements.ManifestFileUtil; +import com.intellij.packaging.ui.ManifestFileConfiguration; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** +* @author nik +*/ +public class DefaultManifestFileProvider implements ManifestFileProvider { + private final PackagingElementResolvingContext myContext; + + public DefaultManifestFileProvider(PackagingElementResolvingContext context) { + myContext = context; + } + + @Override + public List getClasspathFromManifest(@NotNull CompositePackagingElement archiveRoot, @NotNull ArtifactType artifactType) { + final VirtualFile manifestFile = ManifestFileUtil.findManifestFile(archiveRoot, myContext, artifactType); + if (manifestFile == null) { + return null; + } + + ManifestFileConfiguration configuration = ManifestFileUtil.createManifestFileConfiguration(manifestFile); + return configuration.getClasspath(); + } +} diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultPackagingElementResolvingContext.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultPackagingElementResolvingContext.java index 8c3d162e6b52..16000b44f540 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultPackagingElementResolvingContext.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultPackagingElementResolvingContext.java @@ -25,6 +25,7 @@ import com.intellij.openapi.roots.ui.configuration.FacetsProvider; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.packaging.artifacts.ArtifactManager; import com.intellij.packaging.artifacts.ArtifactModel; +import com.intellij.packaging.elements.ManifestFileProvider; import com.intellij.packaging.elements.PackagingElementResolvingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,6 +66,12 @@ public class DefaultPackagingElementResolvingContext implements PackagingElement return findLibrary(myProject, level, libraryName); } + @NotNull + @Override + public ManifestFileProvider getManifestFileProvider() { + return new DefaultManifestFileProvider(this); + } + @Nullable public static Library findLibrary(Project project, String level, String libraryName) { LibraryTable table = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(level, project); diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementPath.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementPath.java index f529962749fb..dda0981ffcdd 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementPath.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementPath.java @@ -49,15 +49,6 @@ public class PackagingElementPath { return new PackagingElementPath(this, element); } - @Nullable - public PackagingElementPath getParentPath() { - return myParentPath; - } - - public PackagingElement getLastElement() { - return myLastElement; - } - @NotNull public String getPathString() { return getPathString("/"); @@ -123,10 +114,6 @@ public class PackagingElementPath { } return null; } - - public boolean isEmpty() { - return myParentPath == null; - } @Nullable public Artifact findLastArtifact(PackagingElementResolvingContext context) { @@ -140,4 +127,12 @@ public class PackagingElementPath { } return null; } + + public static PackagingElementPath createPath(@NotNull List> elements) { + PackagingElementPath path = EMPTY; + for (PackagingElement element : elements) { + path = new PackagingElementPath(path, element); + } + return path; + } } diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java index 3c887decd6f7..6825a8c9c95d 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java @@ -15,7 +15,7 @@ */ package com.intellij.packaging.impl.ui; -import com.intellij.packaging.ui.ArtifactEditorContext; +import com.intellij.packaging.elements.PackagingElementResolvingContext; import com.intellij.packaging.ui.ArtifactProblemsHolder; import org.jetbrains.annotations.NotNull; @@ -23,13 +23,13 @@ import org.jetbrains.annotations.NotNull; * @author nik */ public abstract class ArtifactProblemsHolderBase implements ArtifactProblemsHolder { - private final ArtifactEditorContext myContext; + private final PackagingElementResolvingContext myContext; - protected ArtifactProblemsHolderBase(ArtifactEditorContext context) { + protected ArtifactProblemsHolderBase(PackagingElementResolvingContext context) { myContext = context; } - public ArtifactEditorContext getContext() { + public PackagingElementResolvingContext getContext() { return myContext; } diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java new file mode 100644 index 000000000000..599c07f69d0e --- /dev/null +++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2011 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.packaging.elements; + +import com.intellij.packaging.artifacts.ArtifactType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author nik + */ +public interface ManifestFileProvider { + @Nullable + List getClasspathFromManifest(@NotNull CompositePackagingElement archiveRoot, @NotNull ArtifactType artifactType); + +} diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java index 487730c2a1f2..a033d3ce9696 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java +++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java @@ -41,4 +41,7 @@ public interface PackagingElementResolvingContext { @Nullable Library findLibrary(@NotNull String level, @NotNull String libraryName); + + @NotNull + ManifestFileProvider getManifestFileProvider(); } diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java index 17bd78a22e99..851ce79497a2 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java +++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java @@ -33,5 +33,5 @@ public abstract class ArtifactProblemQuickFix { return myActionName; } - public abstract void performFix(ArtifactEditor artifactEditor); + public abstract void performFix(ArtifactEditorContext artifactEditorContext); } diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java index 1fa2d6a4f3ba..71ad4f0b369b 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java +++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java @@ -16,6 +16,7 @@ package com.intellij.packaging.ui; import com.intellij.packaging.elements.PackagingElement; +import com.intellij.packaging.elements.PackagingElementResolvingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,7 +27,7 @@ import java.util.List; */ public interface ArtifactProblemsHolder { - ArtifactEditorContext getContext(); + PackagingElementResolvingContext getContext(); void registerError(@NotNull String message); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java index e55af48bc8bb..f541326f0ec5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java @@ -35,6 +35,7 @@ import com.intellij.packaging.artifacts.ArtifactModel; import com.intellij.packaging.artifacts.ArtifactType; import com.intellij.packaging.artifacts.ModifiableArtifactModel; import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.elements.ManifestFileProvider; import com.intellij.packaging.impl.ui.ChooseArtifactsDialog; import com.intellij.packaging.ui.ArtifactEditor; import com.intellij.packaging.ui.ArtifactEditorContext; @@ -158,6 +159,12 @@ public class ArtifactEditorContextImpl implements ArtifactEditorContext { return myParent.findLibrary(level, libraryName); } + @NotNull + @Override + public ManifestFileProvider getManifestFileProvider() { + return myParent.getManifestFileProvider(); + } + public void queueValidation() { myParent.queueValidation(getArtifact()); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorManifestFileProvider.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorManifestFileProvider.java new file mode 100644 index 000000000000..1735ce9d1a0a --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorManifestFileProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2011 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.artifacts; + +import com.intellij.packaging.artifacts.ArtifactType; +import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.elements.ManifestFileProvider; +import com.intellij.packaging.ui.ManifestFileConfiguration; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** +* @author nik +*/ +public class ArtifactEditorManifestFileProvider implements ManifestFileProvider { + private ArtifactsStructureConfigurableContext myArtifactsStructurContext; + + public ArtifactEditorManifestFileProvider(ArtifactsStructureConfigurableContext artifactsStructurContext) { + myArtifactsStructurContext = artifactsStructurContext; + } + + @Override + public List getClasspathFromManifest(@NotNull CompositePackagingElement archiveRoot, @NotNull ArtifactType artifactType) { + final ManifestFileConfiguration manifestFile = myArtifactsStructurContext.getManifestFile(archiveRoot, artifactType); + return manifestFile != null ? manifestFile.getClasspath() : null; + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java index 9ec2fd7febcd..a728d3e4c86a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactErrorPanel.java @@ -15,11 +15,11 @@ */ package com.intellij.openapi.roots.ui.configuration.artifacts; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ConfigurationErrorQuickFix; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.IconLoader; -import com.intellij.packaging.ui.ArtifactProblemQuickFix; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; @@ -37,7 +37,7 @@ public class ArtifactErrorPanel { private JPanel myMainPanel; private JButton myFixButton; private JLabel myErrorLabel; - private List myCurrentQuickFixes; + private List myCurrentQuickFixes; private String myErrorText; public ArtifactErrorPanel(final ArtifactEditorImpl artifactEditor) { @@ -58,15 +58,15 @@ public class ArtifactErrorPanel { performFix(ContainerUtil.getFirstItem(myCurrentQuickFixes, null), artifactEditor); } else { - JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(null, myCurrentQuickFixes) { + JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(null, myCurrentQuickFixes) { @NotNull @Override - public String getTextFor(ArtifactProblemQuickFix value) { + public String getTextFor(ConfigurationErrorQuickFix value) { return value.getActionName(); } @Override - public PopupStep onChosen(ArtifactProblemQuickFix selectedValue, boolean finalChoice) { + public PopupStep onChosen(ConfigurationErrorQuickFix selectedValue, boolean finalChoice) { performFix(selectedValue, artifactEditor); return FINAL_CHOICE; } @@ -78,12 +78,12 @@ public class ArtifactErrorPanel { clearError(); } - private static void performFix(ArtifactProblemQuickFix quickFix, ArtifactEditorImpl artifactEditor) { - quickFix.performFix(artifactEditor); + private static void performFix(ConfigurationErrorQuickFix quickFix, ArtifactEditorImpl artifactEditor) { + quickFix.performFix(); artifactEditor.queueValidation(); } - public void showError(@NotNull String message, @NotNull List quickFixes) { + public void showError(@NotNull String message, @NotNull List quickFixes) { myErrorLabel.setVisible(true); final String errorText = "" + message + ""; if (myErrorLabel.isShowing()) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java index 20317b52c8d1..2670cae27212 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java @@ -18,36 +18,24 @@ package com.intellij.openapi.roots.ui.configuration.artifacts; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ConfigurationErrorQuickFix; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.packaging.elements.PackagingElement; -import com.intellij.packaging.ui.ArtifactProblemQuickFix; -import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collections; import java.util.List; /** * @author nik */ public class ArtifactProblemDescription extends ProjectStructureProblemDescription { - private List myQuickFixes; - private List> myPathToPlace; + private final List> myPathToPlace; - public ArtifactProblemDescription(@NotNull String message, - @NotNull Severity severity, - @Nullable List> pathToPlace, - @NotNull List quickFixes, @NotNull Place place) { - super(message, null, severity, place, Collections.emptyList()); + public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity, @Nullable List> pathToPlace, + @NotNull PlaceInArtifact place, final List quickFixList) { + super(message, null, severity, place, quickFixList); myPathToPlace = pathToPlace; - myQuickFixes = quickFixes; } - @NotNull - public List getQuickFixes() { - return myQuickFixes; - } - - @Nullable + @Nullable public List> getPathToPlace() { return myPathToPlace; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java index 380260c8885f..a9753945e350 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java @@ -15,28 +15,35 @@ */ package com.intellij.openapi.roots.ui.configuration.artifacts; -import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ConfigurationErrorQuickFix; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolder; +import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.elements.PackagingElement; +import com.intellij.packaging.impl.artifacts.PackagingElementPath; import com.intellij.packaging.impl.ui.ArtifactProblemsHolderBase; -import com.intellij.packaging.ui.ArtifactEditorContext; +import com.intellij.packaging.ui.ArtifactEditor; import com.intellij.packaging.ui.ArtifactProblemQuickFix; -import com.intellij.ui.navigation.Place; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.List; /** * @author nik */ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase { + private final ArtifactsStructureConfigurableContext myContext; + private final Artifact myOriginalArtifact; private final ProjectStructureProblemsHolder myProblemsHolder; - public ArtifactProblemsHolderImpl(ArtifactEditorContext context, ProjectStructureProblemsHolder problemsHolder) { + public ArtifactProblemsHolderImpl(ArtifactsStructureConfigurableContext context, + Artifact originalArtifact, + ProjectStructureProblemsHolder problemsHolder) { super(context); + myContext = context; + myOriginalArtifact = originalArtifact; myProblemsHolder = problemsHolder; } @@ -46,9 +53,19 @@ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase { private void registerProblem(@NotNull String message, @Nullable List> pathToPlace, final ProjectStructureProblemDescription.Severity severity, @NotNull ArtifactProblemQuickFix... quickFixes) { - final ArtifactEditorContext context = getContext(); - final Place place = ProjectStructureConfigurable.getInstance(context.getProject()).createArtifactPlace(context.getArtifact()); - myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, Arrays.asList(quickFixes), place)); + String parentPath; + PackagingElement element; + if (pathToPlace != null && !pathToPlace.isEmpty()) { + parentPath = PackagingElementPath.createPath(pathToPlace.subList(0, pathToPlace.size()-1)).getPathString(); + element = pathToPlace.get(pathToPlace.size() - 1); + } + else { + parentPath = null; + element = null; + } + final Artifact artifact = myContext.getArtifactModel().getArtifactByOriginal(myOriginalArtifact); + final PlaceInArtifact place = new PlaceInArtifact(artifact, myContext, parentPath, element); + myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, place, convertQuickFixes(quickFixes))); } public void registerWarning(@NotNull String message, @@ -56,4 +73,18 @@ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase { @NotNull ArtifactProblemQuickFix... quickFixes) { registerProblem(message, pathToPlace, ProjectStructureProblemDescription.Severity.WARNING, quickFixes); } + + private List convertQuickFixes(ArtifactProblemQuickFix[] quickFixes) { + final List result = new SmartList(); + for (final ArtifactProblemQuickFix fix : quickFixes) { + result.add(new ConfigurationErrorQuickFix(fix.getActionName()) { + @Override + public void performFix() { + final ArtifactEditor editor = myContext.getOrCreateEditor(myOriginalArtifact); + fix.performFix(((ArtifactEditorEx)editor).getContext()); + } + }); + } + return result; + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java index 630f125a7b43..9c1643282e08 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProjectStructureElement.java @@ -51,9 +51,9 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement { @Override public void check(final ProjectStructureProblemsHolder problemsHolder) { - final ArtifactEditorEx artifactEditor = (ArtifactEditorEx)myArtifactsStructureContext.getOrCreateEditor(myOriginalArtifact); - final Artifact artifact = artifactEditor.getArtifact(); - artifact.getArtifactType().checkRootElement(artifactEditor.getRootElement(), artifact, new ArtifactProblemsHolderImpl(artifactEditor.getContext(), problemsHolder)); + final Artifact artifact = myArtifactsStructureContext.getArtifactModel().getArtifactByOriginal(myOriginalArtifact); + final ArtifactProblemsHolderImpl artifactProblemsHolder = new ArtifactProblemsHolderImpl(myArtifactsStructureContext, myOriginalArtifact, problemsHolder); + artifact.getArtifactType().checkRootElement(myArtifactsStructureContext.getRootElement(myOriginalArtifact), artifact, artifactProblemsHolder); } public Artifact getOriginalArtifact() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java index 5683bd0ad89b..e7220350e294 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java @@ -17,12 +17,12 @@ package com.intellij.openapi.roots.ui.configuration.artifacts; import com.intellij.openapi.Disposable; import com.intellij.openapi.roots.ui.configuration.artifacts.nodes.PackagingElementNode; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ConfigurationErrorQuickFix; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolderImpl; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.packaging.elements.PackagingElement; -import com.intellij.packaging.ui.ArtifactProblemQuickFix; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -73,16 +73,16 @@ public class ArtifactValidationManagerImpl implements Disposable { if (problemDescriptions != null) { for (ProjectStructureProblemDescription description : problemDescriptions) { final String message = description.getMessage(); - List quickFix = Collections.emptyList(); + List quickFixes = Collections.emptyList(); if (description instanceof ArtifactProblemDescription) { final ArtifactProblemDescription artifactProblem = (ArtifactProblemDescription)description; - quickFix = artifactProblem.getQuickFixes(); + quickFixes = artifactProblem.getFixes(); if (artifactProblem.getPathToPlace() != null) { myProblems.add(artifactProblem); showProblemInTree(artifactProblem); } } - myErrorPanel.showError(message, quickFix); + myErrorPanel.showError(message, quickFixes); } } } 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 a241432298ba..3d7b8196c7c7 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 @@ -32,16 +32,14 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStr import com.intellij.openapi.util.Disposer; import com.intellij.packaging.artifacts.*; import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.elements.ManifestFileProvider; import com.intellij.packaging.impl.artifacts.ArtifactUtil; import com.intellij.packaging.impl.artifacts.DefaultPackagingElementResolvingContext; import com.intellij.packaging.ui.ManifestFileConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * @author nik @@ -57,6 +55,7 @@ public class ArtifactsStructureConfigurableContextImpl implements ArtifactsStruc private final Map myEditorSettings = new HashMap(); private final Map myArtifactElements = new HashMap(); private final ArtifactEditorSettings myDefaultSettings; + private final ManifestFileProvider myManifestFileProvider = new ArtifactEditorManifestFileProvider(this); public ArtifactsStructureConfigurableContextImpl(StructureConfigurableContext context, Project project, ArtifactEditorSettings defaultSettings, final ArtifactAdapter modifiableModelListener) { @@ -203,6 +202,12 @@ public class ArtifactsStructureConfigurableContextImpl implements ArtifactsStruc return library != null ? myContext.getLibraryModel(library) : myContext.getLibrary(libraryName, level); } + @NotNull + @Override + public ManifestFileProvider getManifestFileProvider() { + return myManifestFileProvider; + } + public ManifestFileConfiguration getManifestFile(CompositePackagingElement element, ArtifactType artifactType) { return myManifestFilesInfo.getManifestFile(element, artifactType, this); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/PlaceInArtifact.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/PlaceInArtifact.java new file mode 100644 index 000000000000..8580edea68ce --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/PlaceInArtifact.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2011 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.artifacts; + +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.PlaceInProjectStructure; +import com.intellij.openapi.util.ActionCallback; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.elements.PackagingElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class PlaceInArtifact extends PlaceInProjectStructure { + private final Artifact myArtifact; + private final ArtifactsStructureConfigurableContext myContext; + private final String myParentPath; + private final PackagingElement myPackagingElement; + + public PlaceInArtifact(Artifact artifact, ArtifactsStructureConfigurableContext context, @Nullable String parentPath, + @Nullable PackagingElement packagingElement) { + myArtifact = artifact; + myContext = context; + myParentPath = parentPath; + myPackagingElement = packagingElement; + } + + @NotNull + @Override + public ActionCallback navigate() { + final Artifact artifact = myContext.getArtifactModel().getArtifactByOriginal(myArtifact); + return ProjectStructureConfigurable.getInstance(myContext.getProject()).select(myArtifact, true).doWhenDone(new Runnable() { + public void run() { + final ArtifactEditorEx artifactEditor = (ArtifactEditorEx)myContext.getOrCreateEditor(artifact); + if (myParentPath != null && myPackagingElement != null) { + artifactEditor.getLayoutTreeComponent().selectNode(myParentPath, myPackagingElement); + } + } + }); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/UsageInArtifact.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/UsageInArtifact.java index 087298d522ce..72ec74a4e222 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/UsageInArtifact.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/UsageInArtifact.java @@ -1,6 +1,6 @@ package com.intellij.openapi.roots.ui.configuration.artifacts; -import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.PlaceInProjectStructure; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElementUsage; import com.intellij.packaging.artifacts.Artifact; @@ -40,17 +40,6 @@ public class UsageInArtifact extends ProjectStructureElementUsage { return myContainingElement; } - @Override - public void navigate() { - final Artifact artifact = myContext.getArtifactModel().getArtifactByOriginal(myOriginalArtifact); - ProjectStructureConfigurable.getInstance(myContext.getProject()).select(myOriginalArtifact, true).doWhenDone(new Runnable() { - public void run() { - final ArtifactEditorEx artifactEditor = (ArtifactEditorEx)myContext.getOrCreateEditor(artifact); - artifactEditor.getLayoutTreeComponent().selectNode(myParentPath, myPackagingElement); - } - }); - } - public void removeElement() { getOrCreateEditor().removePackagingElement(myParentPath, myPackagingElement); } @@ -68,6 +57,11 @@ public class UsageInArtifact extends ProjectStructureElementUsage { return myOriginalArtifact.getName(); } + @Override + public PlaceInProjectStructure getPlace() { + return new PlaceInArtifact(myOriginalArtifact, myContext, myParentPath, myPackagingElement); + } + @Override public int hashCode() { return myOriginalArtifact.hashCode(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FindUsagesInProjectStructureActionBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FindUsagesInProjectStructureActionBase.java index 3600e72ef4f1..e69a0b88cc11 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FindUsagesInProjectStructureActionBase.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/FindUsagesInProjectStructureActionBase.java @@ -81,7 +81,7 @@ public abstract class FindUsagesInProjectStructureActionBase extends AnAction im JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(ProjectBundle.message("dependencies.used.in.popup.title"), usagesArray) { @Override public PopupStep onChosen(final ProjectStructureElementUsage selected, final boolean finalChoice) { - selected.navigate(); + selected.getPlace().navigate(); return FINAL_CHOICE; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java index 3873df365b1a..356ee2aa0ebc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/LibraryProjectStructureElement.java @@ -1,5 +1,6 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.JavadocOrderRootType; import com.intellij.openapi.roots.OrderRootType; @@ -16,10 +17,10 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.LibraryConfigurab import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.ui.navigation.Place; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import javax.swing.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.Collections; @@ -80,8 +81,9 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { } @NotNull - private Place createPlace() { - return ProjectStructureConfigurable.getInstance(myContext.getProject()).createProjectOrGlobalLibraryPlace(myLibrary); + private PlaceInProjectStructure createPlace() { + final Project project = myContext.getProject(); + return new PlaceInProjectStructureBase(project, ProjectStructureConfigurable.getInstance(project).createProjectOrGlobalLibraryPlace(myLibrary)); } @Override @@ -144,7 +146,7 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { } myContext.getDaemonAnalyzer().queueUpdate(LibraryProjectStructureElement.this); final ProjectStructureConfigurable structureConfigurable = ProjectStructureConfigurable.getInstance(myContext.getProject()); - structureConfigurable.navigateTo(createPlace(), true).doWhenDone(new Runnable() { + createPlace().navigate().doWhenDone(new Runnable() { @Override public void run() { final NamedConfigurable configurable = structureConfigurable.getConfigurableFor(myLibrary).getSelectedConfugurable(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java index a457a840cbd5..f9cac84a151e 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java @@ -2,6 +2,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; @@ -9,7 +10,6 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.ModuleEditor; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; -import com.intellij.ui.navigation.Place; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; @@ -52,10 +52,11 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { for (OrderEntry entry : entries) { if (!entry.isValid()){ if (entry instanceof JdkOrderEntry && ((JdkOrderEntry)entry).getJdkName() == null) { - problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message"), null, createPlace(), null); - } else { + problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message"), null, createPlace(entry), null); + } + else { problemsHolder.registerError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName()), null, - createPlace(), + createPlace(entry), null); } } @@ -74,8 +75,13 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { } } - private Place createPlace() { - return ProjectStructureConfigurable.getInstance(myContext.getProject()).createModulePlace(myModule); + private PlaceInProjectStructure createPlace() { + final Project project = myContext.getProject(); + return new PlaceInProjectStructureBase(project, ProjectStructureConfigurable.getInstance(project).createModulePlace(myModule)); + } + + private PlaceInProjectStructure createPlace(OrderEntry entry) { + return new PlaceInModuleClasspath(myContext, myModule, entry); } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInModuleClasspath.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInModuleClasspath.java new file mode 100644 index 000000000000..1bf77792e50a --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInModuleClasspath.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2011 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.module.Module; +import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.impl.OrderEntryUtil; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.util.ActionCallback; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class PlaceInModuleClasspath extends PlaceInProjectStructure { + private StructureConfigurableContext myContext; + private Module myModule; + private OrderEntry myOrderEntry; + + public PlaceInModuleClasspath(StructureConfigurableContext context, Module module, OrderEntry orderEntry) { + myContext = context; + myModule = module; + myOrderEntry = orderEntry; + } + + public PlaceInModuleClasspath(@NotNull StructureConfigurableContext context, @NotNull Module module, @NotNull ProjectStructureElement elementInClasspath) { + myContext = context; + myModule = module; + ModuleRootModel rootModel = myContext.getModulesConfigurator().getRootModel(myModule); + if (elementInClasspath instanceof LibraryProjectStructureElement) { + myOrderEntry = OrderEntryUtil.findLibraryOrderEntry(rootModel, ((LibraryProjectStructureElement)elementInClasspath).getLibrary()); + } + else if (elementInClasspath instanceof ModuleProjectStructureElement) { + myOrderEntry = OrderEntryUtil.findModuleOrderEntry(rootModel, ((ModuleProjectStructureElement)elementInClasspath).getModule()); + } + else if (elementInClasspath instanceof SdkProjectStructureElement) { + myOrderEntry = OrderEntryUtil.findJdkOrderEntry(rootModel, ((SdkProjectStructureElement)elementInClasspath).getSdk()); + } + else { + myOrderEntry = null; + } + } + + @NotNull + @Override + public ActionCallback navigate() { + return ProjectStructureConfigurable.getInstance(myContext.getProject()).selectOrderEntry(myModule, myOrderEntry); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInProjectStructure.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInProjectStructure.java new file mode 100644 index 000000000000..dc5a46fb5d8a --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInProjectStructure.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2011 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.util.ActionCallback; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public abstract class PlaceInProjectStructure { + @NotNull + public abstract ActionCallback navigate(); +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInProjectStructureBase.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInProjectStructureBase.java new file mode 100644 index 000000000000..b9b152f8ed0f --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/PlaceInProjectStructureBase.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2011 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.project.Project; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.util.ActionCallback; +import com.intellij.ui.navigation.Place; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class PlaceInProjectStructureBase extends PlaceInProjectStructure { + private final Project myProject; + private final Place myPlace; + + public PlaceInProjectStructureBase(Project project, Place place) { + myProject = project; + myPlace = place; + } + + @NotNull + @Override + public ActionCallback navigate() { + return ProjectStructureConfigurable.getInstance(myProject).navigateTo(myPlace, true); + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java index 500b7460a792..f876ce463486 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java @@ -13,8 +13,6 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; import com.intellij.openapi.roots.ui.configuration.ConfigurationError; -import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; -import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; @@ -27,18 +25,16 @@ import java.util.List; * @author nik */ class ProjectConfigurationProblem extends ConfigurationError { - private final StructureConfigurableContext myContext; private final ProjectStructureProblemDescription myDescription; - public ProjectConfigurationProblem(StructureConfigurableContext context, ProjectStructureProblemDescription description) { + public ProjectConfigurationProblem(ProjectStructureProblemDescription description) { super(description.getMessage(), description.getDescription() != null ? description.getDescription() : description.getMessage()); - myContext = context; myDescription = description; } @Override public void navigate() { - ProjectStructureConfigurable.getInstance(myContext.getProject()).navigateTo(myDescription.getPlace(), true); + myDescription.getPlace().navigate(); } @Override @@ -47,7 +43,7 @@ class ProjectConfigurationProblem extends ConfigurationError { } @Override - public void fix(JComponent contextComponent) { + public void fix(final JComponent contextComponent) { final List fixes = myDescription.getFixes(); if (fixes.size() == 1) { fixes.get(0).performFix(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java index 049fe43a80e6..e77ea6e267d3 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java @@ -27,7 +27,7 @@ import java.util.List; * @author nik */ public class ProjectConfigurationProblems { - private MultiValuesMap myErrors = new MultiValuesMap(); + private final MultiValuesMap myErrors = new MultiValuesMap(); private final ProjectStructureDaemonAnalyzer myAnalyzer; private final StructureConfigurableContext myContext; @@ -67,7 +67,7 @@ public class ProjectConfigurationProblems { final List descriptions = problemsHolder.getProblemDescriptions(); if (descriptions != null) { for (ProjectStructureProblemDescription description : descriptions) { - final ProjectConfigurationProblem error = new ProjectConfigurationProblem(myContext, description); + final ProjectConfigurationProblem error = new ProjectConfigurationProblem(description); myErrors.put(element, error); ConfigurationErrors.Bus.addError(error, myContext.getProject()); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElementUsage.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElementUsage.java index 7ed2aff3b88d..0d3286963d2b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElementUsage.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureElementUsage.java @@ -12,7 +12,7 @@ public abstract class ProjectStructureElementUsage { public abstract String getPresentableName(); - public abstract void navigate(); + public abstract PlaceInProjectStructure getPlace(); @Override public abstract int hashCode(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java index d4b125dc58fb..5af61c4359f3 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; -import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,10 +27,10 @@ public class ProjectStructureProblemDescription { private final String myMessage; private final String myDescription; private final Severity mySeverity; - private final Place myPlace; + private final PlaceInProjectStructure myPlace; private final List myFixes; - public ProjectStructureProblemDescription(@NotNull String message, @Nullable String description, @NotNull Severity severity, @NotNull Place place, + public ProjectStructureProblemDescription(@NotNull String message, @Nullable String description, @NotNull Severity severity, @NotNull PlaceInProjectStructure place, @NotNull List fixes) { myMessage = message; myDescription = description; @@ -57,7 +56,7 @@ public class ProjectStructureProblemDescription { return mySeverity; } - public Place getPlace() { + public PlaceInProjectStructure getPlace() { return myPlace; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java index 411451abfdcc..b4d3a36bbb3b 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; -import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -23,9 +22,9 @@ import org.jetbrains.annotations.Nullable; * @author nik */ public interface ProjectStructureProblemsHolder { - void registerError(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix); + void registerError(@NotNull String message, @Nullable String description, @NotNull PlaceInProjectStructure place, @Nullable ConfigurationErrorQuickFix fix); - void registerWarning(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix); + void registerWarning(@NotNull String message, @Nullable String description, @NotNull PlaceInProjectStructure place, @Nullable ConfigurationErrorQuickFix fix); void registerProblem(@NotNull ProjectStructureProblemDescription description); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java index 730ea05565bb..4d31e1452efb 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java @@ -1,7 +1,6 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.navigation.Place; import com.intellij.util.SmartList; import com.intellij.util.StringBuilderSpinAllocator; import org.jetbrains.annotations.NotNull; @@ -16,12 +15,12 @@ import java.util.List; public class ProjectStructureProblemsHolderImpl implements ProjectStructureProblemsHolder { private List myProblemDescriptions; - public void registerError(@NotNull String message, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) { + public void registerError(@NotNull String message, String description, @NotNull PlaceInProjectStructure place, @Nullable ConfigurationErrorQuickFix fix) { final List fixes = fix != null ? Collections.singletonList(fix) : Collections.emptyList(); registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.ERROR, place, fixes)); } - public void registerWarning(@NotNull String message, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) { + public void registerWarning(@NotNull String message, String description, @NotNull PlaceInProjectStructure place, @Nullable ConfigurationErrorQuickFix fix) { final List fixes = Collections.singletonList(fix); registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.WARNING, place, fixes)); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/UsageInModuleClasspath.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/UsageInModuleClasspath.java index 54922119a573..5f384dd6a14d 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/UsageInModuleClasspath.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/UsageInModuleClasspath.java @@ -2,11 +2,6 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.roots.ModuleRootModel; -import com.intellij.openapi.roots.OrderEntry; -import com.intellij.openapi.roots.impl.OrderEntryUtil; -import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; -import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import org.jetbrains.annotations.NotNull; @@ -49,24 +44,8 @@ public class UsageInModuleClasspath extends ProjectStructureElementUsage { } @Override - public void navigate() { - ModulesConfigurator modulesConfigurator = myContext.getModulesConfigurator(); - - ModuleRootModel rootModel = modulesConfigurator.getRootModel(myModule); - OrderEntry entry; - if (mySourceElement instanceof LibraryProjectStructureElement) { - entry = OrderEntryUtil.findLibraryOrderEntry(rootModel, ((LibraryProjectStructureElement)mySourceElement).getLibrary()); - } - else if (mySourceElement instanceof ModuleProjectStructureElement) { - entry = OrderEntryUtil.findModuleOrderEntry(rootModel, ((ModuleProjectStructureElement)mySourceElement).getModule()); - } - else if (mySourceElement instanceof SdkProjectStructureElement) { - entry = OrderEntryUtil.findJdkOrderEntry(rootModel, ((SdkProjectStructureElement)mySourceElement).getSdk()); - } - else { - entry = null; - } - ProjectStructureConfigurable.getInstance(myContext.getProject()).selectOrderEntry(myModule, entry); + public PlaceInProjectStructure getPlace() { + return new PlaceInModuleClasspath(myContext, myModule, mySourceElement); } @Override diff --git a/java/java-impl/src/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java b/java/java-impl/src/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java index bba67beb5143..60a69517418f 100644 --- a/java/java-impl/src/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java +++ b/java/java-impl/src/com/intellij/codeInspection/equalsAndHashcode/EqualsAndHashcode.java @@ -21,38 +21,45 @@ import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.MethodSignatureUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.concurrent.atomic.AtomicBoolean; - /** * @author max */ public class EqualsAndHashcode extends BaseJavaLocalInspectionTool { - private PsiMethod myHashCode; - private PsiMethod myEquals; - private final AtomicBoolean myInitialized = new AtomicBoolean(); - @NotNull public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { - if (!myInitialized.getAndSet(true)) { - final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(holder.getProject()); - final PsiClass psiObjectClass = ApplicationManager.getApplication().runReadAction( - new Computable() { - @Nullable - public PsiClass compute() { - return psiFacade.findClass("java.lang.Object"); + + final Project project = holder.getProject(); + Pair pair = CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider>() { + @Override + public Result> compute() { + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); + final PsiClass psiObjectClass = ApplicationManager.getApplication().runReadAction( + new Computable() { + @Nullable + public PsiClass compute() { + return psiFacade.findClass("java.lang.Object", GlobalSearchScope.allScope(project)); + } } - } - ); - if (psiObjectClass != null) { + ); + if (psiObjectClass == null) { + return Result.create(null, ProjectRootManager.getInstance(project)); + } PsiMethod[] methods = psiObjectClass.getMethods(); + PsiMethod myEquals = null; + PsiMethod myHashCode = null; for (PsiMethod method : methods) { @NonNls final String name = method.getName(); if ("equals".equals(name)) { @@ -62,10 +69,15 @@ public class EqualsAndHashcode extends BaseJavaLocalInspectionTool { myHashCode = method; } } + return Result.create(Pair.create(myEquals, myHashCode), psiObjectClass); } - } + }); + + if (pair == null) return new PsiElementVisitor() {}; //jdk wasn't configured for the project + final PsiMethod myEquals = pair.first; + final PsiMethod myHashCode = pair.second; if (myEquals == null || myHashCode == null || !myEquals.isValid() || !myHashCode.isValid()) return new PsiElementVisitor() {}; return new JavaElementVisitor() { @@ -73,7 +85,7 @@ public class EqualsAndHashcode extends BaseJavaLocalInspectionTool { super.visitClass(aClass); boolean [] hasEquals = new boolean[] {false}; boolean [] hasHashCode = new boolean[] {false}; - processClass(aClass, hasEquals, hasHashCode); + processClass(aClass, hasEquals, hasHashCode, myEquals, myHashCode); if (hasEquals[0] != hasHashCode[0]) { PsiIdentifier identifier = aClass.getNameIdentifier(); holder.registerProblem(identifier != null ? identifier : aClass, @@ -90,13 +102,16 @@ public class EqualsAndHashcode extends BaseJavaLocalInspectionTool { }; } - private void processClass(final PsiClass aClass, final boolean[] hasEquals, final boolean[] hasHashCode) { + private static void processClass(final PsiClass aClass, + final boolean[] hasEquals, + final boolean[] hasHashCode, + PsiMethod equals, PsiMethod hashcode) { final PsiMethod[] methods = aClass.getMethods(); for (PsiMethod method : methods) { - if (MethodSignatureUtil.areSignaturesEqual(method, myEquals)) { + if (MethodSignatureUtil.areSignaturesEqual(method, equals)) { hasEquals[0] = true; } - else if (MethodSignatureUtil.areSignaturesEqual(method, myHashCode)) { + else if (MethodSignatureUtil.areSignaturesEqual(method, hashcode)) { hasHashCode[0] = true; } } @@ -116,9 +131,4 @@ public class EqualsAndHashcode extends BaseJavaLocalInspectionTool { public String getShortName() { return "EqualsAndHashcode"; } - - public void projectClosed(Project project) { - myEquals = null; - myHashCode = null; - } } diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java index 39c052bd18ac..5a97be03028e 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java @@ -105,9 +105,6 @@ public class MethodSignatureUtil { return new MethodSignatureHandMade(name, parameterTypes, typeParameterList, substitutor, isConstructor); } - /** - * @deprecated use areSignaturesEqual() which takes correct substitutors - */ public static boolean areSignaturesEqual(PsiMethod method1, PsiMethod method2) { return method1.getSignature(PsiSubstitutor.EMPTY).equals(method2.getSignature(PsiSubstitutor.EMPTY)); } diff --git a/platform/lang-api/src/com/intellij/codeInspection/InspectionEP.java b/platform/lang-api/src/com/intellij/codeInspection/InspectionEP.java new file mode 100644 index 000000000000..c7fd6e1822f1 --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInspection/InspectionEP.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2011 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.codeInspection; + +import com.intellij.CommonBundle; +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.lang.LanguageExtensionPoint; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.util.xmlb.annotations.Attribute; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * @author Dmitry Avdeev + * Date: 9/27/11 + */ +public class InspectionEP extends LanguageExtensionPoint { + + public final static ExtensionPointName GLOBAL_INSPECTION = ExtensionPointName.create("com.intellij.globalInspection"); + + @Attribute("shortName") + public String shortName; + @Nls + @NotNull + public String getDisplayName() { + return getLocalizedString(bundle, key, displayName); + } + + @Nls + @NotNull + public String getGroupDisplayName() { + return getLocalizedString(groupBundle, groupKey, groupDisplayName); + } + + @Attribute("key") + public String key; + + @Attribute("bundle") + public String bundle; + + @Attribute("displayName") + public String displayName; + + @Attribute("groupKey") + public String groupKey; + + @Attribute("groupBundle") + public String groupBundle; + + @Attribute("groupName") + public String groupDisplayName; + + @Attribute("enabledByDefault") + public boolean enabledByDefault = false; + + @Attribute("level") + public String level; + + public HighlightDisplayLevel getDefaultLevel() { + HighlightDisplayLevel displayLevel = HighlightDisplayLevel.find(level); + if (displayLevel == null) { + LOG.error("Can't find highlight display level: " + level); + return HighlightDisplayLevel.WARNING; + } + return displayLevel; + } + + private String getLocalizedString(String bundleName, String key, String displayName) { + if (displayName != null) return displayName; + final String baseName = bundleName != null ? bundleName : bundle == null ? ((IdeaPluginDescriptor)myPluginDescriptor).getResourceBundleBaseName() : bundle; + if (baseName == null) { + LOG.error("No resource bundle specified for " + myPluginDescriptor); + } + final ResourceBundle bundle = ResourceBundle.getBundle(baseName, Locale.getDefault(), myPluginDescriptor.getPluginClassLoader()); + return CommonBundle.message(bundle, key); + } + + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionEP"); + + public InspectionProfileEntry instantiateTool() { + try { + return instantiate(implementationClass, ApplicationManager.getApplication().getPicoContainer()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/platform/lang-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/lang-api/src/com/intellij/codeInspection/InspectionProfileEntry.java index befc780184eb..61a2c8020a73 100644 --- a/platform/lang-api/src/com/intellij/codeInspection/InspectionProfileEntry.java +++ b/platform/lang-api/src/com/intellij/codeInspection/InspectionProfileEntry.java @@ -197,6 +197,7 @@ public abstract class InspectionProfileEntry { * Initialize inspection with project. Is called on project opened for all profiles as well as on profile creation. * * @param project to be associated with this entry + * @deprecated this won't work for inspections configured via {@link InspectionEP} */ public void projectOpened(Project project) { } @@ -205,6 +206,7 @@ public abstract class InspectionProfileEntry { * Cleanup inspection settings corresponding to the project. Is called on project closed for all profiles as well as on profile deletion. * * @param project to be disassociated from this entry + * @deprecated this won't work for inspections configured via {@link InspectionEP} */ public void projectClosed(Project project) { } @@ -213,19 +215,23 @@ public abstract class InspectionProfileEntry { * Override this method to return a html inspection description. Otherwise it will be loaded from resources using ID. * * @return hard-code inspection description. + * @deprecated this won't work for inspections configured via {@link InspectionEP} */ @Nullable public String getStaticDescription() { return null; } + /** + * @deprecated this won't work for inspections configured via {@link InspectionEP} + */ @Nullable public String getDescriptionFileName() { return null; } @Nullable - private URL getDescriptionUrl() { + protected URL getDescriptionUrl() { final String fileName = getDescriptionFileName(); if (fileName == null) return null; return ResourceUtil.getResource(getDescriptionContextClass(), "/inspectionDescriptions", fileName); @@ -235,6 +241,10 @@ public abstract class InspectionProfileEntry { return getClass(); } + public boolean isInitialized() { + return true; + } + @Nullable public String loadDescription() { final String description = getStaticDescription(); diff --git a/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionEP.java b/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionEP.java new file mode 100644 index 000000000000..b0139b82c038 --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInspection/LocalInspectionEP.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2011 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.codeInspection; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.util.xmlb.annotations.Attribute; + +/** + * @author Dmitry Avdeev + * Date: 9/28/11 + */ +public class LocalInspectionEP extends InspectionEP { + + public final static ExtensionPointName LOCAL_INSPECTION = ExtensionPointName.create("com.intellij.localInspection"); + + @Attribute("suppressId") + public String id; + + @Attribute("alternativeId") + public String alternativeId; +} diff --git a/platform/lang-api/src/com/intellij/codeInspection/ex/ScopeToolState.java b/platform/lang-api/src/com/intellij/codeInspection/ex/ScopeToolState.java index 9cee1870fc89..dd6943013cad 100644 --- a/platform/lang-api/src/com/intellij/codeInspection/ex/ScopeToolState.java +++ b/platform/lang-api/src/com/intellij/codeInspection/ex/ScopeToolState.java @@ -133,12 +133,15 @@ public class ScopeToolState { public boolean equalTo(ScopeToolState state2) { if (isEnabled() != state2.isEnabled()) return false; if (getLevel() != state2.getLevel()) return false; + InspectionProfileEntry tool = getTool(); + InspectionProfileEntry tool2 = state2.getTool(); + if (!tool.isInitialized() && !tool2.isInitialized()) return true; try { @NonNls String tempRoot = "root"; Element oldToolSettings = new Element(tempRoot); - getTool().writeSettings(oldToolSettings); + tool.writeSettings(oldToolSettings); Element newToolSettings = new Element(tempRoot); - state2.getTool().writeSettings(newToolSettings); + tool2.writeSettings(newToolSettings); return JDOMUtil.areElementsEqual(oldToolSettings, newToolSettings); } catch (WriteExternalException e) { diff --git a/platform/lang-api/src/com/intellij/util/SequentialModelProgressTask.java b/platform/lang-api/src/com/intellij/util/SequentialModelProgressTask.java new file mode 100644 index 000000000000..71440b00aa9b --- /dev/null +++ b/platform/lang-api/src/com/intellij/util/SequentialModelProgressTask.java @@ -0,0 +1,104 @@ +package com.intellij.util; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationTargetException; + +/** + * Allows to execute {@link SequentialTask} under modal progress. + * + * @author Denis Zhdanov + * @since 9/27/11 2:52 PM + */ +public class SequentialModelProgressTask extends Task.Modal { + + private static final Logger LOG = Logger.getInstance("#" + SequentialModelProgressTask.class.getName()); + + /** + * We want to perform formatting by big chunks at EDT. However, there is a possible case that particular formatting iteration + * is executed in short amount of time. Hence, we may want to execute more than one formatting action during single EDT iteration. + * Current constant holds min amount of time to spend to formatting. + */ + private static final long ITERATION_MIN_TIMES_MILLIS = 500; + + private final String myTitle; + + private ProgressIndicator myIndicator; + private SequentialTask myTask; + + public SequentialModelProgressTask(@Nullable Project project, @NotNull String title) { + super(project, title, true); + myTitle = title; + } + + @Override + public void run(@NotNull ProgressIndicator indicator) { + try { + doRun(indicator); + } + catch (Exception e) { + LOG.info("Unexpected exception occurred during processing sequential task '" + myTitle + "'", e); + } + finally { + indicator.stop(); + } + } + + public void doRun(@NotNull ProgressIndicator indicator) throws InvocationTargetException, InterruptedException { + final SequentialTask task = myTask; + if (task == null) { + return; + } + + myIndicator = indicator; + indicator.setIndeterminate(false); + prepare(task); + + // We need to sync background thread and EDT here in order to avoid situation when event queue is full of processing requests. + while (!task.isDone()) { + if (indicator.isCanceled()) { + task.stop(); + break; + } + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + long start = System.currentTimeMillis(); + try { + while (!task.isDone() && System.currentTimeMillis() - start < ITERATION_MIN_TIMES_MILLIS) { + task.iteration(); + } + } + catch (RuntimeException e) { + task.stop(); + throw e; + } + } + }); + } + } + + public void setTask(@Nullable SequentialTask task) { + myTask = task; + } + + @Nullable + public ProgressIndicator getIndicator() { + return myIndicator; + } + + /** + * Executes preliminary jobs prior to the target sequential task processing ({@link SequentialTask#prepare()} by default). + * + * @param task task to be executed + */ + protected void prepare(@NotNull SequentialTask task) { + task.prepare(); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java index 933f8555bfd1..d9144ccb5631 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/AbstractLayoutCodeProcessor.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.actions; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.CodeInsightUtilBase; -import com.intellij.formatting.FormattingProgressTask; import com.intellij.lang.LanguageFormatting; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -41,6 +40,8 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.SequentialModelProgressTask; +import com.intellij.util.SequentialTask; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -237,25 +238,11 @@ public abstract class AbstractLayoutCodeProcessor { return new Runnable() { public void run() { - for (FutureTask task : tasks) { - if (task == null) { - continue; - } - task.run(); - try { - if (!task.get() || task.isCancelled()) { - break; - } - } - catch (InterruptedException e) { - LOG.error("Got unexpected during formatting", e); - break; - } - catch (ExecutionException e) { - LOG.error("Got unexpected during formatting", e); - break; - } - } + SequentialModelProgressTask progressTask = new SequentialModelProgressTask(myProject, myCommandName); + ReformatFilesTask reformatFilesTask = new ReformatFilesTask(tasks); + reformatFilesTask.setCompositeTask(progressTask); + progressTask.setTask(reformatFilesTask); + ProgressManager.getInstance().run(progressTask); } }; } @@ -443,4 +430,69 @@ public abstract class AbstractLayoutCodeProcessor { final Runnable runnable = preprocessFile(myFile); runnable.run(); } + + private class ReformatFilesTask implements SequentialTask { + + private final List> myTasks; + private final int myTotalTasksNumber; + + private SequentialModelProgressTask myCompositeTask; + + ReformatFilesTask(@NotNull List> tasks) { + myTasks = tasks; + myTotalTasksNumber = myTasks.size(); + } + + @Override + public void prepare() { + } + + @Override + public boolean isDone() { + return myTasks.isEmpty(); + } + + @Override + public boolean iteration() { + if (myTasks.isEmpty()) { + return true; + } + FutureTask task = myTasks.remove(myTasks.size() - 1); + if (task == null) { + return myTasks.isEmpty(); + } + task.run(); + try { + if (!task.get() || task.isCancelled()) { + myTasks.clear(); + return true; + } + } + catch (InterruptedException e) { + LOG.error("Got unexpected during formatting", e); + return true; + } + catch (ExecutionException e) { + LOG.error("Got unexpected during formatting", e); + return true; + } + if (myCompositeTask != null) { + ProgressIndicator indicator = myCompositeTask.getIndicator(); + if (indicator != null) { + indicator.setText(myProgressText + (myTotalTasksNumber - myTasks.size()) + "/" + myTotalTasksNumber); + indicator.setFraction((double)(myTotalTasksNumber - myTasks.size()) / myTotalTasksNumber); + } + } + return myTasks.isEmpty(); + } + + @Override + public void stop() { + myTasks.clear(); + } + + public void setCompositeTask(@Nullable SequentialModelProgressTask compositeTask) { + myCompositeTask = compositeTask; + } + } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java index 8df9c74ddc11..7ef6f83a0fb8 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java @@ -1,7 +1,6 @@ package com.intellij.codeInspection.ex; import com.intellij.analysis.AnalysisScope; -import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.*; import com.intellij.codeInspection.reference.RefEntity; @@ -10,48 +9,45 @@ import com.intellij.codeInspection.reference.RefManagerImpl; import com.intellij.codeInspection.reference.RefVisitor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.PsiFile; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; - /** * User: anna * Date: 28-Dec-2005 */ -public class GlobalInspectionToolWrapper extends DescriptorProviderInspection { - @NotNull private final GlobalInspectionTool myTool; +public class GlobalInspectionToolWrapper extends InspectionToolWrapper { public GlobalInspectionToolWrapper(@NotNull GlobalInspectionTool globalInspectionTool) { - myTool = globalInspectionTool; + super(globalInspectionTool); + } + + public GlobalInspectionToolWrapper(InspectionEP ep) { + super(ep); } public void initialize(@NotNull GlobalInspectionContextImpl context) { super.initialize(context); - final RefGraphAnnotator annotator = myTool.getAnnotator(getRefManager()); + final RefGraphAnnotator annotator = getTool().getAnnotator(getRefManager()); if (annotator != null) { ((RefManagerImpl)getRefManager()).registerGraphAnnotator(annotator); } } public void runInspection(@NotNull final AnalysisScope scope, @NotNull final InspectionManager manager) { - myTool.runInspection(scope, manager, getContext(), this); + getTool().runInspection(scope, manager, getContext(), this); } public boolean queryExternalUsagesRequests(final InspectionManager manager) { - return myTool.queryExternalUsagesRequests(manager, getContext(), this); + return getTool().queryExternalUsagesRequests(manager, getContext(), this); } @NotNull public JobDescriptor[] getJobDescriptors(GlobalInspectionContext context) { - final JobDescriptor[] additionalJobs = myTool.getAdditionalJobs(); + final JobDescriptor[] additionalJobs = getTool().getAdditionalJobs(); if (additionalJobs == null) { return isGraphNeeded() ? ((GlobalInspectionContextImpl)context).BUILD_GRAPH_ONLY : JobDescriptor.EMPTY_ARRAY; } @@ -60,55 +56,8 @@ public class GlobalInspectionToolWrapper extends DescriptorProviderInspection { } } - @NotNull - public String getDisplayName() { - return myTool.getDisplayName(); - } - - @NotNull - public String getGroupDisplayName() { - return myTool.getGroupDisplayName(); - } - - @NotNull - @Override - public String[] getGroupPath() { - return myTool.getGroupPath(); - } - - @NotNull - @NonNls - public String getShortName() { - return myTool.getShortName(); - } - - public boolean isEnabledByDefault() { - return myTool.isEnabledByDefault(); - } - - @NotNull - public HighlightDisplayLevel getDefaultLevel() { - return myTool.getDefaultLevel(); - } - - public void readSettings(Element element) throws InvalidDataException { - myTool.readSettings(element); - } - - public void writeSettings(Element element) throws WriteExternalException { - myTool.writeSettings(element); - } - - public JComponent createOptionsPanel() { - return myTool.createOptionsPanel(); - } - public boolean isGraphNeeded() { - return myTool.isGraphNeeded(); - } - - @NotNull public GlobalInspectionTool getTool() { - return myTool; + return getTool().isGraphNeeded(); } public void processFile(final AnalysisScope analysisScope, @@ -117,33 +66,26 @@ public class GlobalInspectionToolWrapper extends DescriptorProviderInspection { final boolean filterSuppressed) { context.getRefManager().iterate(new RefVisitor() { @Override public void visitElement(RefEntity refEntity) { - CommonProblemDescriptor[] descriptors = myTool.checkElement(refEntity, analysisScope, manager, context, GlobalInspectionToolWrapper.this); + CommonProblemDescriptor[] descriptors = getTool() + .checkElement(refEntity, analysisScope, manager, context, GlobalInspectionToolWrapper.this); if (descriptors != null) { addProblemElement(refEntity, filterSuppressed, descriptors); } } }); } - public void projectOpened(Project project) { - myTool.projectOpened(project); - } - - public void projectClosed(Project project) { - myTool.projectClosed(project); - } - public HTMLComposerImpl getComposer() { return new DescriptorComposer(this) { protected void composeAdditionalDescription(final StringBuffer buf, final RefEntity refEntity) { - myTool.compose(buf, refEntity, this); + getTool().compose(buf, refEntity, this); } }; } @Nullable public IntentionAction findQuickFixes(final CommonProblemDescriptor problemDescriptor, final String hint) { - final QuickFix fix = myTool.getQuickFix(hint); + final QuickFix fix = getTool().getQuickFix(hint); if (fix != null) { if (problemDescriptor instanceof ProblemDescriptor) { final ProblemDescriptor descriptor = new ProblemDescriptorImpl(((ProblemDescriptor)problemDescriptor).getStartElement(), @@ -181,21 +123,4 @@ public class GlobalInspectionToolWrapper extends DescriptorProviderInspection { } return null; } - - protected Class getDescriptionContextClass() { - return myTool.getClass(); - } - - @Nullable - public String getStaticDescription() { - return myTool.getStaticDescription(); - } - - @Nullable - public SuppressIntentionAction[] getSuppressActions() { - if (myTool instanceof CustomSuppressableInspectionTool) { - return ((CustomSuppressableInspectionTool)myTool).getSuppressActions(null); - } - return super.getSuppressActions(); - } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java index e96e7d657191..f4cd1e133517 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java @@ -309,7 +309,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel, for (Tools toolList : myTools.values()) { final InspectionProfileEntry tool = toolList.getInspectionTool(element); String toolId = - tool instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)tool).getTool().getID() : tool.getShortName(); + tool instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)tool).getID() : tool.getShortName(); if (id.equals(toolId)) return tool; } return null; @@ -451,8 +451,8 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel, HighlightDisplayKey key = HighlightDisplayKey.find(shortName); if (key == null) { if (tool instanceof LocalInspectionToolWrapper) { - key = HighlightDisplayKey.register(shortName, tool.getDisplayName(), ((LocalInspectionToolWrapper)tool).getTool().getID(), - ((LocalInspectionToolWrapper)tool).getTool().getAlternativeID()); + key = HighlightDisplayKey.register(shortName, tool.getDisplayName(), ((LocalInspectionToolWrapper)tool).getID(), + ((LocalInspectionToolWrapper)tool).getAlternativeID()); } else { key = HighlightDisplayKey.register(shortName, tool.getDisplayName()); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolRegistrar.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolRegistrar.java index 79f43eb1d17b..7f7735b932ca 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolRegistrar.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolRegistrar.java @@ -71,6 +71,22 @@ public class InspectionToolRegistrar { ContainerUtil.addAll(providers, ApplicationManager.getApplication().getComponents(InspectionToolProvider.class)); ContainerUtil.addAll(providers, Extensions.getExtensions(InspectionToolProvider.EXTENSION_POINT_NAME)); registerTools(providers.toArray(new InspectionToolProvider[providers.size()])); + for (final LocalInspectionEP ep : Extensions.getExtensions(LocalInspectionEP.LOCAL_INSPECTION)) { + myInspectionToolFactories.add(new Factory() { + @Override + public InspectionTool create() { + return new LocalInspectionToolWrapper(ep); + } + }); + } + for (final InspectionEP ep : Extensions.getExtensions(InspectionEP.GLOBAL_INSPECTION)) { + myInspectionToolFactories.add(new Factory() { + @Override + public InspectionTool create() { + return new GlobalInspectionToolWrapper(ep); + } + }); + } for (InspectionToolsFactory factory : Extensions.getExtensions(InspectionToolsFactory.EXTENSION_POINT_NAME)) { for (final InspectionProfileEntry profileEntry : factory.createTools()) { myInspectionToolFactories.add(new Factory() { @@ -91,12 +107,55 @@ public class InspectionToolRegistrar { public void registerTools(final InspectionToolProvider[] providers) { for (InspectionToolProvider provider : providers) { +// System.out.println("***** " + provider.getClass().getName()); Class[] classes = provider.getInspectionClasses(); for (Class aClass : classes) { - registerInspectionTool(aClass, true); + Factory factory = registerInspectionTool(aClass, true); + InspectionTool tool = factory.create(); +// printExtension(aClass, tool); } } } + /* + + private void printExtension(Class aClass, InspectionTool tool) { + StringBuilder builder = new StringBuilder(tool instanceof LocalInspectionToolWrapper ? ""); + System.out.println(builder); + } + */ private Factory registerInspectionTool(final Class aClass, boolean store) { if (LocalInspectionTool.class.isAssignableFrom(aClass)) { @@ -245,10 +304,9 @@ public class InspectionToolRegistrar { private static boolean checkTool(@NotNull final InspectionTool toolWrapper) { if (toolWrapper instanceof LocalInspectionToolWrapper) { - final LocalInspectionTool localTool = ((LocalInspectionToolWrapper)toolWrapper).getTool(); - if (!LocalInspectionTool.isValidID(localTool.getID())) { + if (!LocalInspectionTool.isValidID(((LocalInspectionToolWrapper)toolWrapper).getID())) { final String message = InspectionsBundle.message("inspection.disabled.wrong.id", - localTool.getShortName(), localTool.getID(), LocalInspectionTool.VALID_ID_PATTERN); + toolWrapper.getShortName(), ((LocalInspectionToolWrapper)toolWrapper).getID(), LocalInspectionTool.VALID_ID_PATTERN); showNotification(message); return false; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java new file mode 100644 index 000000000000..d6f289baac56 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionToolWrapper.java @@ -0,0 +1,141 @@ +/* + * Copyright 2000-2011 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.codeInspection.ex; + +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInspection.CustomSuppressableInspectionTool; +import com.intellij.codeInspection.InspectionEP; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.intellij.codeInspection.SuppressIntentionAction; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.net.URL; + +/** + * @author Dmitry Avdeev + * Date: 9/28/11 + */ +public abstract class InspectionToolWrapper extends DescriptorProviderInspection { + private T myTool; + protected final E myEP; + + protected InspectionToolWrapper(E ep) { + myEP = ep; + } + + protected InspectionToolWrapper(T tool) { + myTool = tool; + myEP = null; + } + + @NotNull + public T getTool() { + if (myTool == null) { + myTool = (T)myEP.instantiateTool(); + } + return myTool; + } + + public boolean isInitialized() { + return myTool != null; + } + + @NotNull + public String getShortName() { + return myEP == null ? getTool().getShortName() : myEP.shortName; + } + + @NotNull + public String getDisplayName() { + return myEP == null ? getTool().getDisplayName() : myEP.getDisplayName(); + } + + @NotNull + public String getGroupDisplayName() { + return myEP == null ? getTool().getGroupDisplayName() : myEP.getGroupDisplayName(); + } + + public boolean isEnabledByDefault() { + return myEP == null ? getTool().isEnabledByDefault() : myEP.enabledByDefault; + } + + @NotNull + public HighlightDisplayLevel getDefaultLevel() { + return myEP == null ? getTool().getDefaultLevel() : myEP.getDefaultLevel(); + } + + @NotNull + @Override + public String[] getGroupPath() { + return getTool().getGroupPath(); + } + + public void readSettings(Element element) throws InvalidDataException { + getTool().readSettings(element); + } + + public void writeSettings(Element element) throws WriteExternalException { + getTool().writeSettings(element); + } + + public JComponent createOptionsPanel() { + return getTool().createOptionsPanel(); + } + + public void projectOpened(Project project) { + if (myEP == null) { + getTool().projectOpened(project); + } + } + + public void projectClosed(Project project) { + if (myEP == null) { + getTool().projectClosed(project); + } + } + + @Nullable + public String getStaticDescription() { + return myEP == null ? getTool().getStaticDescription() : null; + } + + @Override + protected URL getDescriptionUrl() { + if (myEP == null || ApplicationManager.getApplication().isUnitTestMode()) return super.getDescriptionUrl(); + String fileName = getDescriptionFileName(); + if (fileName == null) return null; + return myEP.getLoaderForClass().getResource("/inspectionDescriptions/" + fileName); + } + + @Nullable + public SuppressIntentionAction[] getSuppressActions() { + if (getTool() instanceof CustomSuppressableInspectionTool) { + return ((CustomSuppressableInspectionTool)getTool()).getSuppressActions(null); + } + return super.getSuppressActions(); + } + + public Class getDescriptionContextClass() { + return getTool().getClass(); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java index 1f67f6bcde28..6ef60cf49a88 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/LocalInspectionToolWrapper.java @@ -23,42 +23,32 @@ import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.reference.RefManagerImpl; import com.intellij.codeInspection.ui.InspectionResultsView; -import com.intellij.codeInspection.ui.InspectionTree; import com.intellij.codeInspection.ui.InspectionTreeNode; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; import com.intellij.util.TripleFunction; import com.intellij.util.containers.HashSet; import com.intellij.util.ui.UIUtil; -import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import javax.swing.tree.DefaultTreeModel; import java.util.*; -import java.util.HashMap; /** * @author max */ -public final class LocalInspectionToolWrapper extends DescriptorProviderInspection { +public final class LocalInspectionToolWrapper extends InspectionToolWrapper { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.LocalInspectionToolWrapper"); - @NotNull private final LocalInspectionTool myTool; - public LocalInspectionToolWrapper(@NotNull LocalInspectionTool tool) { - myTool = tool; + super(tool); } - @NotNull - public LocalInspectionTool getTool() { - return myTool; + public LocalInspectionToolWrapper(LocalInspectionEP ep) { + super(ep); } public void processFile(PsiFile file, final boolean filterSuppressed, final InspectionManager manager) { @@ -68,10 +58,10 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti public void processFile(final PsiFile file, final boolean filterSuppressed, final InspectionManager manager, final boolean isOnTheFly) { final ProblemsHolder holder = new ProblemsHolder(manager, file, isOnTheFly); LocalInspectionToolSession session = new LocalInspectionToolSession(file, 0, file.getTextLength()); - final PsiElementVisitor customVisitor = myTool.buildVisitor(holder, isOnTheFly, session); + final PsiElementVisitor customVisitor = getTool().buildVisitor(holder, isOnTheFly, session); LOG.assertTrue(!(customVisitor instanceof PsiRecursiveElementVisitor), "The visitor returned from LocalInspectionTool.buildVisitor() must not be recursive"); - myTool.inspectionStarted(session, isOnTheFly); + getTool().inspectionStarted(session, isOnTheFly); file.accept(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { @@ -80,7 +70,7 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti } }); - myTool.inspectionFinished(session, holder); + getTool().inspectionFinished(session, holder); addProblemDescriptors(holder.getResults(), filterSuppressed); } @@ -93,7 +83,7 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti public void addProblemDescriptors(List descriptors, final boolean filterSuppressed) { final GlobalInspectionContextImpl context = getContext(); if (context != null) { //can be already closed - addProblemDescriptors(descriptors, filterSuppressed, context, myTool, CONVERT, this); + addProblemDescriptors(descriptors, filterSuppressed, context, getTool(), CONVERT, this); } } private static final TripleFunction CONVERT = new TripleFunction() { @@ -192,75 +182,16 @@ public final class LocalInspectionToolWrapper extends DescriptorProviderInspecti }); } - @NotNull - public String getDisplayName() { - return myTool.getDisplayName(); - } - - @NotNull - public String getGroupDisplayName() { - return myTool.getGroupDisplayName(); - } - - @NotNull - public String getShortName() { - return myTool.getShortName(); - } - - public boolean isEnabledByDefault() { - return myTool.isEnabledByDefault(); - } - - @NotNull - @Override - public String[] getGroupPath() { - return myTool.getGroupPath(); - } - - - @NotNull - public HighlightDisplayLevel getDefaultLevel() { - return myTool.getDefaultLevel(); - } - - public void readSettings(Element element) throws InvalidDataException { - myTool.readSettings(element); - } - - public void writeSettings(Element element) throws WriteExternalException { - myTool.writeSettings(element); - } - - public JComponent createOptionsPanel() { - return myTool.createOptionsPanel(); - } - - public void projectOpened(Project project) { - myTool.projectOpened(project); - } - - public void projectClosed(Project project) { - myTool.projectClosed(project); - } - - protected Class getDescriptionContextClass() { - return myTool.getClass(); - } - - @Nullable - public String getStaticDescription() { - return myTool.getStaticDescription(); - } - - @Nullable - public SuppressIntentionAction[] getSuppressActions() { - if (myTool instanceof CustomSuppressableInspectionTool) { - return ((CustomSuppressableInspectionTool)myTool).getSuppressActions(null); - } - return super.getSuppressActions(); - } - public boolean isUnfair() { - return myTool instanceof UnfairLocalInspectionTool; + return getTool() instanceof UnfairLocalInspectionTool; + } + + public String getID() { + return myEP == null ? getTool().getID() : myEP.id == null ? myEP.shortName : myEP.id; + } + + @Nullable + public String getAlternativeID() { + return myEP == null ? getTool().getAlternativeID() : myEP.alternativeId; } } diff --git a/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java b/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java index d418436999c2..e21e6e3cad67 100644 --- a/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java +++ b/platform/lang-impl/src/com/intellij/conversion/ModuleSettings.java @@ -17,6 +17,7 @@ package com.intellij.conversion; import org.jdom.Element; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,6 +30,8 @@ import java.util.List; */ public interface ModuleSettings extends ComponentManagerSettings { + @NonNls String MODULE_ROOT_MANAGER_COMPONENT = "NewModuleRootManager"; + @NotNull String getModuleName(); diff --git a/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java b/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java index 459c90a92306..27ad0e9246e1 100644 --- a/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java +++ b/platform/lang-impl/src/com/intellij/conversion/impl/ModuleSettingsImpl.java @@ -30,7 +30,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -42,7 +41,6 @@ import java.util.*; */ public class ModuleSettingsImpl extends ComponentManagerSettingsImpl implements ModuleSettings { private final String myModuleName; - @NonNls private static final String MODULE_ROOT_MANAGER_COMPONENT = "NewModuleRootManager"; public ModuleSettingsImpl(File moduleFile, ConversionContextImpl context) throws CannotConvertException { super(moduleFile, context); diff --git a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressTask.java b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressTask.java index eb95d074064e..b99a2ea7b55d 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressTask.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressTask.java @@ -18,35 +18,32 @@ package com.intellij.formatting; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.ide.IdeBundle; import com.intellij.openapi.command.undo.UndoManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; +import com.intellij.util.SequentialModelProgressTask; import com.intellij.util.SequentialTask; import com.intellij.util.containers.ConcurrentHashMap; import com.intellij.util.containers.ConcurrentHashSet; import com.intellij.util.ui.UIUtil; -import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.concurrent.ConcurrentMap; /** - * Formatting progressable task. - * + * Formatting progressable task. + * * @author Denis Zhdanov * @since 2/10/11 3:00 PM */ -public class FormattingProgressTask extends Task.Modal implements FormattingProgressCallback { +public class FormattingProgressTask extends SequentialModelProgressTask implements FormattingProgressCallback { /** * Holds flag that indicates whether formatting was cancelled by end-user or not. @@ -57,27 +54,13 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg return false; } }; - - private static final Logger LOG = Logger.getInstance("#" + FormattingProgressTask.class.getName()); - /** - * We want to perform formatting by big chunks at EDT. However, there is a possible case that particular formatting iteration - * is executed in short amount of time. Hence, we may want to execute more than one formatting action during single EDT iteration. - * Current collection contains mappings between min amount of time allowed for particular state iteration processing from EDT. - */ - private static final TObjectIntHashMap ITERATION_MIN_TIMES_MILLIS = new TObjectIntHashMap(); - static { - ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.WRAPPING_BLOCKS, 500); - ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.PROCESSING_BLOCKS, 500); - ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.APPLYING_CHANGES, 1000); - assert ITERATION_MIN_TIMES_MILLIS.size() == FormattingStateId.values().length; - } - /** * Holds max allowed progress bar value (defined at ProgressWindow.MyDialog.initDialog()). */ private static final double MAX_PROGRESS_VALUE = 1; private static final double TOTAL_WEIGHT; + static { double weight = 0; for (FormattingStateId state : FormattingStateId.values()) { @@ -85,7 +68,7 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg } TOTAL_WEIGHT = weight; } - + private final ConcurrentMap> myCallbacks = new ConcurrentHashMap>(); private final WeakReference myFile; @@ -93,23 +76,20 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg private final int myFileTextLength; @NotNull - private FormattingStateId myLastState = FormattingStateId.WRAPPING_BLOCKS; - private long myDocumentModificationStampBefore = -1; - private volatile boolean myRunning = true; + private FormattingStateId myLastState = FormattingStateId.WRAPPING_BLOCKS; + private long myDocumentModificationStampBefore = -1; + + private int myBlocksToModifyNumber; + private int myModifiedBlocksNumber; - private ProgressIndicator myIndicator; - private SequentialTask myTask; - private int myBlocksToModifyNumber; - private int myModifiedBlocksNumber; - public FormattingProgressTask(@Nullable Project project, @NotNull PsiFile file, @NotNull Document document) { - super(project, getTitle(file), true); + super(project, getTitle(file)); myFile = new WeakReference(file.getVirtualFile()); myDocument = new WeakReference(document); myFileTextLength = file.getTextLength(); addCallback(EventType.CANCEL, new MyCancelCallback()); } - + @NotNull private static String getTitle(@NotNull PsiFile file) { VirtualFile virtualFile = file.getOriginalFile().getVirtualFile(); @@ -122,26 +102,7 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg } @Override - public void run(@NotNull ProgressIndicator indicator) { - try { - doRun(indicator); - } - catch (Exception e) { - LOG.info("Unexpected exception occurred during reformatting file " + myFile, e); - } - finally { - if (myIndicator != null) { - myIndicator.stop(); - } - } - } - - public void doRun(@NotNull ProgressIndicator indicator) throws InvocationTargetException, InterruptedException { - final SequentialTask task = myTask; - if (task == null) { - return; - } - + protected void prepare(@NotNull final SequentialTask task) { UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { @@ -152,30 +113,6 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg task.prepare(); } }); - - // We need to sync background thread and EDT here in order to avoid situation when event queue is full of processing requests. - myIndicator = indicator; - while (myRunning && !task.isDone()) { - if (indicator.isCanceled()) { - task.stop(); - break; - } - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - long start = System.currentTimeMillis(); - try { - while (!task.isDone() && System.currentTimeMillis() - start < ITERATION_MIN_TIMES_MILLIS.get(myLastState)) { - task.iteration(); - } - } - catch (RuntimeException e) { - task.stop(); - throw e; - } - } - }); - } } @Override @@ -205,7 +142,7 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg Collection candidate = myCallbacks.putIfAbsent(eventType, result = new ConcurrentHashSet()); if (candidate != null) { result = candidate; - } + } } return result; } @@ -214,73 +151,69 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg public void afterWrappingBlock(@NotNull LeafBlockWrapper wrapped) { update(FormattingStateId.WRAPPING_BLOCKS, MAX_PROGRESS_VALUE * wrapped.getEndOffset() / myFileTextLength); } - + @Override public void afterProcessingBlock(@NotNull LeafBlockWrapper block) { update(FormattingStateId.PROCESSING_BLOCKS, MAX_PROGRESS_VALUE * block.getEndOffset() / myFileTextLength); } - + @Override public void beforeApplyingFormatChanges(@NotNull Collection modifiedBlocks) { myBlocksToModifyNumber = modifiedBlocks.size(); updateTextIfNecessary(FormattingStateId.APPLYING_CHANGES); setCancelText(IdeBundle.message("action.stop")); } - + @Override public void afterApplyingChange(@NotNull LeafBlockWrapper block) { if (myModifiedBlocksNumber++ >= myBlocksToModifyNumber) { return; } - - update(FormattingStateId.APPLYING_CHANGES, MAX_PROGRESS_VALUE * myModifiedBlocksNumber / myBlocksToModifyNumber); - } - @Override - public void setTask(@Nullable SequentialTask task) { - myTask = task; + update(FormattingStateId.APPLYING_CHANGES, MAX_PROGRESS_VALUE * myModifiedBlocksNumber / myBlocksToModifyNumber); } /** * Updates current progress state if necessary. - * - * @param state current state - * @param completionRate completion rate of the given state. Is assumed to belong to [0; 1] interval + * + * @param state current state + * @param completionRate completion rate of the given state. Is assumed to belong to [0; 1] interval */ private void update(@NotNull FormattingStateId state, double completionRate) { - if (myIndicator == null) { + ProgressIndicator indicator = getIndicator(); + if (indicator == null) { return; } updateTextIfNecessary(state); - + myLastState = state; double newFraction = 0; for (FormattingStateId prevState : state.getPreviousStates()) { newFraction += MAX_PROGRESS_VALUE * prevState.getProgressWeight() / TOTAL_WEIGHT; } newFraction += completionRate * state.getProgressWeight() / TOTAL_WEIGHT; - + // We don't bother about imprecise floating point arithmetic here because that is enough for progress representation. - double currentFraction = myIndicator.getFraction(); + double currentFraction = indicator.getFraction(); if (newFraction - currentFraction < MAX_PROGRESS_VALUE / 100) { return; } - - myIndicator.setFraction(newFraction); + + indicator.setFraction(newFraction); } - + private void updateTextIfNecessary(@NotNull FormattingStateId currentState) { - if (myLastState != currentState && myIndicator != null) { - myIndicator.setText(currentState.getDescription()); + ProgressIndicator indicator = getIndicator(); + if (myLastState != currentState && indicator != null) { + indicator.setText(currentState.getDescription()); } } - + private class MyCancelCallback implements Runnable { @Override public void run() { FORMATTING_CANCELLED_FLAG.set(true); - myRunning = false; VirtualFile file = myFile.get(); Document document = myDocument.get(); if (file == null || document == null || myDocumentModificationStampBefore < 0) { @@ -290,7 +223,7 @@ public class FormattingProgressTask extends Task.Modal implements FormattingProg if (editor == null) { return; } - + UndoManager manager = UndoManager.getInstance(myProject); while (manager.isUndoAvailable(editor) && document.getModificationStamp() != myDocumentModificationStampBefore) { manager.undo(editor); diff --git a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionManager.java b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionManager.java index 15b4e838a06b..c3e948250e30 100644 --- a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionManager.java +++ b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionManager.java @@ -36,6 +36,7 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -108,12 +109,16 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen @Override public void projectOpened() { - final Collection ids = FrameworkDetectorRegistry.getInstance().getAllDetectorIds(); - synchronized (myLock) { - myDetectorsToProcess.clear(); - myDetectorsToProcess.addAll(ids); - } - queueDetection(); + StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { + public void run() { + final Collection ids = FrameworkDetectorRegistry.getInstance().getAllDetectorIds(); + synchronized (myLock) { + myDetectorsToProcess.clear(); + myDetectorsToProcess.addAll(ids); + } + queueDetection(); + } + }); } @Override diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/SimpleTree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/SimpleTree.java index 3426f2d75558..11723b213847 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/SimpleTree.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/SimpleTree.java @@ -16,6 +16,7 @@ package com.intellij.ui.treeStructure; import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.NodeRenderer; import com.intellij.ide.util.treeView.TreeVisitor; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; @@ -43,16 +44,12 @@ import java.util.ArrayList; import java.util.List; public class SimpleTree extends Tree implements CellEditorListener { - - private final MouseListener myMouseListener = new MyMouseListener(); + private static final SimpleNode NULL_NODE = new NullNode(); + private static final int INVALID = -1; private ActionGroup myPopupGroup; private String myPlace; - private static final SimpleNode NULL_NODE = new NullNode(); - - // From FTree: - private static final int INVALID = -1; private JComponent myEditorComponent; private boolean myEscapePressed; private int myEditingRow; @@ -70,8 +67,8 @@ public class SimpleTree extends Tree implements CellEditorListener { configureUiHelper(TreeUIHelper.getInstance()); - addMouseListener(myMouseListener); - setCellRenderer(new SimpleNodeRenderer()); + addMouseListener(new MyMouseListener()); + setCellRenderer(new NodeRenderer()); setEditable(false); getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); @@ -101,7 +98,7 @@ public class SimpleTree extends Tree implements CellEditorListener { setUI(new BasicTreeUI()); // In WindowsXP UI handles are not shown :( } - setOpaque(false); + setOpaque(UIUtil.isUnderGTKLookAndFeel()); } public SimpleTree(TreeModel aModel) { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java index ce8e85b6b7ca..a3b7a452409a 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java @@ -20,7 +20,6 @@ import com.intellij.execution.util.ExecUtil; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.ApplicationBundle; @@ -30,6 +29,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.SystemInfo; @@ -48,7 +48,7 @@ import java.io.IOException; import static com.intellij.util.containers.CollectionFactory.hashMap; import static java.util.Arrays.asList; -public class CreateDesktopEntryAction extends AnAction { +public class CreateDesktopEntryAction extends DumbAwareAction { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CreateDesktopEntryAction"); private static final int MIN_ICON_SIZE = 32; diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java index 4ba12c1786bd..8fdd59ec92fc 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java @@ -20,13 +20,13 @@ import com.intellij.execution.util.ExecUtil; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; -import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; @@ -43,7 +43,7 @@ import static java.util.Arrays.asList; /** * @author yole */ -public class CreateLauncherScriptAction extends AnAction { +public class CreateLauncherScriptAction extends DumbAwareAction { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CreateLauncherScriptAction"); public static boolean isAvailable() { @@ -69,7 +69,20 @@ public class CreateLauncherScriptAction extends AnAction { return; } - final File target = new File(dialog.myPathField.getText(), dialog.myNameField.getText()); + String path = dialog.myPathField.getText(); + if (!path.startsWith("/")) { + final String home = System.getenv("HOME"); + if (home != null && new File(home).isDirectory()) { + if (path.startsWith("~")) { + path = home + path.substring(1); + } + else { + path = home + "/" + path; + } + } + } + + final File target = new File(path, dialog.myNameField.getText()); if (target.exists()) { int rc = Messages.showOkCancelDialog(project, ApplicationBundle.message("launcher.script.overwrite", target), "Create Launcher Script", Messages.getQuestionIcon()); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index d892dfb614c5..019b59619859 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -370,10 +370,9 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { final boolean prevIcon = p instanceof IconPresentationWrapper || p instanceof IconLikeCustomStatusBarWidget; final boolean nextIcon = n instanceof IconPresentationWrapper || n instanceof IconLikeCustomStatusBarWidget; + // 2peter: please do not touch it anymore :) self.setBorder(prevIcon ? BorderFactory.createEmptyBorder(2, 2, 2, 2) : StatusBarWidget.WidgetBorder.INSTANCE); - if (nextIcon) { - n.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); - } + if (nextIcon) n.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MacStatusBarUI.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MacStatusBarUI.java index b80c574ef8c6..3dc6cc985010 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MacStatusBarUI.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MacStatusBarUI.java @@ -111,59 +111,6 @@ public class MacStatusBarUI extends StatusBarUI implements Activatable { BACKGROUND_PAINTER.paintBorder(c, g, 0, 0, bounds.width, bounds.height); } - static final class MacPressedBackgroundPainter implements Border { - private static final Color TOP_COLOR = new Color(90, 90, 90); - private static final Color BOTTOM_COLOR = new Color(130, 130, 130); - - private static final Color TOP_LEFT_COLOR = new Color(90, 90, 90); - private static final Color BOTTOM_LEFT_COLOR = new Color(120, 120, 120); - - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - final Graphics2D g2d = (Graphics2D) g.create(); - - g2d.setPaint(new GradientPaint(0, 1, TOP_COLOR, 0, height - 2, BOTTOM_COLOR)); - g2d.fillRect(x, y, width, height); - - g2d.setPaint(new GradientPaint(0, 0, TOP_LEFT_COLOR, 0, height, BOTTOM_LEFT_COLOR)); - g2d.drawLine(0, 0, 0, height); - - g2d.setColor(new Color(200, 200, 200)); - g2d.drawLine(width - 1, 0, width - 1, height); - - g2d.dispose(); - } - - public Insets getBorderInsets(Component c) { - return new Insets(1, 1, 1, 1); - } - - public boolean isBorderOpaque() { - return true; - } - } - - static final class MacHoverBackgroundPainter implements Border { - private static final Color TOP_COLOR = new Color(240, 240, 240); - private static final Color BOTTOM_COLOR = new Color(190, 190, 190); - private static final Insets INSETS = new Insets(0, 0, 0, 0); - - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - final Graphics2D g2d = (Graphics2D) g.create(); - final GradientPaint paint = new GradientPaint(0, 1, TOP_COLOR, 0, height - 2, BOTTOM_COLOR); - g2d.setPaint(paint); - g2d.fillRect(x + 2, y, width - 4, height); - g2d.dispose(); - } - - public Insets getBorderInsets(Component c) { - return INSETS; - } - - public boolean isBorderOpaque() { - return true; - } - } - private static final class MacBackgroundPainter implements Border { private static final Color ACTIVE_TOP_COLOR = new Color(202, 202, 202); private static final Color ACTIVE_BOTTOM_COLOR = new Color(167, 167, 167); @@ -178,58 +125,55 @@ public class MacStatusBarUI extends StatusBarUI implements Activatable { private static final Insets INSETS = new Insets(0, 0, 0, 0); - private static BufferedImage ACTIVE_CACHE; - private static BufferedImage INACTIVE_CACHE; + private BufferedImage[] myCache = new BufferedImage[2]; public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { final Graphics2D g2d = (Graphics2D) g; - final Rectangle clip = g.getClipBounds(); - final boolean active = isActive(c); - BufferedImage img = active ? ACTIVE_CACHE : INACTIVE_CACHE; + Rectangle r = g2d.getClipBounds(); + Image img = getCachedImage(c, g2d); + int step = img.getWidth(null); + for (int i = r.x; i < r.x + r.width; i += step) { + g2d.drawImage(img, i, y, null); + } + } + + private Image getCachedImage(Component c, Graphics2D g2d) { + boolean active = isActive(c); + int ndx = active ? 0 : 1; + BufferedImage image = myCache[ndx]; + if (image == null || image.getHeight(null) != c.getHeight()) { + int width = 50; + int height = c.getHeight(); + image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.OPAQUE); + Graphics2D g = image.createGraphics(); - if (img == null || img.getHeight() != height) { final Color top = active ? ACTIVE_TOP_COLOR : INACTIVE_TOP_COLOR; final Color bottom = active ? ACTIVE_BOTTOM_COLOR : INACTIVE_BOTTOM_COLOR; - img = getSample(height, top, bottom); + + final GradientPaint paint = new GradientPaint(0, 0, top, 0, height, bottom); + g.setPaint(paint); + g.fillRect(0, 0, width, height); if (active) { - ACTIVE_CACHE = img; + g.setColor(ACTIVE_BORDER_TOP_COLOR); + g.drawLine(0, 0, width, 0); + + g.setColor(ACTIVE_BORDER2_TOP_COLOR); + g.drawLine(0, 1, width, 1); } else { - INACTIVE_CACHE = img; + g.setColor(INACTIVE_BORDER_TOP_COLOR); + g.drawLine(0, 0, width, 0); + + g.setColor(INACTIVE_BORDER2_TOP_COLOR); + g.drawLine(0, 1, width, 1); } + + myCache[ndx] = image; } - - final Graphics2D g2 = (Graphics2D)g; - for (int i = clip.x; i < clip.x + clip.width; i += 50) { - g2.drawImage(img, null, i, y); - } - - if (active) { - g2d.setColor(ACTIVE_BORDER_TOP_COLOR); - g2d.drawLine(clip.x, 0, clip.width, 0); - - g2d.setColor(ACTIVE_BORDER2_TOP_COLOR); - g2d.drawLine(clip.x, 1, clip.width, 1); - } else { - g2d.setColor(INACTIVE_BORDER_TOP_COLOR); - g2d.drawLine(clip.x, 0, clip.width, 0); - - g2d.setColor(INACTIVE_BORDER2_TOP_COLOR); - g2d.drawLine(clip.x, 1, clip.width, 1); - } - - g2d.dispose(); - } - - private static BufferedImage getSample(int height, Color top, Color bottom) { - BufferedImage img = new BufferedImage(50, height, BufferedImage.TYPE_INT_RGB); - Graphics2D imageGraphics = (Graphics2D)img.getGraphics(); - imageGraphics.setPaint(new GradientPaint(0, 0, top, 0, height, bottom)); - imageGraphics.fillRect(0, 0, 50, height); - return img; + return image; } public Insets getBorderInsets(Component c) { diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 7314cc783f29..6b75c2e8b040 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -175,6 +175,10 @@ + + - Inspection Gadgets - InspectionGadgets - InspectionGadgets Software + Inspection Gadgets + InspectionGadgets + InspectionGadgets Software - inspection - 1.0 - + inspection + 1.0 + - com.siyeh.InspectionGadgetsBundle + com.siyeh.InspectionGadgetsBundle - - - + + - - - com.siyeh.ig.InspectionGadgetsPlugin - - - - - com.siyeh.ig.InspectionGadgetsProjectComponent - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.siyeh.ig.InspectionGadgetsPlugin + + + + + com.siyeh.ig.InspectionGadgetsProjectComponent + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java index eb370307073e..5d4c042c836f 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java @@ -18,11 +18,7 @@ package com.siyeh.ig; import com.intellij.codeInspection.BaseJavaLocalInspectionTool; import com.intellij.codeInspection.LocalInspectionToolSession; import com.intellij.codeInspection.ProblemsHolder; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElementVisitor; import com.intellij.ui.DocumentAdapter; @@ -49,7 +45,7 @@ public abstract class BaseInspection extends BaseJavaLocalInspectionTool { private String m_shortName = null; private long timestamp = -1L; - private InspectionGadgetsPlugin inspectionGadgetsPlugin = null; + private final InspectionGadgetsPlugin inspectionGadgetsPlugin = InspectionGadgetsPlugin.getInstance(); @Override @NotNull @@ -211,25 +207,4 @@ public abstract class BaseInspection extends BaseJavaLocalInspectionTool { timestamp = -1L; } } - - @Override - public void projectOpened(Project project) { - super.projectOpened(project); - if (inspectionGadgetsPlugin != null) { - return; - } - @NonNls - final Application application = ApplicationManager.getApplication(); - inspectionGadgetsPlugin = (InspectionGadgetsPlugin) - application.getComponent("InspectionGadgets"); - } - - @Override - public void projectClosed(Project project) { - super.projectClosed(project); - final Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); - if (openProjects.length == 0) { - inspectionGadgetsPlugin = null; - } - } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/GroupDisplayNameUtil.java b/plugins/InspectionGadgets/src/com/siyeh/ig/GroupDisplayNameUtil.java index d6a07e5899de..60fc5cc5de07 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/GroupDisplayNameUtil.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/GroupDisplayNameUtil.java @@ -15,7 +15,7 @@ */ package com.siyeh.ig; -import com.intellij.codeInsight.daemon.GroupNames; +import com.intellij.codeInspection.InspectionsBundle; import org.jetbrains.annotations.NonNls; import java.util.HashMap; @@ -26,46 +26,47 @@ public class GroupDisplayNameUtil { private static final Map packageGroupDisplayNameMap = new HashMap(); static { - packageGroupDisplayNameMap.put("abstraction", GroupNames.ABSTRACTION_GROUP_NAME); - packageGroupDisplayNameMap.put("assignment", GroupNames.ASSIGNMENT_GROUP_NAME); - packageGroupDisplayNameMap.put("bitwise", GroupNames.BITWISE_GROUP_NAME); - packageGroupDisplayNameMap.put("bugs", GroupNames.BUGS_GROUP_NAME); - packageGroupDisplayNameMap.put("classlayout", GroupNames.CLASS_LAYOUT_GROUP_NAME); - packageGroupDisplayNameMap.put("classmetrics", GroupNames.CLASS_METRICS_GROUP_NAME); - packageGroupDisplayNameMap.put("cloneable", GroupNames.CLONEABLE_GROUP_NAME); - packageGroupDisplayNameMap.put("controlflow", GroupNames.CONTROL_FLOW_GROUP_NAME); - packageGroupDisplayNameMap.put("dataflow", GroupNames.DATA_FLOW_ISSUES); - packageGroupDisplayNameMap.put("dependency", GroupNames.DEPENDENCY_GROUP_NAME); - packageGroupDisplayNameMap.put("encapsulation", GroupNames.ENCAPSULATION_GROUP_NAME); - packageGroupDisplayNameMap.put("errorhandling", GroupNames.ERROR_HANDLING_GROUP_NAME); - packageGroupDisplayNameMap.put("finalization", GroupNames.FINALIZATION_GROUP_NAME); - packageGroupDisplayNameMap.put("imports", GroupNames.IMPORTS_GROUP_NAME); - packageGroupDisplayNameMap.put("inheritance", GroupNames.INHERITANCE_GROUP_NAME); - packageGroupDisplayNameMap.put("initialization", GroupNames.INITIALIZATION_GROUP_NAME); - packageGroupDisplayNameMap.put("internationalization", GroupNames.INTERNATIONALIZATION_GROUP_NAME); - packageGroupDisplayNameMap.put("j2me", GroupNames.J2ME_GROUP_NAME); - packageGroupDisplayNameMap.put("javabeans", GroupNames.JAVABEANS_GROUP_NAME); - packageGroupDisplayNameMap.put("javadoc", GroupNames.JAVADOC_GROUP_NAME); - packageGroupDisplayNameMap.put("jdk", GroupNames.JDK_GROUP_NAME); - packageGroupDisplayNameMap.put("migration", GroupNames.LANGUAGE_LEVEL_SPECIFIC_GROUP_NAME); - packageGroupDisplayNameMap.put("junit", GroupNames.JUNIT_GROUP_NAME); - packageGroupDisplayNameMap.put("logging", GroupNames.LOGGING_GROUP_NAME); - packageGroupDisplayNameMap.put("maturity", GroupNames.MATURITY_GROUP_NAME); - packageGroupDisplayNameMap.put("memory", GroupNames.MEMORY_GROUP_NAME); - packageGroupDisplayNameMap.put("methodmetrics", GroupNames.METHOD_METRICS_GROUP_NAME); - packageGroupDisplayNameMap.put("modularization", GroupNames.MODULARIZATION_GROUP_NAME); - packageGroupDisplayNameMap.put("naming", GroupNames.NAMING_CONVENTIONS_GROUP_NAME); - packageGroupDisplayNameMap.put("numeric", GroupNames.NUMERIC_GROUP_NAME); - packageGroupDisplayNameMap.put("packaging", GroupNames.PACKAGING_GROUP_NAME); - packageGroupDisplayNameMap.put("performance", GroupNames.PERFORMANCE_GROUP_NAME); - packageGroupDisplayNameMap.put("portability", GroupNames.PORTABILITY_GROUP_NAME); - packageGroupDisplayNameMap.put("redundancy", GroupNames.DECLARATION_REDUNDANCY); - packageGroupDisplayNameMap.put("resources", GroupNames.RESOURCE_GROUP_NAME); - packageGroupDisplayNameMap.put("security", GroupNames.SECURITY_GROUP_NAME); - packageGroupDisplayNameMap.put("serialization", GroupNames.SERIALIZATION_GROUP_NAME); - packageGroupDisplayNameMap.put("style", GroupNames.STYLE_GROUP_NAME); - packageGroupDisplayNameMap.put("threading", GroupNames.THREADING_GROUP_NAME); - packageGroupDisplayNameMap.put("visibility", GroupNames.VISIBILITY_GROUP_NAME); + packageGroupDisplayNameMap.put("abstraction", "group.names.abstraction.issues"); + packageGroupDisplayNameMap.put("assignment", "group.names.assignment.issues"); + packageGroupDisplayNameMap.put("bitwise", "group.names.bitwise.operation.issues"); + packageGroupDisplayNameMap.put("bugs", "group.names.probable.bugs"); + packageGroupDisplayNameMap.put("classlayout", "group.names.class.structure"); + packageGroupDisplayNameMap.put("classmetrics", "group.names.class.metrics"); + packageGroupDisplayNameMap.put("cloneable", "group.names.cloning.issues"); + packageGroupDisplayNameMap.put("controlflow", "group.names.control.flow.issues"); + packageGroupDisplayNameMap.put("dataflow", "group.names.data.flow.issues"); + packageGroupDisplayNameMap.put("dependency", "group.names.dependency.issues"); + packageGroupDisplayNameMap.put("encapsulation", "group.names.encapsulation.issues"); + packageGroupDisplayNameMap.put("errorhandling", "group.names.error.handling"); + packageGroupDisplayNameMap.put("finalization", "group.names.finalization.issues"); + packageGroupDisplayNameMap.put("imports", "group.names.imports"); + packageGroupDisplayNameMap.put("inheritance", "group.names.inheritance.issues"); + packageGroupDisplayNameMap.put("initialization", "group.names.initialization.issues"); + packageGroupDisplayNameMap.put("internationalization", "group.names.internationalization.issues"); + packageGroupDisplayNameMap.put("j2me", "group.names.j2me.issues"); + packageGroupDisplayNameMap.put("javabeans", "group.names.javabeans.issues"); + packageGroupDisplayNameMap.put("javadoc", "group.names.javadoc.issues"); + packageGroupDisplayNameMap.put("jdk", "group.names.java.language.level.issues"); + packageGroupDisplayNameMap.put("migration", + "group.names.language.level.specific.issues.and.migration.aids"); + packageGroupDisplayNameMap.put("junit", "group.names.junit.issues"); + packageGroupDisplayNameMap.put("logging", "group.names.logging.issues"); + packageGroupDisplayNameMap.put("maturity", "group.names.code.maturity.issues"); + packageGroupDisplayNameMap.put("memory", "group.names.memory.issues"); + packageGroupDisplayNameMap.put("methodmetrics", "group.names.method.metrics"); + packageGroupDisplayNameMap.put("modularization", "group.names.modularization.issues"); + packageGroupDisplayNameMap.put("naming", "group.names.naming.conventions"); + packageGroupDisplayNameMap.put("numeric", "group.names.numeric.issues"); + packageGroupDisplayNameMap.put("packaging", "group.names.packaging.issues"); + packageGroupDisplayNameMap.put("performance", "group.names.performance.issues"); + packageGroupDisplayNameMap.put("portability", "group.names.portability.issues"); + packageGroupDisplayNameMap.put("redundancy", "group.names.declaration.redundancy"); + packageGroupDisplayNameMap.put("resources", "group.names.resource.management.issues"); + packageGroupDisplayNameMap.put("security", "group.names.security.issues"); + packageGroupDisplayNameMap.put("serialization", "group.names.serialization.issues"); + packageGroupDisplayNameMap.put("style", "group.names.code.style.issues"); + packageGroupDisplayNameMap.put("threading", "group.names.threading.issues"); + packageGroupDisplayNameMap.put("visibility", "group.names.visibility.issues"); } private GroupDisplayNameUtil() {} @@ -80,6 +81,6 @@ public class GroupDisplayNameUtil { final String key = name.substring(index + 1); final String groupDisplayName = packageGroupDisplayNameMap.get(key); assert groupDisplayName != null : "No display name found for " + key; - return groupDisplayName; + return InspectionsBundle.message(groupDisplayName); } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java index 44aa9f52f7a6..ec9419feebc5 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java @@ -17,7 +17,6 @@ package com.siyeh.ig; import com.intellij.codeInspection.GlobalInspectionTool; import com.intellij.codeInspection.InspectionProfileEntry; -import com.intellij.codeInspection.InspectionToolProvider; import com.intellij.codeInspection.booleanIsAlwaysInverted.BooleanMethodIsAlwaysInvertedInspection; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; @@ -96,8 +95,7 @@ import java.util.*; "OverlyCoupledMethod", "OverlyLongMethod", "ClassWithTooManyMethods"}) -public class InspectionGadgetsPlugin implements ApplicationComponent, - InspectionToolProvider { +public class InspectionGadgetsPlugin implements ApplicationComponent { @NonNls private static final String DESCRIPTION_DIRECTORY_NAME = "src/inspectionDescriptions/"; @@ -109,6 +107,10 @@ public class InspectionGadgetsPlugin implements ApplicationComponent, private volatile InspectionGadgetsTelemetry telemetry = null; private volatile boolean telemetryEnabled = false; + public static InspectionGadgetsPlugin getInstance() { + return ApplicationManager.getApplication().getComponent(InspectionGadgetsPlugin.class); + } + public static void main(String... args) throws FileNotFoundException { final PrintStream out; if (args.length == 0) { @@ -272,7 +274,6 @@ public class InspectionGadgetsPlugin implements ApplicationComponent, return "InspectionGadgets"; } - @Override public Class[] getInspectionClasses() { if (m_inspectionClasses.isEmpty()) { registerAbstractionInspections(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsProjectComponent.java b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsProjectComponent.java index 2950b17792b5..ec8db7bb66c8 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsProjectComponent.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsProjectComponent.java @@ -15,8 +15,6 @@ */ package com.siyeh.ig; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.project.Project; import com.siyeh.ig.telemetry.TelemetryToolWindow; @@ -33,10 +31,7 @@ public class InspectionGadgetsProjectComponent implements ProjectComponent{ } public void projectOpened(){ - final Application application = ApplicationManager.getApplication(); - final InspectionGadgetsPlugin inspectionGadgetsPlugin = - (InspectionGadgetsPlugin) - application.getComponent("InspectionGadgets"); + final InspectionGadgetsPlugin inspectionGadgetsPlugin = InspectionGadgetsPlugin.getInstance(); telemetryEnabled = inspectionGadgetsPlugin.isTelemetryEnabled(); if(telemetryEnabled){ toolWindow = new TelemetryToolWindow(inspectionGadgetsPlugin.getTelemetry()); diff --git a/plugins/android/src/org/jetbrains/android/converter/AndroidModuleConverter1.java b/plugins/android/src/org/jetbrains/android/converter/AndroidModuleConverter1.java index 0008c0d06736..8143152f2a25 100644 --- a/plugins/android/src/org/jetbrains/android/converter/AndroidModuleConverter1.java +++ b/plugins/android/src/org/jetbrains/android/converter/AndroidModuleConverter1.java @@ -18,7 +18,6 @@ package org.jetbrains.android.converter; import com.intellij.conversion.CannotConvertException; import com.intellij.conversion.ConversionProcessor; import com.intellij.conversion.ModuleSettings; -import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModificator; import com.intellij.openapi.roots.OrderRootType; @@ -45,7 +44,6 @@ import java.util.List; */ public class AndroidModuleConverter1 extends ConversionProcessor { private static final String PLATFORM_NAME_ATTRIBUTE = "PLATFORM_NAME"; - private static final String NEW_MODULE_MANAGER = "NewModuleRootManager"; @NonNls private static final String OPTION_VALUE_ATTRIBUTE = "value"; @Override @@ -131,7 +129,7 @@ public class AndroidModuleConverter1 extends ConversionProcessor } private static void addNewDependency(ModuleSettings moduleSettings, @NotNull String jdkName) { - Element moduleManagerElement = moduleSettings.getComponentElement(NEW_MODULE_MANAGER); + Element moduleManagerElement = moduleSettings.getComponentElement(ModuleSettings.MODULE_ROOT_MANAGER_COMPONENT); if (moduleManagerElement != null) { Element newEntryElement = new Element(OrderEntryFactory.ORDER_ENTRY_ELEMENT_NAME); newEntryElement.setAttribute("type", "jdk"); @@ -142,7 +140,7 @@ public class AndroidModuleConverter1 extends ConversionProcessor } private static void removeOldDependencies(ModuleSettings moduleSettings, @NotNull String libName) { - Element moduleManagerElement = moduleSettings.getComponentElement(NEW_MODULE_MANAGER); + Element moduleManagerElement = moduleSettings.getComponentElement(ModuleSettings.MODULE_ROOT_MANAGER_COMPONENT); if (moduleManagerElement != null) { for (Element entryElement : getChildren(moduleManagerElement, OrderEntryFactory.ORDER_ENTRY_ELEMENT_NAME)) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java index 88535b6d5bd1..0d99f0eb3624 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java @@ -48,7 +48,7 @@ public class GithubCreateGistAction extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(GithubCreateGistAction.class); protected GithubCreateGistAction() { - super("Create gist", "Create github gist", ICON); + super("Create Gist...", "Create github gist", ICON); } @Override diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form index 7db5ce3f3bcf..0e95f6830868 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form @@ -37,10 +37,7 @@ - - - - + diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/after.groovy.template new file mode 100644 index 000000000000..b97ee20b7d0e --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/after.groovy.template @@ -0,0 +1,2 @@ + +x = 0b110000; diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/before.groovy.template new file mode 100644 index 000000000000..31180db4ef5b --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/before.groovy.template @@ -0,0 +1,2 @@ + +x = 48; diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/description.html new file mode 100644 index 000000000000..f3725552e96d --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToBinaryIntention/description.html @@ -0,0 +1,6 @@ + + +This intention converts selected integer literal (written in either decimal or hexadecimal or octal notation) +into binary notation. + + diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToDecimalIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToDecimalIntention/description.html index 2232a4be43e0..801ea56f1e90 100644 --- a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToDecimalIntention/description.html +++ b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToDecimalIntention/description.html @@ -1,7 +1,7 @@ -This intention converts selected integer literal (written in either hexadecimal or octal notation) +This intention converts selected integer literal (written in either hexadecimal or octal or binary notation) into decimal notation. diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToHexIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToHexIntention/description.html index a76ad7175293..05cb64ead0ea 100644 --- a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToHexIntention/description.html +++ b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToHexIntention/description.html @@ -1,7 +1,7 @@ -This intention converts selected integer literal (written in either decimal or octal notation) +This intention converts selected integer literal (written in either decimal or octal or binary notation) into hexadecimal notation. diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToOctalIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToOctalIntention/description.html index 0b690cad27c7..b7a9d1c8a949 100644 --- a/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToOctalIntention/description.html +++ b/plugins/groovy/resources/intentionDescriptions/ConvertIntegerToOctalIntention/description.html @@ -1,7 +1,7 @@ -This intention converts selected integer literal (written in either decimal or hexadecimal notation) -back into octal notation. +This intention converts selected integer literal (written in either decimal or hexadecimal or binary notation) +into octal notation. diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 9a2188953171..aaff48c9eb55 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -343,8 +343,6 @@ - - @@ -366,6 +364,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle @@ -489,6 +809,11 @@ intention.category.groovy/intention.category.conversions org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToOctalIntention + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle + intention.category.groovy/intention.category.conversions + org.jetbrains.plugins.groovy.intentions.conversions.ConvertIntegerToBinaryIntention + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle intention.category.groovy/intention.category.conversions diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionProvider.java deleted file mode 100644 index f0b5897eb45c..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/GroovyInspectionProvider.java +++ /dev/null @@ -1,184 +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 org.jetbrains.plugins.groovy.codeInspection; - -import com.intellij.codeInspection.InspectionToolProvider; -import com.intellij.openapi.components.ApplicationComponent; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.annotator.inspections.GroovyImmutableAnnotationInspection; -import org.jetbrains.plugins.groovy.annotator.inspections.GroovySingletonAnnotationInspection; -import org.jetbrains.plugins.groovy.codeInspection.assignment.*; -import org.jetbrains.plugins.groovy.codeInspection.bugs.*; -import org.jetbrains.plugins.groovy.codeInspection.confusing.*; -import org.jetbrains.plugins.groovy.codeInspection.control.*; -import org.jetbrains.plugins.groovy.codeInspection.exception.*; -import org.jetbrains.plugins.groovy.codeInspection.gpath.*; -import org.jetbrains.plugins.groovy.codeInspection.metrics.*; -import org.jetbrains.plugins.groovy.codeInspection.naming.*; -import org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection; -import org.jetbrains.plugins.groovy.codeInspection.secondUnsafeCall.SecondUnsafeCallInspection; -import org.jetbrains.plugins.groovy.codeInspection.threading.*; -import org.jetbrains.plugins.groovy.codeInspection.unassignedVariable.UnassignedVariableAccessInspection; -import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUnresolvedAccessInspection; -import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection; -import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection; -import org.jetbrains.plugins.groovy.codeInspection.validity.GroovyDuplicateSwitchBranchInspection; -import org.jetbrains.plugins.groovy.codeInspection.validity.GroovyUnreachableStatementInspection; - -/** - * @author ilyas - */ -public class GroovyInspectionProvider implements InspectionToolProvider, ApplicationComponent { - - public Class[] getInspectionClasses() { - return new Class[] { - SecondUnsafeCallInspection.class, - UnusedDefInspection.class, - UnassignedVariableAccessInspection.class, - MissingReturnInspection.class, - - GroovyAssignabilityCheckInspection.class, - GroovyResultOfAssignmentUsedInspection.class, - GroovyAssignmentCanBeOperatorAssignmentInspection.class, - GroovyAssignmentToForLoopParameterInspection.class, - GroovyAssignmentToMethodParameterInspection.class, - GroovyNestedAssignmentInspection.class, - GroovySillyAssignmentInspection.class, - GroovyUncheckedAssignmentOfMemberOfRawTypeInspection.class, - - GroovyContinueOrBreakFromFinallyBlockInspection.class, - GroovyReturnFromFinallyBlockInspection.class, - GroovyThrowFromFinallyBlockInspection.class, - GroovyEmptyCatchBlockInspection.class, - GroovyEmptyFinallyBlockInspection.class, - GroovyEmptyTryBlockInspection.class, - GroovyUnusedCatchParameterInspection.class, - - GroovyBreakInspection.class, - GroovyContinueInspection.class, - GroovyUnreachableStatementInspection.class, - GroovyLoopStatementThatDoesntLoopInspection.class, - GroovyConditionalWithIdenticalBranchesInspection.class, - GroovyConditionalCanBeElvisInspection.class, - GroovyConditionalCanBeConditionalCallInspection.class, - GroovyIfStatementWithIdenticalBranchesInspection.class, - GroovyIfStatementWithTooManyBranchesInspection.class, - GroovyFallthroughInspection.class, - GroovyUnnecessaryContinueInspection.class, - GroovyUnnecessaryReturnInspection.class, - GroovySwitchStatementWithNoDefaultInspection.class, - GroovyReturnFromClosureCanBeImplicitInspection.class, - GroovyTrivialConditionalInspection.class, - GroovyConstantConditionalInspection.class, - GroovyConstantIfStatementInspection.class, - GroovyTrivialIfInspection.class, - - GroovyAccessToStaticFieldLockedOnInstanceInspection.class, - GroovyDoubleCheckedLockingInspection.class, - GroovyUnconditionalWaitInspection.class, - GroovyPublicFieldAccessedInSynchronizedContextInspection.class, - GroovyBusyWaitInspection.class, - GroovyEmptySyncBlockInspection.class, - GroovySynchronizationOnThisInspection.class, - GroovySynchronizedMethodInspection.class, - GroovyNestedSynchronizedStatementInspection.class, - GroovyThreadStopSuspendResumeInspection.class, - GroovySystemRunFinalizersOnExitInspection.class, - GroovyNotifyWhileNotSynchronizedInspection.class, - GroovyWaitCallNotInLoopInspection.class, - GroovyWaitWhileNotSynchronizedInspection.class, - GroovySynchronizationOnNonFinalFieldInspection.class, - GroovySynchronizationOnVariableInitializedWithLiteralInspection.class, - GroovyUnsynchronizedMethodOverridesSynchronizedMethodInspection.class, - GroovyWhileLoopSpinsOnFieldInspection.class, - - GroovyMethodParameterCountInspection.class, - GroovyOverlyComplexMethodInspection.class, - GroovyOverlyLongMethodInspection.class, - GroovyOverlyNestedMethodInspection.class, - GroovyMethodWithMoreThanThreeNegationsInspection.class, - GroovyMultipleReturnPointsPerMethodInspection.class, - - GroovyNestedSwitchInspection.class, - GroovyConditionalInspection.class, - GrFieldAlreadyDefinedInspection.class, - GroovyNestedConditionalInspection.class, - GroovyNegatedConditionalInspection.class, - GroovyNegatedIfInspection.class, - GroovyResultOfIncrementOrDecrementUsedInspection.class, - UnnecessaryQualifiedReferenceInspection.class, - GroovyEmptyStatementBodyInspection.class, - GroovyPointlessBooleanInspection.class, - GroovyPointlessArithmeticInspection.class, - GroovyDoubleNegationInspection.class, - GroovyOverlyComplexArithmeticExpressionInspection.class, - GroovyOverlyComplexBooleanExpressionInspection.class, - GroovyOctalIntegerInspection.class, - - GroovyDuplicateSwitchBranchInspection.class, - - GroovyNonShortCircuitBooleanInspection.class, - GroovyInfiniteLoopStatementInspection.class, - GroovyInfiniteRecursionInspection.class, - GroovyDivideByZeroInspection.class, - GroovyResultOfObjectAllocationIgnoredInspection.class, - GroovyAccessibilityInspection.class, - GroovyConstructorNamedArgumentsInspection.class, - GroovyRangeTypeCheckInspection.class, - GroovyLabeledStatementInspection.class, - - GroovyClassNamingConventionInspection.class, - GroovyInterfaceNamingConventionInspection.class, - GroovyAnnotationNamingConventionInspection.class, - GroovyEnumerationNamingConventionInspection.class, - GroovyLocalVariableNamingConventionInspection.class, - GroovyStaticMethodNamingConventionInspection.class, - GroovyStaticVariableNamingConventionInspection.class, - GroovyInstanceMethodNamingConventionInspection.class, - GroovyInstanceVariableNamingConventionInspection.class, - GroovyConstantNamingConventionInspection.class, - GroovyParameterNamingConventionInspection.class, - - GroovyGetterCallCanBePropertyAccessInspection.class, - GroovySetterCallCanBePropertyAccessInspection.class, - GroovyMapGetCanBeKeyedAccessInspection.class, - GroovyMapPutCanBeKeyedAccessInspection.class, - GroovyListGetCanBeKeyedAccessInspection.class, - GroovyListSetCanBeKeyedAccessInspection.class, - - GroovyUntypedAccessInspection.class, - GroovyUnresolvedAccessInspection.class, - - GroovyImmutableAnnotationInspection.class, - GroovySingletonAnnotationInspection.class - }; - } - - @NonNls - @NotNull - public String getComponentName() { - return "GroovyInspectionProvider"; - } - - public void initComponent() { - - } - - public void disposeComponent() { - - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOctalIntegerInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOctalIntegerInspection.java index f1806d540957..f93c7a7a74cb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOctalIntegerInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyOctalIntegerInspection.java @@ -19,9 +19,9 @@ import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; -import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; import org.jetbrains.plugins.groovy.codeInspection.BaseInspection; +import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; public class GroovyOctalIntegerInspection extends BaseInspection { @@ -52,6 +52,7 @@ public class GroovyOctalIntegerInspection extends BaseInspection { @NonNls final String text = literal.getText(); if (text.startsWith("0") && !"0".equals(text) && !text.startsWith("0x") && !text.startsWith("0X") && + !text.startsWith("0b") && !text.startsWith("0B") && !text.contains(".") && !text.contains("e") && !text.contains("E")) { registerError(literal); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyFindUsagesProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyFindUsagesProvider.java index 7389efc525e7..b4c3ac89490d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyFindUsagesProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyFindUsagesProvider.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrLabeledStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.refactoring.rename.PropertyForRename; @@ -61,6 +62,7 @@ public class GroovyFindUsagesProvider implements FindUsagesProvider { if (element instanceof PsiVariable || element instanceof GrReferenceExpression) return "variable"; if (element instanceof GrLabeledStatement) return "label"; if (element instanceof PropertyForRename) return "property"; + if (element instanceof GrClosableBlock) return "closure"; return ""; } @@ -90,6 +92,8 @@ public class GroovyFindUsagesProvider implements FindUsagesProvider { return ((GrLabeledStatement)element).getLabelName(); } else if (element instanceof PropertyForRename) { return ((PropertyForRename)element).getPropertyName(); + } else if (element instanceof GrClosableBlock) { + return "closure"; } return ""; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorReference.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorReference.java index 54040682455a..3cce2e414f6e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorReference.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorReference.java @@ -9,15 +9,18 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; +import org.jetbrains.plugins.groovy.gpp.GppTypeConverter; import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; +import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -68,6 +71,12 @@ public class LiteralConstructorReference extends PsiReferenceBase.Poly> myMethodToBodyMap = new HashMap>(); - - if (body != null) { - for (PsiElement element : body.getChildren()) { - if (element instanceof GrMethod) { - GrOpenBlock block = ((GrMethod)element).getBlock(); - if (block != null) { - ArrayList list = new ArrayList(); - for (PsiElement child : block.getChildren()) { - if (child != block.getLBrace() && child != block.getRBrace()) { - list.add(child); - } - } - myMethodToBodyMap.put(((GrMethod)element), list); - } - } - } + List> methods = new ArrayList>(); + for (GrMethod method : body.getGroovyMethods()) { + methods.add(new Pair(method, method.getBlock())); } - + final PsiClass iface = (PsiClass)resolved; final Collection collection = OverrideImplementUtil.getMethodsToOverrideImplement(anonymous, true); for (CandidateInfo info : collection) { - myMethodToBodyMap.put((PsiMethod)info.getElement(), Collections.emptyList()); + methods.add(new Pair((PsiMethod)info.getElement(), null)); } - if (myMethodToBodyMap.size() == 1) { - createSingleMethodWrapper(project, iface, newExpr, myMethodToBodyMap); + + StringBuilder buffer = new StringBuilder(); + if (methods.size() == 1) { + final Pair pair = methods.get(0); + appendClosureTextByMethod(pair.getFirst(), buffer, pair.getSecond(), newExpr); } else { - createMultipleMethodWrapper(project, iface, newExpr, myMethodToBodyMap); - } - } - - private static void createMultipleMethodWrapper(final Project project, - final PsiClass iface, - final GrNewExpression newExpression, - final HashMap> methodToBodyMap) - throws IncorrectOperationException { - - final ArrayList typesToImport = new ArrayList(); - StringBuffer buffer = new StringBuffer(); - final int length = methodToBodyMap.size(); - buffer.append("["); - final Iterator iterator = methodToBodyMap.keySet().iterator(); - if (iterator.hasNext()) { + buffer.append("["); buffer.append("\n"); - appendMethodEntry(iterator.next(), typesToImport, buffer, methodToBodyMap); + for (Pair pair : methods) { + final PsiMethod method = pair.getFirst(); + final GrOpenBlock block = pair.getSecond(); + buffer.append(method.getName()).append(": "); + appendClosureTextByMethod(method, buffer, block, newExpr); + buffer.append(",\n"); + } + if (methods.size() > 0) { + buffer.delete(buffer.length() - 2, buffer.length()); + buffer.append('\n'); + } + buffer.append("]"); } - while (iterator.hasNext()) { - buffer.append(",\n"); - appendMethodEntry(iterator.next(), typesToImport, buffer, methodToBodyMap); - } - if (length > 0) { - buffer.append("\n"); - } - buffer.append("]"); - - buffer.append(" as ").append(iface.getName()); - - createAndAdjustNewExpression(project, newExpression, typesToImport, buffer); - } - - private static void appendMethodEntry(final PsiMethod method, - final ArrayList typesToImport, - final StringBuffer buffer, - HashMap> methodToBodyMap) { - buffer.append(method.getName()).append(":").append(" "); - appendClosureTextByMethod(method, buffer, typesToImport, methodToBodyMap); - } - - private static void createSingleMethodWrapper(final Project project, - final PsiClass iface, - final GrNewExpression newExpression, - HashMap> methodToBodyMap) throws IncorrectOperationException { - final ArrayList typesToImport = new ArrayList(); - StringBuffer buffer = new StringBuffer(); - - final PsiMethod method = methodToBodyMap.keySet().iterator().next(); - // Create closure text - appendClosureTextByMethod(method, buffer, typesToImport, methodToBodyMap); - // create safe type cast - buffer.append(" as ").append(iface.getName()); - createAndAdjustNewExpression(project, newExpression, typesToImport, buffer); + buffer.append(" as ").append(iface.getQualifiedName()); + createAndAdjustNewExpression(project, newExpr, buffer); } private static void createAndAdjustNewExpression(final Project project, final GrNewExpression newExpression, - final ArrayList typesToImport, - final StringBuffer buffer) throws IncorrectOperationException { - final PsiFile file = newExpression.getContainingFile(); - - final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); - final GrExpression expr = factory.createExpressionFromText(buffer.toString()); + final StringBuilder buffer) throws IncorrectOperationException { + final GrExpression expr = GroovyPsiElementFactory.getInstance(project).createExpressionFromText(buffer.toString()); final GrExpression safeTypeExpr = newExpression.replaceWithExpression(expr, false); - - //add necessary imports - if (file instanceof GroovyFileBase) { - final GroovyFileBase fileBase = (GroovyFileBase)file; - //collect unresolved references - final List unresolved = new ArrayList(); - safeTypeExpr.accept(new GroovyElementVisitor() { - public void visitElement(final GroovyPsiElement element) { - for (PsiElement psiElement : element.getChildren()) { - if (psiElement instanceof GroovyPsiElement) { - ((GroovyPsiElement)psiElement).accept(this); - } - } - } - - @Override - public void visitCodeReferenceElement(final GrCodeReferenceElement refElement) { - final String name = refElement.getReferenceName(); - if (refElement.getQualifier() == null && refElement.resolve() == null && name != null) { - unresolved.add(refElement); - } - } - }); - - for (PsiType type : typesToImport) { - if (type instanceof PsiClassType) { - final PsiClass clazz = ((PsiClassType)type).resolve(); - for (GrCodeReferenceElement element : unresolved) { - if (clazz != null && clazz.getName() != null && clazz.getName().equals(element.getReferenceName())) { - fileBase.addImportForClass(clazz); - } - } - } - } - } - - //place caret to correct place -// moveCaretToCorrectPosition(editor, safeTypeExpr); + GrReferenceAdjuster.shortenReferences(safeTypeExpr); } private static void appendClosureTextByMethod(final PsiMethod method, - final StringBuffer buffer, - final ArrayList typesToImport, - HashMap> methodToBodyMap) { + final StringBuilder buffer, + @Nullable GrOpenBlock block, + GroovyPsiElement context) { final PsiParameterList list = method.getParameterList(); buffer.append("{ "); final PsiParameter[] parameters = list.getParameters(); @@ -210,54 +122,43 @@ public class ReplaceAbstractClassInstanceByMapIntention extends Intention { if (parameters.length > 0) { final PsiParameter first = parameters[0]; final PsiType type = first.getType(); - typesToImport.add(type); - buffer.append(type.getPresentableText()).append(" "); - buffer.append(createName(generatedNames, first, type)); + buffer.append(type.getCanonicalText()).append(" "); + buffer.append(createName(generatedNames, first, type, context)); } for (int i = 1; i < parameters.length; i++) { buffer.append(", "); final PsiParameter param = parameters[i]; final PsiType type = param.getType(); - typesToImport.add(type); - buffer.append(type.getPresentableText()).append(" "); - String name = createName(generatedNames, param, type); + buffer.append(type.getCanonicalText()).append(" "); + String name = createName(generatedNames, param, type, context); buffer.append(name); } if (parameters.length > 0) { - buffer.append(" ->\n"); + buffer.append(" ->"); } - for (PsiElement element : methodToBodyMap.get(method)) { - buffer.append(element.getText()).append("\n"); + if (block != null) { + final PsiElement lBrace = block.getLBrace(); + final PsiElement rBrace = block.getRBrace(); + for (PsiElement child = lBrace != null ? lBrace.getNextSibling() : block.getFirstChild(); + child != null && child != rBrace; + child = child.getNextSibling()) { + buffer.append(child.getText()); + } } - buffer.append(" }"); } - private static String createName(final Set generatedNames, final PsiParameter param, final PsiType type) { + private static String createName(final Set generatedNames, final PsiParameter param, final PsiType type, GroovyPsiElement context) { String name = param.getName(); if (name == null) { - name = generateNameByType(type, generatedNames); + name = GroovyNameSuggestionUtil.suggestVariableNameByType(type, new DefaultGroovyVariableNameValidator(context, generatedNames))[0]; assert name != null; } generatedNames.add(name); return name; } - private static String generateNameByType(final PsiType type, final Set set) { - final String text = type.getPresentableText(); - final ArrayList strings = GroovyNamesUtil.camelizeString(text); - assert strings.size() > 0; - final String last = strings.get(strings.size() - 1).toLowerCase(); - int i = 1; - String name = last; - while (set.contains(name)) { - name = last + i; - i++; - } - return name; - } - static class MyPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { if (element instanceof GrNewExpression) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java index 426047ad009b..35e0ab68089c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParserDefinition.java @@ -26,6 +26,7 @@ import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.psi.tree.TokenSet; @@ -83,20 +84,24 @@ public class GroovyParserDefinition implements ParserDefinition { } public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) { - if (right.getElementType() == kIMPORT && left.getElementType() != TokenType.WHITE_SPACE) { + final IElementType lType = left.getElementType(); + final IElementType rType = right.getElementType(); + + if (rType == kIMPORT && lType != TokenType.WHITE_SPACE) { return MUST_LINE_BREAK; } - else if (left.getElementType() == MODIFIERS && right.getElementType() == MODIFIERS) { + else if (lType == MODIFIERS && rType == MODIFIERS) { return MUST; } - if (left.getElementType() == mSEMI || left.getElementType() == mSL_COMMENT) { + if (lType == mSEMI || lType == mSL_COMMENT) { return MUST_LINE_BREAK; } - if (left.getElementType() == mNLS || left.getElementType() == mGDOC_COMMENT_START) { + if (lType == mNLS || lType == mGDOC_COMMENT_START) { return MAY; } - - if (left.getElementType() == mDOLLAR) return MUST_NOT; + + final IElementType parentType = left.getTreeParent().getElementType(); + if (parentType == GSTRING || parentType == REGEX || parentType == GSTRING_INJECTION) return MUST_NOT; return LanguageUtil.canStickTokensTogetherByLexer(left, right, new GroovyLexer()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java index 4683165f29e5..aad90873f1a1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java @@ -4,7 +4,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author peter @@ -13,7 +13,7 @@ public abstract class GrTypeConverter { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.intellij.groovy.typeConverter"); protected static boolean isMethodCallConversion(GroovyPsiElement context) { - return context.getParent() instanceof GrMethodCall; + return PsiUtil.isInMethodCallContext(context); } @Nullable diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 3b0af34d927e..44750d6c59d2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -105,13 +105,14 @@ public class PsiImplUtil { // check priorities GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(oldExpr.getProject()); - if (oldExpr.getParent() instanceof GrStringInjection) { + if (oldParent instanceof GrStringInjection) { if (newExpr instanceof GrString || newExpr instanceof GrLiteral && ((GrLiteral)newExpr).getValue() instanceof String) { - return GrStringUtil.replaceStringInjectionByLiteral((GrStringInjection)oldExpr.getParent(), (GrLiteral)newExpr); + return GrStringUtil.replaceStringInjectionByLiteral((GrStringInjection)oldParent, (GrLiteral)newExpr); } else { newExpr = factory.createExpressionFromText("{" + newExpr.getText() + "}"); - return (GrExpression)((GrClosableBlock)oldExpr.replace(newExpr)).getStatements()[0]; + oldParent.getNode().replaceChild(oldExpr.getNode(), newExpr.getNode()); + return newExpr; } } else if (PsiTreeUtil.getParentOfType(oldExpr, GrStringInjection.class, false, GrCodeBlock.class) != null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java index ee9cd8fbef5f..14e3a052885b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrClosableBlockImpl.java @@ -57,7 +57,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil; * @author ilyas */ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock { - private volatile GrParameter mySyntheticItParameter; + private GrParameter[] mySyntheticItParameter; public GrClosableBlockImpl(@NotNull IElementType type, CharSequence buffer) { super(type, buffer); @@ -102,7 +102,10 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock processor.handleEvent(ResolveUtil.DECLARATION_SCOPE_PASSED, this); } - if (!ResolveUtil.processElement(processor, getOwner(), state)) return false; + String nameHint = ResolveUtil.getNameHint(processor); + if (nameHint == null || nameHint.equals(OWNER_NAME)) { + if (!processor.execute(getOwner(), state)) return false; + } final PsiClass closureClass = GroovyPsiManager.getInstance(getProject()).findClassWithCache(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, getResolveScope()); if (closureClass != null) { @@ -134,7 +137,7 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock public GrParameter[] getAllParameters() { if (hasParametersSection()) return getParameters(); - return new GrParameter[]{getSyntheticItParameter()}; + return getSyntheticItParameter(); } @Override @@ -180,10 +183,10 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock return getType(); } - public GrParameter getSyntheticItParameter() { - GrParameter res = mySyntheticItParameter; + public GrParameter[] getSyntheticItParameter() { + GrParameter[] res = mySyntheticItParameter; if (res == null) { - res = new ClosureSyntheticParameter(this); + res = new GrParameter[]{new ClosureSyntheticParameter(this)}; synchronized (this) { if (mySyntheticItParameter == null) { mySyntheticItParameter = res; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 8731c12f7e07..d40154d97101 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -19,7 +19,6 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.codeInsight.completion.PrefixMatcher; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.ResolveCache; @@ -419,16 +418,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl result = new ArrayList(); + final PsiField field = clazz.findFieldByName(refName, false); if (field != null && field.hasModifierProperty(PsiModifier.STATIC)) { result.add(new GroovyResolveResultImpl(field, helper.isAccessible(field, ref, null))); @@ -480,6 +487,12 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl{0} cannot be inlined. variable.is.accessed.for.writing=Variable ''{0}'' is accessed for writing +introduce.closure.parameter.elements.header=Adding parameter to a closure diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java index 95719197579a..d9c636a877dc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.parameter; import com.intellij.codeInsight.ChangeContextUtil; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.search.searches.MethodReferencesSearch; @@ -35,11 +36,13 @@ import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import gnu.trove.TIntProcedure; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; +import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; @@ -48,10 +51,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; @@ -59,15 +59,19 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAc import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; +import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; +import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction; import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; +import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import org.jetbrains.plugins.groovy.refactoring.inline.InlineMethodConflictSolver; import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.FieldConflictsResolver; import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.OldReferencesResolver; import java.util.ArrayList; +import java.util.BitSet; import java.util.Collection; import java.util.List; @@ -105,7 +109,7 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess @Override public String getProcessedElementsHeader() { - return RefactoringBundle.message("introduce.parameter.elements.header"); + return GroovyRefactoringBundle.message("introduce.closure.parameter.elements.header"); } }; } @@ -188,13 +192,20 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess ArrayList result = new ArrayList(); if (!mySettings.generateDelegate() && toSearchFor != null) { - Collection refs = ReferencesSearch.search(toSearchFor, toSearchFor.getResolveScope(), true).findAll(); + Collection refs; if (toSearchFor instanceof GrField) { + refs = ReferencesSearch.search(toSearchFor, toSearchFor.getResolveScope(), true).findAll(); final GrAccessorMethod[] getters = ((GrField)toSearchFor).getGetters(); for (GrAccessorMethod getter : getters) { refs.addAll(MethodReferencesSearch.search(getter, getter.getResolveScope(), true).findAll()); } } + else if (toSearchFor instanceof GrVariable) { + refs = findUsagesForLocal(toReplaceIn, ((GrVariable)toSearchFor)); + } + else { + refs = ReferencesSearch.search(toSearchFor, toSearchFor.getResolveScope(), true).findAll(); + } for (PsiReference ref1 : refs) { PsiElement ref = ref1.getElement(); @@ -205,6 +216,10 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess result.add(new ChangedMethodCallInfo(ref)); } } + + if (toSearchFor instanceof GrVariable && !((GrVariable)toSearchFor).hasModifierProperty(PsiModifier.FINAL)) { + setPreviewUsages(true); + } } if (mySettings.replaceAllOccurrences()) { @@ -223,6 +238,60 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess return UsageViewUtil.removeDuplicatedUsages(usageInfos); } + private static Collection findUsagesForLocal(GrClosableBlock initializer, final GrVariable var) { + final Instruction[] flow = ControlFlowUtils.findControlFlowOwner(initializer).getControlFlow(); + final ArrayList writes = ControlFlowUtils.inferWriteAccessMap(flow, var); + + Instruction writeInstr = null; + + final PsiElement parent = initializer.getParent(); + if (parent instanceof GrVariable) { + writeInstr = ContainerUtil.find(flow, new Condition() { + @Override + public boolean value(Instruction instruction) { + return instruction.getElement() == var; + } + }); + } + else if (parent instanceof GrAssignmentExpression) { + final GrReferenceExpression refExpr = (GrReferenceExpression)((GrAssignmentExpression)parent).getLValue(); + final Instruction instruction = ContainerUtil.find(flow, new Condition() { + @Override + public boolean value(Instruction instruction) { + return instruction.getElement() == refExpr; + } + }); + + LOG.assertTrue(instruction != null); + final BitSet prev = writes.get(instruction.num()); + if (prev.cardinality() == 1) { + writeInstr = flow[prev.nextSetBit(0)]; + } + } + + LOG.assertTrue(writeInstr != null); + + Collection result = new ArrayList(); + for (Instruction instruction : flow) { + if (!(instruction instanceof ReadWriteVariableInstruction)) continue; + if (((ReadWriteVariableInstruction)instruction).isWrite()) continue; + + final PsiElement element = instruction.getElement(); + if (element instanceof GrVariable && element != var) continue; + if (!(element instanceof GrReferenceExpression)) continue; + + final GrReferenceExpression ref = (GrReferenceExpression)element; + if (ref.isQualified() || ref.resolve() != var) continue; + + final BitSet prev = writes.get(instruction.num()); + if (prev.cardinality() == 1 && prev.get(writeInstr.num())) { + result.add(ref); + } + } + + return result; + } + @Override protected void performRefactoring(UsageInfo[] usages) { if (mySettings.generateDelegate()) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java index 9e61a3fa7f85..2cdcd43a7840 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java @@ -52,13 +52,16 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyIcons; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -276,7 +279,17 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler { private static GrVariable findVariableToUse(GrParametersOwner owner) { final PsiElement parent = owner.getParent(); if (parent instanceof GrVariable) return (GrVariable)parent; - + if (parent instanceof GrAssignmentExpression && + ((GrAssignmentExpression)parent).getRValue() == owner && + ((GrAssignmentExpression)parent).getOperationToken() == GroovyTokenTypes.mASSIGN) { + final GrExpression lValue = ((GrAssignmentExpression)parent).getLValue(); + if (lValue instanceof GrReferenceExpression) { + final PsiElement resolved = ((GrReferenceExpression)lValue).resolve(); + if (resolved instanceof GrVariable) { + return (GrVariable)resolved; + } + } + } return null; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy index 3bc2eef4e340..8d70081f7843 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy @@ -440,6 +440,17 @@ class Point { configureGppScript "Point p = [239, 42]" assertEquals 2, multiResolveReference().size() + configureGppScript """ +def foo(Point p) {} +foo([2, 3]) +""" + assertEquals 2, multiResolveReference().size() + + configureGppScript """ +def foo(Point... p) {} +foo(['super':[2, 3]]) +""" + assertEquals 2, multiResolveReference().size() } public void testGotoClassFromLiteralOnsetsWhenNoConstructorsPresent() throws Exception { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy index db83752af748..3d9d20690f89 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/LiteralConstructorUsagesTest.groovy @@ -77,6 +77,98 @@ Foo untyped() { [] } assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size()) } + public void testList_GppMethodCall() throws Exception { + //------------------------declarations + def foo = myFixture.addClass(""" + package z; + class Foo { + public Foo() {} + } + """) + + myFixture.addClass(""" + package z; + public class Bar { + public static void giveMeFoo(int a, Foo f) {} + } +""") + myFixture.addFileToProject("Decl.groovy", "static def giveMeFooAsWell(z.Foo f) {}") + + //----------------------usages + myFixture.addFileToProject "a.gpp", "z.Bar.giveMeFoo(2, []) //usage" + myFixture.addFileToProject "b.groovy", """ + @Typed package aa; + z.Bar.giveMeFoo(3, []) //usage + """ + myFixture.addFileToProject "c.groovy", """ + @Typed def someMethod() { + z.Bar.giveMeFoo 4, [] //usage + Decl.giveMeFooAsWell([]) //usage + } + z.Bar.giveMeFoo 5, [] //non-typed context + Decl.giveMeFooAsWell([]) + """ + myFixture.addFileToProject "invalid.gpp", "z.Bar.giveMeFoo 42, 239, []" + myFixture.addFileToProject "nonGpp.groovy", "z.Bar.giveMeFoo(6, [])" + assertEquals(4, ReferencesSearch.search(foo.constructors[0]).findAll().size()) + } + + public void testList_GppConstructorCallWithSeveralParameters() throws Exception { + def foo = myFixture.addClass(""" + class Foo { + Foo() {} + } + """) + + myFixture.addClass(""" + class Bar { + Bar(Foo f1, Foo f2, Foo f3) {} + } + """) + myFixture.addFileToProject "a.gpp", "new Bar([],[],[])" + assertEquals(3, ReferencesSearch.search(foo.constructors[0]).findAll().size()) + } + + public void testMap_GppOverloads() throws Exception { + def foo = myFixture.addClass(""" + class Foo { + Foo() {} + Foo(int a) {} + } + """) + + myFixture.addClass(""" + class Bar { + static void foo(Foo f1, Foo f2) {} + } + """) + myFixture.addFileToProject "a.gpp", "Bar.foo([:], [super:2])" + assertEquals(1, ReferencesSearch.search(foo.constructors[0]).findAll().size()) + assertEquals(1, ReferencesSearch.search(foo.constructors[1]).findAll().size()) + } + + public void testGppCallVarargs() throws Exception { + def foo = myFixture.addClass(""" + class Foo { + Foo() {} + Foo(int a) {} + } + """) + + myFixture.addClass(""" + class Bar { + static void foo(Foo f1, Foo f2) {} + static void doo(int a, Foo f1, Foo f2) {} + } + """) + myFixture.addFileToProject "a.gpp", """ + Bar.foo([:], [super:2]) + Bar.doo 3, [:], [super:2] + """ + assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size()) + assertEquals(2, ReferencesSearch.search(foo.constructors[1]).findAll().size()) + } + public void testOverloadedConstructorUsages() throws Exception { def foo = myFixture.addClass(""" class Foo { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy index d8ae27cceb77..4d8517cce450 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy @@ -16,12 +16,12 @@ package org.jetbrains.plugins.groovy.lang.resolve; +import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiReference import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod import org.jetbrains.plugins.groovy.util.TestUtils -import com.intellij.psi.JavaPsiFacade /** * @author ven @@ -245,6 +245,22 @@ public class Test extends MyMap { assertEquals "a.Cl", resolve("a.groovy").qualifiedName } + void testInnerClassInStaticImport() { + myFixture.addClass("package x; public class X{public static class Inner{}}") + def resolved = resolve("a.groovy") + assertNotNull(resolved) + } + + void testInnerClassImportedByStaticImport() { + myFixture.addClass(""" +package x; +public class X{ + public static class Inner{ + } +}""") + assertNotNull(resolve("a.groovy")) + } + private void doTest() { doTest(getTestName(true) + "/" + getTestName(false) + ".groovy"); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy index c8b57896b7c6..a16e36e559d7 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy @@ -746,4 +746,8 @@ class Foo { void testDontUseQualifierScopeInDGM() { assertNull resolve('a.groovy') } + + void testInferPlusType() { + assertNotNull(resolve('a.groovy')) + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterInClosureTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterInClosureTest.java index 45f5e9b08374..8ef6db72d81a 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterInClosureTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterInClosureTest.java @@ -84,4 +84,12 @@ public class GrIntroduceParameterInClosureTest extends LightCodeInsightFixtureTe public void testDelegate() { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, true); } + + public void testVarAssignedToClosure() { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false); + } + + public void testCorrectOccurrencesForLocalVar() { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false); + } } diff --git a/plugins/groovy/testdata/groovy/refactoring/inlineLocal/varInGString.test b/plugins/groovy/testdata/groovy/refactoring/inlineLocal/varInGString.test index 1be9568a95d5..c8aa17da20d9 100644 --- a/plugins/groovy/testdata/groovy/refactoring/inlineLocal/varInGString.test +++ b/plugins/groovy/testdata/groovy/refactoring/inlineLocal/varInGString.test @@ -1,4 +1,4 @@ def s="$x+$y" print "${s}wow+$s" ----- -print "${"$x+$y" }wow+$x+$y" \ No newline at end of file +print "${"$x+$y"}wow+$x+$y" \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall.groovy b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall.groovy index 949b6ad44215..0669cac07953 100644 --- a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall.groovy +++ b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall.groovy @@ -1,2 +1,2 @@ Closure clos = {println "test" } -[1, 2, 3].each {clos.call()} \ No newline at end of file +if ([1, 2, 3].length()>1) {clos.call()} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall_after.groovy b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall_after.groovy index ed6dc7ae8bab..91115445f8a3 100644 --- a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall_after.groovy +++ b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/ClosureCall_after.groovy @@ -1,2 +1,2 @@ Closure clos = {String anObject -> println anObject } -[1, 2, 3].each {clos.call("test")} \ No newline at end of file +if ([1, 2, 3].length()>1) {clos.call("test")} \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/CorrectOccurrencesForLocalVar.groovy b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/CorrectOccurrencesForLocalVar.groovy new file mode 100644 index 000000000000..1905a1fb4c94 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/CorrectOccurrencesForLocalVar.groovy @@ -0,0 +1,13 @@ +Closure clos + +clos = {print "foo"} +clos() +clos.call() + +clos = {print "foo"} +clos() +clos.call() + +clos = {print "foo"} +clos() +clos.call() diff --git a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/CorrectOccurrencesForLocalVar_after.groovy b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/CorrectOccurrencesForLocalVar_after.groovy new file mode 100644 index 000000000000..06d25974456e --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/CorrectOccurrencesForLocalVar_after.groovy @@ -0,0 +1,13 @@ +Closure clos + +clos = {print "foo"} +clos() +clos.call() + +clos = {String anObject -> print anObject} +clos("foo") +clos.call("foo") + +clos = {print "foo"} +clos() +clos.call() diff --git a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/VarAssignedToClosure.groovy b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/VarAssignedToClosure.groovy new file mode 100644 index 000000000000..656d2d8360ea --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/VarAssignedToClosure.groovy @@ -0,0 +1,4 @@ +Closure clos +clos= {print "foo"} +clos() +clos.call() diff --git a/plugins/groovy/testdata/refactoring/introduceParameterInClosure/VarAssignedToClosure_after.groovy b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/VarAssignedToClosure_after.groovy new file mode 100644 index 000000000000..8c9fd877dd94 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterInClosure/VarAssignedToClosure_after.groovy @@ -0,0 +1,4 @@ +Closure clos +clos= {String anObject -> print anObject} +clos("foo") +clos.call("foo") diff --git a/plugins/groovy/testdata/resolve/class/innerClassImportedByStaticImport/a.groovy b/plugins/groovy/testdata/resolve/class/innerClassImportedByStaticImport/a.groovy new file mode 100644 index 000000000000..6acfc570adc3 --- /dev/null +++ b/plugins/groovy/testdata/resolve/class/innerClassImportedByStaticImport/a.groovy @@ -0,0 +1,3 @@ +import static x.X.Inner + +print new Inner() \ No newline at end of file diff --git a/plugins/groovy/testdata/resolve/class/innerClassInStaticImport/a.groovy b/plugins/groovy/testdata/resolve/class/innerClassInStaticImport/a.groovy new file mode 100644 index 000000000000..45c2f1a66631 --- /dev/null +++ b/plugins/groovy/testdata/resolve/class/innerClassInStaticImport/a.groovy @@ -0,0 +1 @@ +import static x.X.Inner \ No newline at end of file diff --git a/plugins/groovy/testdata/resolve/method/inferPlusType/a.groovy b/plugins/groovy/testdata/resolve/method/inferPlusType/a.groovy new file mode 100644 index 000000000000..37637e20f875 --- /dev/null +++ b/plugins/groovy/testdata/resolve/method/inferPlusType/a.groovy @@ -0,0 +1,3 @@ +[[1, 2, 3], [2, 3], [0, 2]]. + collect {it + [56]}. + findAll {it.size() >= 3} \ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenBaseModifiableModelsProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenBaseModifiableModelsProvider.java index adb57ff69e80..60feedee56ae 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenBaseModifiableModelsProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenBaseModifiableModelsProvider.java @@ -32,7 +32,9 @@ import com.intellij.openapi.roots.ui.configuration.ModulesProvider; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packaging.artifacts.ArtifactModel; import com.intellij.packaging.artifacts.ModifiableArtifactModel; +import com.intellij.packaging.elements.ManifestFileProvider; import com.intellij.packaging.elements.PackagingElementResolvingContext; +import com.intellij.packaging.impl.artifacts.DefaultManifestFileProvider; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -131,6 +133,7 @@ public abstract class MavenBaseModifiableModelsProvider implements MavenModifiab private class MyPackagingElementResolvingContext implements PackagingElementResolvingContext { private final ModulesProvider myModulesProvider = new MavenModulesProvider(); private final MavenFacetsProvider myFacetsProvider = new MavenFacetsProvider(); + private final DefaultManifestFileProvider myManifestFileProvider = new DefaultManifestFileProvider(this); @NotNull public Project getProject() { @@ -159,6 +162,12 @@ public abstract class MavenBaseModifiableModelsProvider implements MavenModifiab final LibraryTable table = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(level, myProject); return table != null ? table.getLibraryByName(libraryName) : null; } + + @NotNull + @Override + public ManifestFileProvider getManifestFileProvider() { + return myManifestFileProvider; + } } private class MavenModulesProvider implements ModulesProvider {