correct field names/modifiers in reflection access

This commit is contained in:
Alexey Kudravtsev
2015-06-08 14:23:39 +03:00
parent 4b79683e7c
commit 7fe4fdf62f
9 changed files with 65 additions and 111 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 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.
@@ -101,7 +101,7 @@ public class ColorUtil {
PsiField psiField = (PsiField)psiElement;
final PsiClass psiClass = psiField.getContainingClass();
if (psiClass != null && "java.awt.Color".equals(psiClass.getQualifiedName())) {
Color c = ReflectionUtil.getField(Color.class, null, Color.class, psiField.getName());
Color c = ReflectionUtil.getStaticFieldValue(Color.class, Color.class, psiField.getName());
if (c != null) {
buffer.append(generatePreviewHtml(c));
}
@@ -207,7 +207,7 @@ public class CharTableImpl implements CharTable {
for (Field field : aClass.getDeclaredFields()) {
if ((field.getModifiers() & Modifier.STATIC) == 0) continue;
if ((field.getModifiers() & Modifier.PUBLIC) == 0) continue;
String typeName = ReflectionUtil.getField(aClass, null, String.class, field.getName());
String typeName = ReflectionUtil.getStaticFieldValue(aClass, String.class, field.getName());
if (typeName != null) {
staticIntern(typeName);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 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.
@@ -94,7 +94,7 @@ public final class SwingCleanuper implements ApplicationComponent{
public void run() {
// KeyboardFocusManager.newFocusOwner
resetStaticField(KeyboardFocusManager.class, "newFocusOwner");
ReflectionUtil.resetStaticField(KeyboardFocusManager.class, "newFocusOwner");
// Clear "realOppositeComponent", "realOppositeWindow"
final KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
@@ -105,8 +105,8 @@ public final class SwingCleanuper implements ApplicationComponent{
// Memory leak on static field in BasicPopupMenuUI
try {
final Object helperObject = ReflectionUtil.getField(BasicPopupMenuUI.class, null, Object.class, "menuKeyboardHelper");
if (null != helperObject) {
Object helperObject = ReflectionUtil.getStaticFieldValue(BasicPopupMenuUI.class, Object.class, "menuKeyboardHelper");
if (helperObject != null) {
resetField(helperObject, Component.class, "lastFocused");
}
}
@@ -117,11 +117,10 @@ public final class SwingCleanuper implements ApplicationComponent{
// Memory leak on javax.swing.TransferHandler$SwingDragGestureRecognizer.component
try{
final Object recognizerObject = ReflectionUtil.getField(TransferHandler.class, null, null, "recognizer");
DragGestureRecognizer recognizer = ReflectionUtil.getStaticFieldValue(TransferHandler.class, DragGestureRecognizer.class, "recognizer");
if(recognizerObject!=null){ // that is memory leak
final Method setComponentMethod = DragGestureRecognizer.class.getDeclaredMethod("setComponent", Component.class);
setComponentMethod.invoke(recognizerObject,new Object[]{null});
if (recognizer != null) { // that is memory leak
recognizer.setComponent(null);
}
}
catch (Exception e){
@@ -144,9 +143,9 @@ public final class SwingCleanuper implements ApplicationComponent{
// Ignore
}
resetStaticField(KeyboardFocusManager.class, "newFocusOwner");
resetStaticField(KeyboardFocusManager.class, "permanentFocusOwner");
resetStaticField(KeyboardFocusManager.class, "currentFocusCycleRoot");
ReflectionUtil.resetStaticField(KeyboardFocusManager.class, "newFocusOwner");
ReflectionUtil.resetStaticField(KeyboardFocusManager.class, "permanentFocusOwner");
ReflectionUtil.resetStaticField(KeyboardFocusManager.class, "currentFocusCycleRoot");
}
}
);
@@ -248,9 +247,6 @@ public final class SwingCleanuper implements ApplicationComponent{
// Ignore
}
}
private static void resetStaticField(@NotNull Class aClass, @NotNull @NonNls String name) {
ReflectionUtil.resetField(aClass, null, name);
}
public final void disposeComponent(){}
@@ -262,7 +258,7 @@ public final class SwingCleanuper implements ApplicationComponent{
public final void initComponent() { }
private static void fixJTextComponentMemoryLeak() {
final JTextComponent component = ReflectionUtil.getField(JTextComponent.class, null, JTextComponent.class, "focusedComponent");
final JTextComponent component = ReflectionUtil.getStaticFieldValue(JTextComponent.class, JTextComponent.class, "focusedComponent");
if (component != null && !component.isDisplayable()){
ReflectionUtil.resetField(JTextComponent.class, JTextComponent.class, "focusedComponent");
}
@@ -19,7 +19,6 @@ import com.intellij.ide.DataManager;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.impl.TypeSafeDataProviderAdapter;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
@@ -38,7 +37,9 @@ import com.intellij.openapi.ui.Queryable;
import com.intellij.openapi.ui.popup.StackingPopupDispatcher;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
@@ -276,8 +277,6 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
runnable.run();
}
myDisposeActions.clear();
final JRootPane root = myDialog.getRootPane();
Runnable disposer = new Runnable() {
@Override
public void run() {
@@ -287,20 +286,15 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (myDialog != null && root != null) {
myDialog.remove(root);
if (myDialog != null && myDialog.getRootPane() != null) {
myDialog.remove(myDialog.getRootPane());
}
}
});
}
};
if (EventQueue.isDispatchThread()) {
disposer.run();
}
else {
SwingUtilities.invokeLater(disposer);
}
UIUtil.invokeLaterIfNeeded(disposer);
}
private boolean isProgressDialog() {
@@ -867,12 +861,12 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
if (rootPane != null) { // Workaround for bug in native code to hold rootPane
try {
ReflectionUtil.resetField(rootPane.getClass(), null, "glassPane");
ReflectionUtil.resetField(rootPane.getClass(), null, "contentPane");
ReflectionUtil.resetField(rootPane, "glassPane");
ReflectionUtil.resetField(rootPane, "contentPane");
rootPane = null;
ReflectionUtil.resetField(Window.class, null, "windowListener");
ReflectionUtil.resetField(this, "windowListener");
}
catch (Exception ignored) {
}
@@ -880,8 +874,10 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
// http://bugs.sun.com/view_bug.do?bug_id=6614056
try {
final List<?> list = ReflectionUtil.getField(Dialog.class, null, null, "modalDialogs");
list.remove(this);
synchronized (getTreeLock()) {
List<?> list = ReflectionUtil.getStaticFieldValue(Dialog.class, List.class, "modalDialogs");
list.remove(this);
}
}
catch (final Exception ignored) {
}
@@ -1083,71 +1079,6 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
return wrapper != null && PlatformDataKeys.UI_DISPOSABLE.is(dataId) ? wrapper.getDisposable() : null;
}
}
private class MyFocusCommand extends FocusCommand implements KeyEventProcessor {
private Context myContextOnFinish;
private final List<KeyEvent> myEvents = new ArrayList<KeyEvent>();
private final DialogWrapper myWrapper;
private MyFocusCommand(DialogWrapper wrapper) {
myWrapper = getDialogWrapper();
setToInvalidateRequestors(false);
Disposer.register(wrapper.getDisposable(), new Disposable() {
@Override
public void dispose() {
if (!myTypeAheadDone.isProcessed()) {
myTypeAheadDone.setDone();
}
flushEvents();
}
});
}
@Override
@NotNull
public ActionCallback run() {
return myTypeAheadDone;
}
@Override
public KeyEventProcessor getProcessor() {
return this;
}
@Override
public Boolean dispatch(@NotNull KeyEvent e, @NotNull Context context) {
if (myWrapper == null || myTypeAheadDone.isProcessed()) return null;
myEvents.addAll(context.getQueue());
context.getQueue().clear();
if (isToDispatchToDialogNow(e)) {
return false;
} else {
myEvents.add(e);
return true;
}
}
private boolean isToDispatchToDialogNow(KeyEvent e) {
return e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_ESCAPE || e.getKeyCode() == KeyEvent.VK_TAB;
}
@Override
public void finish(@NotNull Context context) {
myContextOnFinish = context;
}
private void flushEvents() {
if (myWrapper.isToDispatchTypeAhead() && myContextOnFinish != null) {
myContextOnFinish.dispatch(myEvents);
}
}
}
}
private static void setupSelectionOnPreferredComponent(final JComponent component) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 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.
@@ -73,7 +73,7 @@ public class KeyStrokeMap {
}
if (symbol.length() > 1) {
final Integer code = (Integer)ReflectionUtil.getField(KeyEvent.class, null, int.class, "VK_" + StringUtil.toUpperCase(symbol));
final Integer code = ReflectionUtil.getStaticFieldValue(KeyEvent.class, int.class, "VK_" + StringUtil.toUpperCase(symbol));
if (code == null) {
return throwUnrecognized(symbol);
}
@@ -186,7 +186,7 @@ public abstract class UsefulTestCase extends TestCase {
catch (Exception e) {
throw new RuntimeException(e);
}
Set<String> files = ReflectionUtil.getField(aClass, null, Set.class, "files");
Set<String> files = ReflectionUtil.getStaticFieldValue(aClass, Set.class, "files");
DELETE_ON_EXIT_HOOK_CLASS = aClass;
DELETE_ON_EXIT_HOOK_DOT_FILES = files;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 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.
@@ -20,7 +20,7 @@ import com.intellij.Patches;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.DifferenceFilter;
import com.intellij.util.containers.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -211,6 +211,7 @@ public class ReflectionUtil {
LOG.info(e);
}
}
public static void resetField(@NotNull Object object, @Nullable("null means any type") Class type, @NotNull String name) {
try {
resetField(object, findField(object.getClass(), type, name));
@@ -256,6 +257,10 @@ public class ReflectionUtil {
}
}
public static void resetStaticField(@NotNull Class aClass, @NotNull @NonNls String name) {
resetField(aClass, null, name);
}
@Nullable
public static Method findMethod(@NotNull Collection<Method> methods, @NonNls @NotNull String name, @NotNull Class... parameters) {
for (final Method method : methods) {
@@ -332,7 +337,7 @@ public class ReflectionUtil {
return method == null ? null : method.getDeclaringClass();
}
public static <T> T getField(@NotNull Class objectClass, Object object, @Nullable("null means any type") Class<T> fieldType, @NotNull @NonNls String fieldName) {
public static <T> T getField(@NotNull Class objectClass, @Nullable Object object, @Nullable("null means any type") Class<T> fieldType, @NotNull @NonNls String fieldName) {
try {
final Field field = findAssignableField(objectClass, fieldType, fieldName);
return (T)field.get(object);
@@ -347,8 +352,30 @@ public class ReflectionUtil {
}
}
public static <T> T getStaticFieldValue(@NotNull Class objectClass, @Nullable("null means any type") Class<T> fieldType, @NotNull @NonNls String fieldName) {
try {
final Field field = findAssignableField(objectClass, fieldType, fieldName);
if (!Modifier.isStatic(field.getModifiers())) {
throw new IllegalArgumentException("Field " + objectClass + "." + fieldName + " is not static");
}
return (T)field.get(null);
}
catch (NoSuchFieldException e) {
LOG.debug(e);
return null;
}
catch (IllegalAccessException e) {
LOG.debug(e);
return null;
}
}
// returns true if value was set
public static <T> boolean setField(@NotNull Class objectClass, Object object, @Nullable("null means any type") Class<T> fieldType, @NotNull @NonNls String fieldName, T value) {
public static <T> boolean setField(@NotNull Class objectClass,
Object object,
@Nullable("null means any type") Class<T> fieldType,
@NotNull @NonNls String fieldName,
T value) {
try {
final Field field = findAssignableField(objectClass, fieldType, fieldName);
field.set(object, value);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 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.
@@ -39,7 +39,7 @@ public class AtomicFieldUpdater<T,V> {
@NotNull
public static Unsafe getUnsafe() {
Unsafe unsafe = ReflectionUtil.getField(Unsafe.class, null, Unsafe.class, "theUnsafe");
Unsafe unsafe = ReflectionUtil.getStaticFieldValue(Unsafe.class, Unsafe.class, "theUnsafe");
if (unsafe == null) {
throw new RuntimeException("Could not find 'theUnsafe' field in the " + Unsafe.class);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 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.
@@ -63,6 +63,6 @@ public class MavenLeakDetector {
// we can ignore this one
return Collections.emptyMap();
}
return ReflectionUtil.getField(clazz, null, Map.class, "hooks");
return ReflectionUtil.getStaticFieldValue(clazz, Map.class, "hooks");
}
}