diff options
Diffstat (limited to 'platform/core-impl/src')
9 files changed, 205 insertions, 53 deletions
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java index 3094304a02cb..a6b957c0c508 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java @@ -15,7 +15,6 @@ */ package com.intellij.ide.plugins; -import com.intellij.ide.IdeBundle; import com.intellij.openapi.extensions.PluginId; import com.intellij.util.containers.HashMap; import gnu.trove.TObjectIntHashMap; @@ -32,7 +31,7 @@ public class PluginDescriptorComparator implements Comparator<IdeaPluginDescript private final TObjectIntHashMap<PluginId> myIdToNumberMap = new TObjectIntHashMap<PluginId>(); private int myAvailableNumber = 1; - public PluginDescriptorComparator(IdeaPluginDescriptor[] descriptors) throws Exception{ + public PluginDescriptorComparator(IdeaPluginDescriptor[] descriptors){ final Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap = new HashMap<PluginId, IdeaPluginDescriptor>(); for (final IdeaPluginDescriptor descriptor : descriptors) { idToDescriptorMap.put(descriptor.getPluginId(), descriptor); @@ -46,18 +45,20 @@ public class PluginDescriptorComparator implements Comparator<IdeaPluginDescript } } - private void assignNumbers(PluginId id, Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap, Stack<PluginId> visited) throws Exception { + private void assignNumbers(PluginId id, Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap, Stack<PluginId> visited){ visited.push(id); try { final IdeaPluginDescriptor ideaPluginDescriptor = idToDescriptorMap.get(id); - if (ideaPluginDescriptor == null) { - // missing optional dependency + if (ideaPluginDescriptor == null || !ideaPluginDescriptor.isEnabled()) { + // missing optional dependency or already disabled due to cycles return; } final PluginId[] parentIds = ideaPluginDescriptor.getDependentPluginIds(); for (final PluginId parentId : parentIds) { if (visited.contains(parentId)) { - throw new Exception(IdeBundle.message("error.plugins.should.not.have.cyclic.dependencies") + id + "->" + parentId + "->...->" + id); + //disable plugins in the cycle + ideaPluginDescriptor.setEnabled(false); + break; } } for (PluginId parentId1 : parentIds) { diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java index cf2d45ad4945..8f4fd771ebdd 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java @@ -25,10 +25,7 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.ExtensionAreas; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.*; -import com.intellij.openapi.util.BuildNumber; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.util.io.ZipFileCache; @@ -479,8 +476,10 @@ public class PluginManagerCore { } static void prepareLoadingPluginsErrorMessage(final String errorMessage) { - if (errorMessage != null) { - if (!ApplicationManager.getApplication().isHeadlessEnvironment() && !ApplicationManager.getApplication().isUnitTestMode()) { + if (!StringUtil.isEmptyOrSpaces(errorMessage)) { + if (ApplicationManager.getApplication() != null + && !ApplicationManager.getApplication().isHeadlessEnvironment() + && !ApplicationManager.getApplication().isUnitTestMode()) { if (myPluginError == null) { myPluginError = errorMessage; } @@ -499,6 +498,7 @@ public class PluginManagerCore { } } + @Deprecated static Comparator<IdeaPluginDescriptor> getPluginDescriptorComparator(Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap) { final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap); final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph); @@ -549,6 +549,7 @@ public class PluginManagerCore { })); } + @Deprecated static IdeaPluginDescriptorImpl[] findCorePlugin(IdeaPluginDescriptorImpl[] pluginDescriptors) { for (IdeaPluginDescriptorImpl descriptor : pluginDescriptors) { if (CORE_PLUGIN_ID.equals(descriptor.getPluginId().getIdString())) { @@ -820,7 +821,7 @@ public class PluginManagerCore { message.insert(0, IdeBundle.message("error.problems.found.loading.plugins")); return message.toString(); } - return null; + return ""; } static void loadDescriptorsFromClassPath(@NotNull List<IdeaPluginDescriptorImpl> result, @Nullable StartupProgress progress) { @@ -900,14 +901,7 @@ public class PluginManagerCore { loadDescriptorsFromClassPath(result, fromSources ? progress : null); IdeaPluginDescriptorImpl[] pluginDescriptors = result.toArray(new IdeaPluginDescriptorImpl[result.size()]); - try { - Arrays.sort(pluginDescriptors, new PluginDescriptorComparator(pluginDescriptors)); - } - catch (Exception e) { - prepareLoadingPluginsErrorMessage(IdeBundle.message("error.plugins.were.not.loaded", e.getMessage())); - getLogger().info(e); - return findCorePlugin(pluginDescriptors); - } + Arrays.sort(pluginDescriptors, new PluginDescriptorComparator(pluginDescriptors)); return pluginDescriptors; } @@ -1090,12 +1084,13 @@ public class PluginManagerCore { String errorMessage = filterBadPlugins(result, disabledPluginNames); if (!brokenPluginsList.isEmpty()) { - errorMessage = "Following plugins are incompatible with current IDE build: " + StringUtil.join(brokenPluginsList, ", ") - + "<br>\n" + StringUtil.notNullize(errorMessage); + if (!StringUtil.isEmptyOrSpaces(errorMessage)) { + errorMessage += "<br>"; + } + errorMessage += "Following plugins are incompatible with current IDE build: " + StringUtil.join(brokenPluginsList, ", ") + + "<br>\n" + StringUtil.notNullize(errorMessage); } - prepareLoadingPluginsErrorMessage(errorMessage); - final Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap = new HashMap<PluginId, IdeaPluginDescriptorImpl>(); for (final IdeaPluginDescriptorImpl descriptor : result) { idToDescriptorMap.put(descriptor.getPluginId(), descriptor); @@ -1112,8 +1107,28 @@ public class PluginManagerCore { mergeOptionalConfigs(idToDescriptorMap); addModulesAsDependents(idToDescriptorMap); + final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap); + final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph); + if (!builder.isAcyclic()) { + final Couple<PluginId> circularDependency = builder.getCircularDependency(); + final PluginId id = circularDependency.getFirst(); + final PluginId parentId = circularDependency.getSecond(); + if (!StringUtil.isEmptyOrSpaces(errorMessage)) { + errorMessage += "<br>"; + } + errorMessage += IdeBundle.message("error.plugins.should.not.have.cyclic.dependencies") + id + "->" + parentId + "->...->" + id; + } + + prepareLoadingPluginsErrorMessage(errorMessage); + + final Comparator<PluginId> idComparator = builder.comparator(); // sort descriptors according to plugin dependencies - Collections.sort(result, getPluginDescriptorComparator(idToDescriptorMap)); + Collections.sort(result, new Comparator<IdeaPluginDescriptor>() { + @Override + public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { + return idComparator.compare(o1.getPluginId(), o2.getPluginId()); + } + }); for (int i = 0; i < result.size(); i++) { ourId2Index.put(result.get(i).getPluginId(), i); diff --git a/platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java b/platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java new file mode 100644 index 000000000000..a743569b1798 --- /dev/null +++ b/platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java @@ -0,0 +1,112 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.util; + +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.util.text.StringUtil; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class PropertiesComponentImpl extends PropertiesComponent implements PersistentStateComponent<Element> { + private final Map<String, String> myMap = new LinkedHashMap<String, String>(); + @NonNls private static final String ELEMENT_PROPERTY = "property"; + @NonNls private static final String ATTRIBUTE_NAME = "name"; + @NonNls private static final String ATTRIBUTE_VALUE = "value"; + + @NotNull + public String getComponentName() { + return "PropertiesComponent"; + } + + PropertiesComponentImpl() { + } + + @Override + public Element getState() { + Element parentNode = new Element("state"); + for (final String key : myMap.keySet()) { + String value = myMap.get(key); + if (value != null) { + Element element = new Element(ELEMENT_PROPERTY); + element.setAttribute(ATTRIBUTE_NAME, key); + element.setAttribute(ATTRIBUTE_VALUE, value); + parentNode.addContent(element); + } + } + return parentNode; + } + + @Override + public void loadState(final Element parentNode) { + myMap.clear(); + for (Element e : parentNode.getChildren(ELEMENT_PROPERTY)) { + String name = e.getAttributeValue(ATTRIBUTE_NAME); + if (name != null) { + myMap.put(name, e.getAttributeValue(ATTRIBUTE_VALUE)); + } + } + } + + @Override + public String getValue(String name) { + return myMap.get(name); + } + + @Override + public void setValue(String name, String value) { + myMap.put(name, value); + } + + @Override + public void setValue(@NotNull String name, @NotNull String value, @NotNull String defaultValue) { + if (value.equals(defaultValue)) { + myMap.remove(name); + } + else { + myMap.put(name, value); + } + } + + @Override + public void unsetValue(String name) { + myMap.remove(name); + } + + @Override + public boolean isValueSet(String name) { + return myMap.containsKey(name); + } + + @Override + public String[] getValues(@NonNls String name) { + final String value = getValue(name); + return value != null ? value.split("\n") : null; + } + + @Override + public void setValues(@NonNls String name, String[] values) { + if (values == null) { + setValue(name, null); + } + else { + setValue(name, StringUtil.join(values, "\n")); + } + } +}
\ No newline at end of file diff --git a/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java index 60ae5417620b..7415e0d66fad 100644 --- a/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java +++ b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java @@ -53,11 +53,11 @@ public class MockApplicationEx extends MockApplication implements ApplicationEx } @Override - public void exit(boolean force) { + public void exit(boolean force, boolean exitConfirmed) { } @Override - public void restart(boolean force) { + public void restart(boolean exitConfirmed) { } @Override diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java index acb83f1fe2fd..bf84725f7910 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java +++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java @@ -60,10 +60,18 @@ public interface ApplicationEx extends Application { void doNotSave(boolean value); boolean isDoNotSave(); - //force exit - void exit(boolean force); + /** + * @param force if true, no additional confirmations will be shown. The application is guaranteed to exit + * @param exitConfirmed if true, suppresses any shutdown confirmation. However, if there are any background processes or tasks running, + * a corresponding confirmation will be shown with the possibility to cancel the operation + */ + void exit(boolean force, boolean exitConfirmed); - void restart(boolean force); + /** + * @param exitConfirmed if true, suppresses any shutdown confirmation. However, if there are any background processes or tasks running, + * a corresponding confirmation will be shown with the possibility to cancel the operation + */ + void restart(boolean exitConfirmed); /** * Runs modal process. For internal use only, see {@link Task} diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java index 78ce83cc5154..62fbfa502c79 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java @@ -409,7 +409,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern } } else { - buffer.append(getBuild().asString()); + buffer.append(getBuild().asStringWithAllDetails()); } return buffer.toString(); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java index ce3bc9559769..7b4e9ec210ac 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -26,12 +26,15 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.LowMemoryWatcher; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileVisitor; @@ -55,6 +58,7 @@ import java.util.concurrent.ConcurrentMap; public class FileManagerImpl implements FileManager { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.impl.FileManagerImpl"); + private final Key<FileViewProvider> myPsiHardRefKey = Key.create("HARD_REFERENCE_TO_PSI"); //non-static! private final PsiManagerImpl myManager; private final FileIndexFacade myFileIndex; @@ -166,7 +170,7 @@ public class FileManagerImpl implements FileManager { @NotNull public FileViewProvider findViewProvider(@NotNull final VirtualFile file) { assert !file.isDirectory(); - FileViewProvider viewProvider = getFromInjected(file); + FileViewProvider viewProvider = findCachedViewProvider(file); if (viewProvider != null) return viewProvider; viewProvider = myVFileToViewProviderMap.get(file); if(viewProvider == null) { @@ -178,8 +182,9 @@ public class FileManagerImpl implements FileManager { @Override public FileViewProvider findCachedViewProvider(@NotNull final VirtualFile file) { FileViewProvider viewProvider = getFromInjected(file); - if (viewProvider != null) return viewProvider; - return myVFileToViewProviderMap.get(file); + if (viewProvider == null) viewProvider = myVFileToViewProviderMap.get(file); + if (viewProvider == null) viewProvider = file.getUserData(myPsiHardRefKey); + return viewProvider; } @Nullable @@ -214,9 +219,14 @@ public class FileManagerImpl implements FileManager { if (document != null) { PsiDocumentManagerBase.cachePsi(document, null); } + virtualFile.putUserData(myPsiHardRefKey, null); } else { - myVFileToViewProviderMap.put(virtualFile, fileViewProvider); + if (virtualFile instanceof LightVirtualFile) { + virtualFile.putUserData(myPsiHardRefKey, fileViewProvider); + } else { + myVFileToViewProviderMap.put(virtualFile, fileViewProvider); + } } } } @@ -398,7 +408,12 @@ public class FileManagerImpl implements FileManager { PsiDirectory psiDir = myVFileToPsiDirMap.get(vFile); if (psiDir != null) return psiDir; - if (myFileIndex.isExcludedFile(vFile)) return null; + if (Registry.is("ide.hide.excluded.files")) { + if (myFileIndex.isExcludedFile(vFile)) return null; + } + else { + if (FileTypeRegistry.getInstance().isFileIgnored(vFile)) return null; + } VirtualFile parent = vFile.getParent(); if (parent != null) { //? @@ -430,7 +445,8 @@ public class FileManagerImpl implements FileManager { @Nullable PsiFile getCachedPsiFileInner(@NotNull VirtualFile file) { - final FileViewProvider fileViewProvider = myVFileToViewProviderMap.get(file); + FileViewProvider fileViewProvider = myVFileToViewProviderMap.get(file); + if (fileViewProvider == null) fileViewProvider = file.getUserData(myPsiHardRefKey); return fileViewProvider instanceof SingleRootFileViewProvider ? ((SingleRootFileViewProvider)fileViewProvider).getCachedPsi(fileViewProvider.getBaseLanguage()) : null; } diff --git a/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java b/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java index 7d597b70c0bd..2d84c928db22 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +48,7 @@ public class ObjectStubTree<T extends Stub> { return myRoot; } + @NotNull public List<T> getPlainList() { return myPlainList; } @@ -65,7 +66,7 @@ public class ObjectStubTree<T extends Stub> { return sink.getResult(); } - protected static void enumerateStubs(final Stub root, final List<Stub> result) { + protected static void enumerateStubs(@NotNull Stub root, @NotNull List<Stub> result) { ((ObjectStubBase)root).id = result.size(); result.add(root); for (Stub child : root.getChildrenStubs()) { diff --git a/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java b/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java index b440a43b0613..bd8309313e24 100644 --- a/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java +++ b/platform/core-impl/src/com/intellij/util/indexing/FileContentImpl.java @@ -31,6 +31,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import java.io.IOException; @@ -48,7 +49,7 @@ public final class FileContentImpl extends UserDataHolderBase implements FileCon private byte[] myContent; private CharSequence myContentAsText; private final long myStamp; - private final byte[] myHash; + private byte[] myHash; @Override public Project getProject() { @@ -94,31 +95,26 @@ public final class FileContentImpl extends UserDataHolderBase implements FileCon } public FileContentImpl(@NotNull final VirtualFile file, @NotNull final CharSequence contentAsText, final Charset charset) { - this(file, contentAsText, null, charset, -1, null); + this(file, contentAsText, null, charset, -1); } public FileContentImpl(@NotNull final VirtualFile file, @NotNull final CharSequence contentAsText, final Charset charset, long documentStamp) { - this(file, contentAsText, null, charset, documentStamp, null); + this(file, contentAsText, null, charset, documentStamp); } public FileContentImpl(@NotNull final VirtualFile file, @NotNull final byte[] content) { - this(file, content, null); - } - - public FileContentImpl(@NotNull final VirtualFile file, @NotNull final byte[] content, byte[] hash) { - this(file, null, content, LoadTextUtil.detectCharsetAndSetBOM(file, content), -1, hash); + this(file, null, content, LoadTextUtil.detectCharsetAndSetBOM(file, content), -1); } public FileContentImpl(@NotNull final VirtualFile file) { - this(file, null, null, null, -1, null); + this(file, null, null, null, -1); } private FileContentImpl(@NotNull VirtualFile file, CharSequence contentAsText, byte[] content, Charset charset, - long stamp, - byte[] hash + long stamp ) { myFile = file; myContentAsText = contentAsText; @@ -128,7 +124,6 @@ public final class FileContentImpl extends UserDataHolderBase implements FileCon // remember name explicitly because the file could be renamed afterwards myFileName = file.getName(); myStamp = stamp; - myHash = hash; } @NotNull @@ -215,10 +210,14 @@ public final class FileContentImpl extends UserDataHolderBase implements FileCon return myFileName; } - public byte[] getHash() { + public @Nullable byte[] getHash() { return myHash; } + public void setHash(byte[] hash) { + myHash = hash; + } + public PsiFile getPsiFileAccountingForUnsavedDocument() { Document document = FileDocumentManager.getInstance().getCachedDocument(getFile()); PsiFile psi = null; |