mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,6 +45,7 @@ public abstract class AbstractCollectionComboBoxModel<T> extends AbstractListMod
|
||||
public void setSelectedItem(@Nullable Object anItem) {
|
||||
//noinspection unchecked
|
||||
mySelection = (T)anItem;
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2332,8 +2332,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
UIUtil.drawLine(g, end.x, y1, end.x + charWidth - 1, y1);
|
||||
}
|
||||
else if (attributes.getEffectType() == EffectType.BOLD_LINE_UNDERSCORE) {
|
||||
UIUtil.drawLine(g, end.x, y - 1, end.x + charWidth - 1, y - 1);
|
||||
UIUtil.drawLine(g, end.x, y, end.x + charWidth - 1, y);
|
||||
drawBoldLineUnderScore(g, end.x, y - 1, charWidth - 1);
|
||||
}
|
||||
else if (attributes.getEffectType() != EffectType.BOXED) {
|
||||
UIUtil.drawLine(g, end.x, y, end.x + charWidth - 1, y);
|
||||
@@ -2342,6 +2341,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
}
|
||||
|
||||
private static void drawBoldLineUnderScore(Graphics g, int x, int y, int width) {
|
||||
int height = JBUI.scale(Registry.intValue("editor.bold.underline.height", 2));
|
||||
g.fillRect(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWidthInRange(int startOffset, int endOffset) {
|
||||
if (myUseNewRendering) return myView.getMaxWidthInRange(startOffset, endOffset);
|
||||
@@ -3423,8 +3427,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
else if (effectType == EffectType.BOLD_LINE_UNDERSCORE) {
|
||||
g.setColor(effectColor);
|
||||
UIUtil.drawLine(g, xStart, y, xEnd, y);
|
||||
UIUtil.drawLine(g, xStart, y + 1, xEnd, y + 1);
|
||||
drawBoldLineUnderScore(g, xStart, y, xEnd-xStart);
|
||||
g.setColor(savedColor);
|
||||
}
|
||||
else if (effectType == EffectType.STRIKEOUT) {
|
||||
|
||||
@@ -46,10 +46,7 @@ import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.PlainDocument;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.ListIterator;
|
||||
@@ -72,6 +69,22 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
public SpeedSearchBase(Comp component) {
|
||||
myComponent = component;
|
||||
|
||||
myComponent.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent event) {
|
||||
manageSearchPopup(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent event) {
|
||||
moveSearchPopup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent event) {
|
||||
moveSearchPopup();
|
||||
}
|
||||
});
|
||||
myComponent.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
@@ -568,7 +581,11 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
return;
|
||||
}
|
||||
myPopupLayeredPane.add(mySearchPopup, JLayeredPane.POPUP_LAYER);
|
||||
if (myPopupLayeredPane == null) return; // See # 27482. Somewho it does happen...
|
||||
moveSearchPopup();
|
||||
}
|
||||
|
||||
private void moveSearchPopup() {
|
||||
if (myComponent == null || mySearchPopup == null || myPopupLayeredPane == null) return;
|
||||
Point lPaneP = myPopupLayeredPane.getLocationOnScreen();
|
||||
Point componentP = getComponentLocationOnScreen();
|
||||
Rectangle r = getComponentVisibleRect();
|
||||
|
||||
@@ -539,6 +539,9 @@ editor.xcode.like.scrollbar.description=Enables auto-hideable Xcode-like editor
|
||||
editor.config.stop.at.project.root=true
|
||||
editor.config.stop.at.project.root.description=Stops searching for .editorconfig at project root (requires project reopening)
|
||||
|
||||
editor.bold.underline.height=2
|
||||
editor.bold.underline.height.description=Underline height for EffectType.BOLD_LINE_UNDERSCORE
|
||||
|
||||
JDK8042508.bug.fixed=false
|
||||
JDK8042508.bug.fixed.description=Disable check for type variable until javac bug is fixed
|
||||
|
||||
|
||||
@@ -188,7 +188,9 @@ public class Foundation {
|
||||
public static String getEncodingName(long nsStringEncoding) {
|
||||
long cfEncoding = myFoundationLibrary.CFStringConvertNSStringEncodingToEncoding(nsStringEncoding);
|
||||
ID pointer = myFoundationLibrary.CFStringConvertEncodingToIANACharSetName(cfEncoding);
|
||||
return toStringViaUTF8(pointer);
|
||||
String name = toStringViaUTF8(pointer);
|
||||
if ("macintosh".equals(name)) name = "MacRoman"; // JDK8 does not recognize IANA's "macintosh" alias
|
||||
return name;
|
||||
}
|
||||
|
||||
public static long getEncodingCode(@Nullable String encodingName) {
|
||||
|
||||
@@ -16,15 +16,14 @@
|
||||
package com.intellij.util.lang;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.io.URLUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import sun.misc.Resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
@@ -53,13 +52,8 @@ class JarLoader extends Loader {
|
||||
}
|
||||
}
|
||||
|
||||
private File getFileUrl() throws IOException {
|
||||
try {
|
||||
return new File(myURL.toURI());
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
private String getFileUrl() throws IOException {
|
||||
return FileUtil.unquote(myURL.getFile());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+56
-6
@@ -16,12 +16,11 @@
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
|
||||
public class SynchronizationUtil {
|
||||
|
||||
private SynchronizationUtil() {
|
||||
}
|
||||
private SynchronizationUtil() {}
|
||||
|
||||
public static boolean isInSynchronizedContext(PsiElement element) {
|
||||
final PsiElement context =
|
||||
@@ -29,10 +28,61 @@ public class SynchronizationUtil {
|
||||
if (context instanceof PsiSynchronizedStatement) {
|
||||
return true;
|
||||
}
|
||||
if (!(context instanceof PsiMethod)) {
|
||||
if (context instanceof PsiMethod) {
|
||||
final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)context;
|
||||
if (modifierListOwner.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (context instanceof PsiMethod || context instanceof PsiLambdaExpression) {
|
||||
final HoldsLockAssertionVisitor visitor = new HoldsLockAssertionVisitor();
|
||||
context.accept(visitor);
|
||||
final PsiAssertStatement assertStatement = visitor.getAssertStatement();
|
||||
return assertStatement != null && assertStatement.getTextOffset() + assertStatement.getTextLength() < element.getTextOffset();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isCallToHoldsLock(PsiExpression expression) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiMethodCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)context;
|
||||
return modifierListOwner.hasModifierProperty(PsiModifier.SYNCHRONIZED);
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
|
||||
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
|
||||
final String name = methodExpression.getReferenceName();
|
||||
if (!"holdsLock".equals(name)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethod method = methodCallExpression.resolveMethod();
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
return com.intellij.psi.util.InheritanceUtil.isInheritor(aClass, "java.lang.Thread");
|
||||
}
|
||||
|
||||
private static class HoldsLockAssertionVisitor extends JavaRecursiveElementVisitor {
|
||||
private PsiAssertStatement myAssertStatement = null;
|
||||
|
||||
@Override
|
||||
public void visitAssertStatement(PsiAssertStatement statement) {
|
||||
if (myAssertStatement != null) return;
|
||||
super.visitAssertStatement(statement);
|
||||
final PsiExpression condition = statement.getAssertCondition();
|
||||
if (isCallToHoldsLock(condition)) {
|
||||
myAssertStatement = statement;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (myAssertStatement != null) return;
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
public PsiAssertStatement getAssertStatement() {
|
||||
return myAssertStatement;
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -21,6 +21,7 @@ import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.siyeh.ig.psiutils.SynchronizationUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -61,6 +62,14 @@ class VariableAccessVisitor extends JavaRecursiveElementVisitor {
|
||||
m_inSynchronizedContext = wasInSync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLambdaExpression(PsiLambdaExpression expression) {
|
||||
final boolean wasInSync = m_inSynchronizedContext;
|
||||
m_inSynchronizedContext = false;
|
||||
super.visitLambdaExpression(expression);
|
||||
m_inSynchronizedContext = wasInSync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull PsiReferenceExpression ref) {
|
||||
super.visitReferenceExpression(ref);
|
||||
@@ -128,6 +137,15 @@ class VariableAccessVisitor extends JavaRecursiveElementVisitor {
|
||||
m_inSynchronizedContext = wasInSync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssertStatement(PsiAssertStatement statement) {
|
||||
final PsiExpression condition = statement.getAssertCondition();
|
||||
if (SynchronizationUtil.isCallToHoldsLock(condition)) {
|
||||
m_inSynchronizedContext = true;
|
||||
}
|
||||
super.visitAssertStatement(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethod(@NotNull PsiMethod method) {
|
||||
if (method.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
|
||||
+7
-3
@@ -3,12 +3,16 @@ package com.siyeh.igtest.threading.call_to_native_method_while_locked;
|
||||
public class CallToNativeMethodWhileLocked {
|
||||
|
||||
synchronized void a() {
|
||||
Double.<warning descr="Call to native method 'doubleToLongBits()' in a synchronized context">doubleToLongBits</warning>(9.7);
|
||||
Double.<warning descr="Call to native method 'doubleToRawLongBits()' in a synchronized context">doubleToRawLongBits</warning>(9.7);
|
||||
Runnable r = () -> {
|
||||
Double.doubleToLongBits(123.4);
|
||||
Double.doubleToRawLongBits(123.4);
|
||||
};
|
||||
new Object() {
|
||||
long l = Double.doubleToLongBits(42.0);
|
||||
long l = Double.doubleToRawLongBits(42.0);
|
||||
};
|
||||
Runnable s = () -> {
|
||||
assert Thread.holdsLock(this);
|
||||
Double.<warning descr="Call to native method 'doubleToRawLongBits()' in a synchronized context">doubleToRawLongBits</warning>(40.0);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -4,12 +4,16 @@ public class FieldAccessedSynchronizedAndUnsynchronized
|
||||
{
|
||||
private final Object m_lock = new Object();
|
||||
private Object <warning descr="Field 'm_contents' is accessed in both synchronized and unsynchronized contexts">m_contents</warning> = new Object();
|
||||
private Object <warning descr="Field 'a' is accessed in both synchronized and unsynchronized contexts">a</warning>;
|
||||
private Object b;
|
||||
|
||||
public void foo()
|
||||
{
|
||||
synchronized(m_lock)
|
||||
{
|
||||
m_contents = new Object();
|
||||
a = new Object();
|
||||
b = new Object();
|
||||
}
|
||||
getContents();
|
||||
}
|
||||
@@ -24,6 +28,17 @@ public class FieldAccessedSynchronizedAndUnsynchronized
|
||||
getContents();
|
||||
}
|
||||
|
||||
public synchronized void g() {
|
||||
Runnable r = () -> {
|
||||
System.out.println(a);
|
||||
};
|
||||
}
|
||||
|
||||
public void h() {
|
||||
assert Thread.holdsLock(m_lock);
|
||||
System.out.println(b);
|
||||
}
|
||||
|
||||
}
|
||||
class Test {
|
||||
private Object <warning descr="Field 'object' is accessed in both synchronized and unsynchronized contexts">object</warning>;
|
||||
|
||||
Reference in New Issue
Block a user