diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java index efc2f822ca8a..e5592528a78f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java @@ -70,10 +70,12 @@ public class ExpectedTypesProvider { }; private static final PsiType[] PRIMITIVE_TYPES = {PsiType.BYTE, PsiType.CHAR, PsiType.SHORT, PsiType.INT, PsiType.LONG, PsiType.FLOAT, PsiType.DOUBLE}; + @NotNull public static ExpectedTypeInfo createInfo(@NotNull PsiType type, int kind, PsiType defaultType, TailType tailType) { return createInfoImpl(type, kind, defaultType, tailType); } + @NotNull private static ExpectedTypeInfoImpl createInfoImpl(@NotNull PsiType type, int kind, PsiType defaultType, TailType tailType) { int dims = 0; while (type instanceof PsiArrayType) { @@ -85,23 +87,27 @@ public class ExpectedTypesProvider { return new ExpectedTypeInfoImpl(type, kind, dims, defaultType, tailType); } + @NotNull public static ExpectedTypeInfo[] getExpectedTypes(@Nullable PsiExpression expr, boolean forCompletion) { return getExpectedTypes(expr, forCompletion, false, false); } + @NotNull public static ExpectedTypeInfo[] getExpectedTypes(@Nullable PsiExpression expr, boolean forCompletion, final boolean voidable, boolean usedAfter) { return getExpectedTypes(expr, forCompletion, ourGlobalScopeClassProvider, voidable, usedAfter); } + @NotNull public static ExpectedTypeInfo[] getExpectedTypes(@Nullable PsiExpression expr, boolean forCompletion, ExpectedClassProvider classProvider, boolean usedAfter) { return getExpectedTypes(expr, forCompletion, classProvider, false, usedAfter); } + @NotNull public static ExpectedTypeInfo[] getExpectedTypes(@Nullable PsiExpression expr, boolean forCompletion, ExpectedClassProvider classProvider, final boolean voidable, boolean usedAfter) { - if (expr == null) return null; + if (expr == null) return ExpectedTypeInfo.EMPTY_ARRAY; PsiElement parent = expr.getParent(); while (parent instanceof PsiParenthesizedExpression) { expr = (PsiExpression)parent; diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index 670be6fbde7a..f786be7e5c9a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -103,6 +103,8 @@ public class OverrideImplementUtil { PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(aClass.getProject()).getResolveHelper(); for (HierarchicalMethodSignature signature : allMethodSigs) { PsiMethod method = signature.getMethod(); + LOG.assertTrue(method.isValid()); + if (method.hasModifierProperty(PsiModifier.STATIC) || !resolveHelper.isAccessible(method, aClass, aClass)) continue; PsiClass hisClass = method.getContainingClass(); if (hisClass == null) continue; diff --git a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java index 9bde7a523ce1..738dd457457a 100644 --- a/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java +++ b/platform/lang-api/src/com/intellij/psi/impl/ElementBase.java @@ -20,6 +20,7 @@ import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.IndexNotReadyException; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.UserDataHolderBase; @@ -84,9 +85,11 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable baseIcon = myBaseIcon.get(flags); } + final Project project = psiElement.getProject(); if (isToDeferIconLoading()) { return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, flags), new NullableFunction() { public Icon fun(ElementIconRequest request) { + if (project.isDisposed()) return null; final PsiElement element = request.getElement(); if (!element.isValid()) return null; if (element.getProject().isDisposed()) return null; diff --git a/platform/lang-api/src/com/intellij/psi/util/ProximityLocation.java b/platform/lang-api/src/com/intellij/psi/util/ProximityLocation.java index 84542c91eeb2..f1554c54e86c 100644 --- a/platform/lang-api/src/com/intellij/psi/util/ProximityLocation.java +++ b/platform/lang-api/src/com/intellij/psi/util/ProximityLocation.java @@ -32,7 +32,7 @@ public class ProximityLocation implements UserDataHolder { private final Module myPositionModule; private final ProcessingContext myContext; - public ProximityLocation(final PsiElement position, final Module positionModule) { + public ProximityLocation(@Nullable final PsiElement position, final Module positionModule) { this(position, positionModule, new ProcessingContext()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index ad4955069902..dd7e941c6253 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -218,7 +218,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { @NotNull private LookupImpl obtainLookup(Editor editor, CompletionParameters parameters) { LookupImpl existing = (LookupImpl)LookupManager.getActiveLookup(editor); - if (existing != null) { + if (existing != null && existing.isCompletion()) { existing.markReused(); if (!autopopup) { existing.setFocused(true); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 829910392524..fab60030a8e6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -698,6 +698,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { int index = myList.getSelectedIndex(); Rectangle itmBounds = myList.getCellBounds(index, index); if (itmBounds == null){ + LOG.error("No bounds for " + index + "; size=" + myList.getModel().getSize()); return null; } Point layeredPanePoint=SwingUtilities.convertPoint(myList,itmBounds.x,itmBounds.y,getComponent()); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 56a061a95da7..83567e55db03 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -1375,7 +1375,7 @@ public abstract class ChooseByNameBase { private final ChooseByNameModel myModel; private final PsiProximityComparator myProximityComparator; - private PathProximityComparator(final ChooseByNameModel model, final PsiElement context) { + private PathProximityComparator(final ChooseByNameModel model, @Nullable final PsiElement context) { myModel = model; myProximityComparator = new PsiProximityComparator(context); } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index ee81f60378c5..1ce9ea5865cb 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -35,6 +35,7 @@ import com.intellij.openapi.roots.*; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter; @@ -175,8 +176,9 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone } private void doInitialize() { - myState = new IndexState(); - myState.doInitialize(false); + IndexState newState = new IndexState(); + newState.doInitialize(false); + myState = newState; } private boolean isExcludeRootForModule(Module module, VirtualFile excludeRoot) { @@ -219,12 +221,13 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone } }; - private class PackageSink extends QueryFactory> { + private class PackageSink extends QueryFactory>> { private PackageSink() { - registerExecutor(new QueryExecutor>() { - public boolean execute(@NotNull final List allDirs, @NotNull final Processor consumer) { - for (VirtualFile dir : allDirs) { - DirectoryInfo info = getInfoForDirectory(dir); + registerExecutor(new QueryExecutor>>() { + public boolean execute(@NotNull final Pair> stateAndDirs, + @NotNull final Processor consumer) { + for (VirtualFile dir : stateAndDirs.second) { + DirectoryInfo info = stateAndDirs.first.myDirToInfoMap.get(dir); assert info != null; if (!info.isInLibrarySource || info.libraryClassRoot != null) { @@ -237,15 +240,21 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone } public Query search(@NotNull String packageName, boolean includeLibrarySources) { - List allDirs = doGetDirectoriesByPackageName(packageName); - return new FilteredQuery(includeLibrarySources ? new CollectionQuery(allDirs) : createQuery(allDirs), - IS_VALID); + checkAvailability(); + dispatchPendingEvents(); + + IndexState state = myState; + List allDirs = state.myPackageNameToDirsMap.get(packageName); + if (allDirs == null) allDirs = Collections.emptyList(); + + Query query = includeLibrarySources ? new CollectionQuery(allDirs) + : createQuery(Pair.create(state, allDirs)); + return new FilteredQuery(query, IS_VALID); } } @NotNull public Query getDirectoriesByPackageName(@NotNull String packageName, boolean includeLibrarySources) { - checkAvailability(); return mySink.search(packageName, includeLibrarySources); } @@ -255,14 +264,6 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone return myState.myDirToPackageName.get(dir); } - @NotNull - private List doGetDirectoriesByPackageName(@NotNull String packageName) { - dispatchPendingEvents(); - - List dirs = myState.myPackageNameToDirsMap.get(packageName); - return dirs != null ? dirs : Collections.emptyList(); - } - private void dispatchPendingEvents() { myConnection.deliverImmediately(); } @@ -370,9 +371,10 @@ public class DirectoryIndexImpl extends DirectoryIndex implements ProjectCompone IndexState copy = null; for (VirtualFile dir : list) { - DirectoryInfo info = myState.myDirToInfoMap.remove(dir); - if (info != null) { + if (myState.myDirToInfoMap.containsKey(dir)) { if (copy == null) copy = myState.copy(); + + copy.myDirToInfoMap.remove(dir); copy.setPackageName(dir, null); } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 798d5e43dfd3..064518fe73f7 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -260,8 +260,12 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF private void switchFromStubToAST(ASTNode root, final Iterator> stubs) { + final IElementType contentElementType = getContentElementType(); + if (!(contentElementType instanceof IStubFileElementType)) { + throw new AssertionError("Invalid content element type: " + contentElementType + "; elementType=" + myElementType + "; file=" + getClass() + "; viewProvider=" + getViewProvider()); + } ((TreeElement)root).acceptTree(new RecursiveTreeElementWalkingVisitor() { - final StubBuilder builder = ((IStubFileElementType)getContentElementType()).getBuilder(); + final StubBuilder builder = ((IStubFileElementType)contentElementType).getBuilder(); @Override protected void visitNode(TreeElement tree) { @@ -624,6 +628,8 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF @Nullable private StubTree derefStub() { + if (myStub == null) return null; + synchronized (myStubLock) { return myStub != null ? myStub.get() : null; } diff --git a/platform/lang-impl/src/com/intellij/psi/util/proximity/PsiProximityComparator.java b/platform/lang-impl/src/com/intellij/psi/util/proximity/PsiProximityComparator.java index a2ed62943ac5..669d4cdabb86 100644 --- a/platform/lang-impl/src/com/intellij/psi/util/proximity/PsiProximityComparator.java +++ b/platform/lang-impl/src/com/intellij/psi/util/proximity/PsiProximityComparator.java @@ -49,7 +49,7 @@ public class PsiProximityComparator implements Comparator { }; private static final Key MODULE_BY_LOCATION = Key.create("ModuleByLocation"); - public PsiProximityComparator(PsiElement context) { + public PsiProximityComparator(@Nullable PsiElement context) { myContext = context; } @@ -68,6 +68,7 @@ public class PsiProximityComparator implements Comparator { return - proximity1.compareTo(proximity2); } + if (myContext == null) return 0; Module contextModule = ModuleUtil.findModuleForPsiElement(myContext); if (contextModule == null) return 0; diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarComponent.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarComponent.java index 5716aa6a54c7..de271c29ff7e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarComponent.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarComponent.java @@ -32,6 +32,7 @@ public class DiffToolbarComponent extends JPanel { public void resetToolbar(DiffRequest.ToolbarAddons toolBar) { if (myToolbar != null) remove(myToolbar.getComponent()); myToolbar = new DiffToolbarImpl(); + myToolbar.setTargetComponent(myWholeComponent); myToolbar.reset(toolBar); myToolbar.registerKeyboardActions(myWholeComponent); add(myToolbar.getComponent(), BorderLayout.CENTER); diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarImpl.java index 6375ee6fede0..621db6cdaf7c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffToolbarImpl.java @@ -25,6 +25,7 @@ import javax.swing.*; public class DiffToolbarImpl implements DiffToolbar { private final DefaultActionGroup myActionGroup = new DefaultActionGroup(); private ActionToolbar myActionToolbar; + private JComponent myTargetComponent; public void registerKeyboardActions(JComponent registerActionsTo) { AnAction[] actions = getAllActions(); @@ -54,9 +55,11 @@ public class DiffToolbarImpl implements DiffToolbar { } public JComponent getComponent() { - if (myActionToolbar == null) + if (myActionToolbar == null) { myActionToolbar = ActionManager.getInstance(). createActionToolbar(ActionPlaces.UNKNOWN, myActionGroup, true); + myActionToolbar.setTargetComponent(myTargetComponent); + } return myActionToolbar.getComponent(); } @@ -78,4 +81,11 @@ public class DiffToolbarImpl implements DiffToolbar { myActionGroup.removeAll(); toolBar.customize(this); } + + public void setTargetComponent(JComponent component) { + myTargetComponent = component; + if (myActionToolbar != null) { + myActionToolbar.setTargetComponent(component); + } + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java index 0748d10a7858..bb914dcb93d2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java @@ -433,7 +433,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { final byte[] content = delegate.contentsToByteArray(file); ApplicationEx application = (ApplicationEx)ApplicationManager.getApplication(); - if ((cacheContent && !delegate.isReadOnly() || (!application.isInternal() && !application.isUnitTestMode())) && + if ((!delegate.isReadOnly() || (!application.isInternal() && !application.isUnitTestMode())) && !noCaching && content.length <= FILE_LENGTH_TO_CACHE_THRESHOLD) { synchronized (INPUT_LOCK) { writeContent(file, content, delegate.isReadOnly()); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java index f567da8e2552..1ae742b0b119 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateToggleAction.java @@ -58,26 +58,12 @@ import java.util.List; * @author: lesya * @author Konstantin Bulenkov */ -public class AnnotateToggleAction extends ToggleAction implements DumbAware { +public class AnnotateToggleAction extends ToggleAction implements DumbAware, AnnotationColors { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.actions.AnnotateToggleAction"); protected static final Key> KEY_IN_EDITOR = Key.create("Annotations"); - private final static Color[] BG_COLORS = { - new Color(222, 241, 229), - new Color(234, 255, 226), - new Color(208, 229, 229), - new Color(255, 226, 199), - new Color(227, 226, 223), - new Color(255, 213, 203), - new Color(220, 204, 236), - new Color(255, 191, 195), - new Color(243, 223, 243), - new Color(217, 228, 249), - new Color(255, 251, 207), - new Color(217, 222, 229), - new Color(255, 204, 238), - new Color(236, 236, 236)}; public void update(AnActionEvent e) { + super.update(e); final boolean enabled = isEnabled(VcsContextFactory.SERVICE.getInstance().createContextOn(e)); e.getPresentation().setEnabled(enabled); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationColors.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationColors.java new file mode 100644 index 000000000000..dc3d1bd60ef8 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotationColors.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.vcs.actions; + +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public interface AnnotationColors { + Color[] BG_COLORS = { + new Color(222, 241, 229), + new Color(234, 255, 226), + new Color(208, 229, 229), + new Color(255, 226, 199), + new Color(227, 226, 223), + new Color(255, 213, 203), + new Color(220, 204, 236), + new Color(255, 191, 195), + new Color(243, 223, 243), + new Color(217, 228, 249), + new Color(255, 251, 207), + new Color(217, 222, 229), + new Color(255, 204, 238), + new Color(236, 236, 236) + }; +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index e2c4033377fd..859e402e3b82 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -816,7 +816,7 @@ set.replaceable.by.enum.set.display.name=Set replaceable with EnumSet non.static.inner.class.in.secure.context.display.name=Non-static inner class in secure context tail.recursion.display.name=Tail recursion finally.block.cannot.complete.normally.display.name='finally' block which can not complete normally -arithmetic.on.volatile.field.display.name=Arithmetic operation on volatile field +non.atomic.operation.on.volatile.field.display.name=Non-atomic operation on volatile field public.static.collection.field.display.name='public static' collection field non.exception.name.ends.with.exception.display.name=Non-exception class name ends with 'Exception' synchronized.method.display.name='synchronized' method @@ -993,7 +993,7 @@ serializable.inner.class.has.serial.version.uid.field.problem.descriptor=Inner c serializable.inner.class.with.non.serializable.outer.class.problem.descriptor=Inner class #ref is serializable while its outer class is not #loc busy.wait.problem.descriptor=Call to Thread.#ref() in a loop, probably busy-waiting #loc sleep.while.holding.lock.problem.descriptor=Call to Thread.#ref() while synchronized #loc -arithmetic.on.volatile.field.problem.descriptor=Arithmetic operation on volatile field #ref #loc +non.atomic.operation.on.volatile.field.problem.descriptor=Non-atomic operation on volatile field #ref #loc call.to.native.method.while.locked.problem.descriptor=Call to native method #ref() in a synchronized context #loc object.notify.problem.descriptor=#ref should probably be replaced with 'notifyAll()' #loc condition.signal.problem.descriptor=#ref should probably be replaced with 'signalAll()' #loc diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java index c3ee767d914f..466d5a5c6c98 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java @@ -821,7 +821,6 @@ public class InspectionGadgetsPlugin implements ApplicationComponent, private void registerThreadingInspections() { m_inspectionClasses.add(AccessToNonThreadSafeStaticFieldFromInstanceInspection.class); m_inspectionClasses.add(AccessToStaticFieldLockedOnInstanceInspection.class); - m_inspectionClasses.add(ArithmeticOnVolatileFieldInspection.class); m_inspectionClasses.add(AwaitNotInLoopInspection.class); m_inspectionClasses.add(AwaitWithoutCorrespondingSignalInspection.class); m_inspectionClasses.add(BusyWaitInspection.class); @@ -834,6 +833,7 @@ public class InspectionGadgetsPlugin implements ApplicationComponent, m_inspectionClasses.add(MethodMayBeSynchronizedInspection.class); m_inspectionClasses.add(NakedNotifyInspection.class); m_inspectionClasses.add(NestedSynchronizedStatementInspection.class); + m_inspectionClasses.add(NonAtomicOperationOnVolatileFieldInspection.class); m_inspectionClasses.add(NonSynchronizedMethodOverridesSynchronizedMethodInspection.class); m_inspectionClasses.add(NotifyCalledOnConditionInspection.class); m_inspectionClasses.add(NotifyNotInSynchronizedContextInspection.class); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ArithmeticOnVolatileFieldInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ArithmeticOnVolatileFieldInspection.java deleted file mode 100644 index 212a98d849d3..000000000000 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/ArithmeticOnVolatileFieldInspection.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * 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.siyeh.ig.threading; - -import com.intellij.psi.*; -import com.intellij.psi.tree.IElementType; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.BaseInspection; -import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.WellFormednessUtils; -import org.jetbrains.annotations.NotNull; - -public class ArithmeticOnVolatileFieldInspection extends BaseInspection { - - @NotNull - public String getDisplayName() { - return InspectionGadgetsBundle.message( - "arithmetic.on.volatile.field.display.name"); - } - - @NotNull - protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "arithmetic.on.volatile.field.problem.descriptor"); - } - - public BaseInspectionVisitor buildVisitor() { - return new AritmeticOnVolatileFieldInspection(); - } - - private static class AritmeticOnVolatileFieldInspection - extends BaseInspectionVisitor { - - @Override public void visitBinaryExpression( - @NotNull PsiBinaryExpression expression) { - super.visitBinaryExpression(expression); - if (expression.getROperand() == null) { - return; - } - final PsiJavaToken sign = expression.getOperationSign(); - final IElementType tokenType = sign.getTokenType(); - if (!JavaTokenType.ASTERISK.equals(tokenType) && - !JavaTokenType.DIV.equals(tokenType) && - !JavaTokenType.PLUS.equals(tokenType) && - !JavaTokenType.MINUS.equals(tokenType) && - !JavaTokenType.PERC.equals(tokenType)) { - return; - } - final PsiExpression lhs = expression.getLOperand(); - checkForVolatile(lhs); - final PsiExpression rhs = expression.getROperand(); - checkForVolatile(rhs); - } - - @Override public void visitAssignmentExpression( - @NotNull PsiAssignmentExpression expression) { - super.visitAssignmentExpression(expression); - if (!WellFormednessUtils.isWellFormed(expression)) { - return; - } - final PsiJavaToken sign = expression.getOperationSign(); - final IElementType tokenType = sign.getTokenType(); - if (!JavaTokenType.ASTERISKEQ.equals(tokenType) && - !JavaTokenType.DIVEQ.equals(tokenType) && - !JavaTokenType.PLUSEQ.equals(tokenType) && - !JavaTokenType.MINUSEQ.equals(tokenType) && - !JavaTokenType.PERCEQ.equals(tokenType)) { - return; - } - final PsiExpression lhs = expression.getLExpression(); - checkForVolatile(lhs); - final PsiExpression rhs = expression.getRExpression(); - checkForVolatile(rhs); - } - - private void checkForVolatile(PsiExpression expression) { - if (!(expression instanceof PsiReferenceExpression)) { - return; - } - final PsiReferenceExpression reference = - (PsiReferenceExpression)expression; - final PsiElement referent = reference.resolve(); - if (!(referent instanceof PsiField)) { - return; - } - final PsiField field = (PsiField)referent; - if (field.hasModifierProperty(PsiModifier.VOLATILE)) { - registerError(expression); - } - } - } -} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java new file mode 100644 index 000000000000..920adbe19f62 --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/threading/NonAtomicOperationOnVolatileFieldInspection.java @@ -0,0 +1,127 @@ +/* + * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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.siyeh.ig.threading; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.psiutils.VariableAccessUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class NonAtomicOperationOnVolatileFieldInspection + extends BaseInspection { + + @Override + @NotNull + public String getDisplayName() { + return InspectionGadgetsBundle.message( + "non.atomic.operation.on.volatile.field.display.name"); + } + + @Override + @NotNull + protected String buildErrorString(Object... infos) { + return InspectionGadgetsBundle.message( + "non.atomic.operation.on.volatile.field.problem.descriptor"); + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new NonAtomicOperationOnVolatileFieldVisitor(); + } + + private static class NonAtomicOperationOnVolatileFieldVisitor + extends BaseInspectionVisitor { + + @Override public void visitAssignmentExpression( + @NotNull PsiAssignmentExpression expression) { + super.visitAssignmentExpression(expression); + final PsiExpression rhs = expression.getRExpression(); + if (rhs == null) { + return; + } + final PsiExpression lhs = expression.getLExpression(); + final PsiField volatileField = findVolatileField(lhs); + if (volatileField == null) { + return; + } + final IElementType tokenType = expression.getOperationTokenType(); + if (tokenType.equals(JavaTokenType.PLUSEQ) || + tokenType.equals(JavaTokenType.MINUSEQ) || + tokenType.equals(JavaTokenType.ASTERISKEQ) || + tokenType.equals(JavaTokenType.DIVEQ) || + tokenType.equals(JavaTokenType.ANDEQ) || + tokenType.equals(JavaTokenType.OREQ)|| + tokenType.equals(JavaTokenType.XOREQ)|| + tokenType.equals(JavaTokenType.PERCEQ)|| + tokenType.equals(JavaTokenType.LTLTEQ)|| + tokenType.equals(JavaTokenType.GTGTEQ)|| + tokenType.equals(JavaTokenType.GTGTGTEQ)) { + registerError(lhs); + return; + } + if (VariableAccessUtils.variableIsUsed(volatileField, rhs)) { + registerError(lhs); + } + } + + @Override + public void visitPrefixExpression(PsiPrefixExpression expression) { + super.visitPrefixExpression(expression); + final PsiExpression operand = expression.getOperand(); + if (operand == null) { + return; + } + final PsiField volatileField = findVolatileField(operand); + if (volatileField == null) { + return; + } + registerError(operand); + } + + @Override + public void visitPostfixExpression(PsiPostfixExpression expression) { + super.visitPostfixExpression(expression); + final PsiExpression operand = expression.getOperand(); + final PsiField volatileField = findVolatileField(operand); + if (volatileField == null) { + return; + } + registerError(operand); + } + + @Nullable + private static PsiField findVolatileField(PsiExpression expression) { + if (!(expression instanceof PsiReferenceExpression)) { + return null; + } + final PsiReferenceExpression reference = + (PsiReferenceExpression)expression; + final PsiElement referent = reference.resolve(); + if (!(referent instanceof PsiField)) { + return null; + } + final PsiField field = (PsiField)referent; + if (!field.hasModifierProperty(PsiModifier.VOLATILE)) { + return null; + } + return field; + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArithmeticOnVolatileField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArithmeticOnVolatileField.html deleted file mode 100644 index 9fd582c5ed02..000000000000 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ArithmeticOnVolatileField.html +++ /dev/null @@ -1,10 +0,0 @@ - -
- -This inspection reports any uses of volatile fields in arithmetic operations. -It's a common misconception that such operations are effectively atomic, but the -Java Memory Model only specifies that loads and stores on volatile variables are -atomic. This can lead to unexpected results, including lost updates, when using -volatile fields in arithmetic operations. -
Powered by InspectionGadgets
- \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html new file mode 100644 index 000000000000..2e6bcad4ccad --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NonAtomicOperationOnVolatileField.html @@ -0,0 +1,13 @@ + +
+ +This inspection reports any non-atomic operations on volatile fields. Non-atomic +operations on volatile fields are operations where the volatile field is read and +the value is used to update the volatile field. It is possible for the value of the +field to change between the read and write, making the operation possibly invalid. +In such cases it is better to use one of the Atomic* or + Atomic*FieldUpdater classes +from the java.util.concurrent.atomic package. +
New in 10, Powered by InspectionGadgets
+ \ No newline at end of file diff --git a/plugins/git4idea/src/git4idea/update/GitStashUtils.java b/plugins/git4idea/src/git4idea/update/GitStashUtils.java index 856af6a7c8a6..14e13b582b7c 100644 --- a/plugins/git4idea/src/git4idea/update/GitStashUtils.java +++ b/plugins/git4idea/src/git4idea/update/GitStashUtils.java @@ -135,6 +135,7 @@ public class GitStashUtils { shelveManager .unshelveChangeList(shelvedChangeList, shelvedChangeList.getChanges(), shelvedChangeList.getBinaryFiles(), changeManager.getDefaultChangeList(), false); + shelveManager.deleteChangeList(shelvedChangeList); } finally { l.setEventsSuppressed(false); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNamesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNamesUtil.java index 6155c6134561..f3d2dfc0b35b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNamesUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNamesUtil.java @@ -31,7 +31,7 @@ import java.util.regex.Pattern; */ public class GroovyNamesUtil { - private static final Pattern PATTERN = Pattern.compile("[A-Za-z][a-z]*"); + private static final Pattern PATTERN = Pattern.compile("[A-Za-z][a-z0-9]*"); private GroovyNamesUtil() { } diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/PhysicalDomParentStrategy.java b/xml/dom-impl/src/com/intellij/util/xml/impl/PhysicalDomParentStrategy.java index 89b2eaefd408..afaa453d1bbd 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/PhysicalDomParentStrategy.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/PhysicalDomParentStrategy.java @@ -82,7 +82,9 @@ public class PhysicalDomParentStrategy implements DomParentStrategy { final XmlElement thatElement = ((PhysicalDomParentStrategy)o).myElement; if (xmlElementsEqual(myElement, thatElement)) { if (myElement != thatElement) { - assert myElement.getNavigationElement() == thatElement.getNavigationElement(); + final PsiElement nav1 = myElement.getNavigationElement(); + final PsiElement nav2 = thatElement.getNavigationElement(); + assert nav1 == nav2 : nav1 + "!=" + nav2; } return true; }