Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Eugene Kudelevsky
2010-11-11 18:37:08 +03:00
24 changed files with 251 additions and 165 deletions
@@ -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;
@@ -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;
@@ -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<ElementIconRequest, Icon>() {
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;
@@ -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());
}
@@ -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);
@@ -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());
@@ -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);
}
@@ -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<VirtualFile, List<VirtualFile>> {
private class PackageSink extends QueryFactory<VirtualFile, Pair<IndexState, List<VirtualFile>>> {
private PackageSink() {
registerExecutor(new QueryExecutor<VirtualFile, List<VirtualFile>>() {
public boolean execute(@NotNull final List<VirtualFile> allDirs, @NotNull final Processor<VirtualFile> consumer) {
for (VirtualFile dir : allDirs) {
DirectoryInfo info = getInfoForDirectory(dir);
registerExecutor(new QueryExecutor<VirtualFile, Pair<IndexState, List<VirtualFile>>>() {
public boolean execute(@NotNull final Pair<IndexState, List<VirtualFile>> stateAndDirs,
@NotNull final Processor<VirtualFile> 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<VirtualFile> search(@NotNull String packageName, boolean includeLibrarySources) {
List<VirtualFile> allDirs = doGetDirectoriesByPackageName(packageName);
return new FilteredQuery<VirtualFile>(includeLibrarySources ? new CollectionQuery<VirtualFile>(allDirs) : createQuery(allDirs),
IS_VALID);
checkAvailability();
dispatchPendingEvents();
IndexState state = myState;
List<VirtualFile> allDirs = state.myPackageNameToDirsMap.get(packageName);
if (allDirs == null) allDirs = Collections.emptyList();
Query<VirtualFile> query = includeLibrarySources ? new CollectionQuery<VirtualFile>(allDirs)
: createQuery(Pair.create(state, allDirs));
return new FilteredQuery<VirtualFile>(query, IS_VALID);
}
}
@NotNull
public Query<VirtualFile> 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<VirtualFile> doGetDirectoriesByPackageName(@NotNull String packageName) {
dispatchPendingEvents();
List<VirtualFile> dirs = myState.myPackageNameToDirsMap.get(packageName);
return dirs != null ? dirs : Collections.<VirtualFile>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);
}
}
@@ -260,8 +260,12 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
private void switchFromStubToAST(ASTNode root, final Iterator<StubElement<?>> 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;
}
@@ -49,7 +49,7 @@ public class PsiProximityComparator implements Comparator<Object> {
};
private static final Key<Module> 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<Object> {
return - proximity1.compareTo(proximity2);
}
if (myContext == null) return 0;
Module contextModule = ModuleUtil.findModuleForPsiElement(myContext);
if (contextModule == null) return 0;
@@ -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);
@@ -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);
}
}
}
@@ -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());
@@ -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<Collection<ActiveAnnotationGutter>> 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);
}
@@ -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)
};
}
@@ -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 <code>#ref</code> is serializable while its outer class is not #loc
busy.wait.problem.descriptor=Call to <code>Thread.#ref()</code> in a loop, probably busy-waiting #loc
sleep.while.holding.lock.problem.descriptor=Call to <code>Thread.#ref()</code> while synchronized #loc
arithmetic.on.volatile.field.problem.descriptor=Arithmetic operation on volatile field <code>#ref</code> #loc
non.atomic.operation.on.volatile.field.problem.descriptor=Non-atomic operation on volatile field <code>#ref</code> #loc
call.to.native.method.while.locked.problem.descriptor=Call to native method <code>#ref()</code> in a synchronized context #loc
object.notify.problem.descriptor=<code>#ref</code> should probably be replaced with 'notifyAll()' #loc
condition.signal.problem.descriptor=<code>#ref</code> should probably be replaced with 'signalAll()' #loc
@@ -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);
@@ -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);
}
}
}
}
@@ -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;
}
}
}
@@ -1,10 +0,0 @@
<html>
<body><table> <tr> <td valign="top" height="150">
<font face="verdana" size="-1">
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.
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
</html>
@@ -0,0 +1,13 @@
<html>
<body><table> <tr> <td valign="top" height="150">
<font face="verdana" size="-1">
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 <b><font
color="#000080">Atomic*</font></b> or
<b><font color="#000080">Atomic*FieldUpdater</font></b> classes
from the <b><font color="#000080">java.util.concurrent.atomic</font></b> package.
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">New in 10, Powered by InspectionGadgets</font> </td> </tr> </table> </body>
</html>
@@ -135,6 +135,7 @@ public class GitStashUtils {
shelveManager
.unshelveChangeList(shelvedChangeList, shelvedChangeList.getChanges(), shelvedChangeList.getBinaryFiles(),
changeManager.getDefaultChangeList(), false);
shelveManager.deleteChangeList(shelvedChangeList);
}
finally {
l.setEventsSuppressed(false);
@@ -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() {
}
@@ -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;
}