mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
optimized version of concreteMethodByName which is much faster in most cases
GitOrigin-RevId: cd49d6e8d5b38eeff1e81a7c8fec461078133d87
This commit is contained in:
committed by
intellij-monorepo-bot
parent
68b8d4365d
commit
84e41c9f76
+3
-2
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
@@ -28,7 +29,7 @@ public class AssertStatementEvaluator implements Evaluator {
|
||||
throw EvaluateExceptionUtil.NULL_STACK_FRAME;
|
||||
}
|
||||
ClassObjectReference classObjectReference = frameProxy.location().declaringType().classObject();
|
||||
Method method = ((ClassType)classObjectReference.referenceType()).concreteMethodByName("desiredAssertionStatus", "()Z");
|
||||
Method method = DebuggerUtils.findMethod(classObjectReference.referenceType(), "desiredAssertionStatus", "()Z");
|
||||
if (method != null) {
|
||||
Value res = context.getDebugProcess().invokeMethod(context, classObjectReference, method, Collections.emptyList());
|
||||
if (res instanceof BooleanValue && !((BooleanValue)res).value()) {
|
||||
|
||||
+4
-3
@@ -1,7 +1,8 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.JVMNameUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
@@ -44,9 +45,9 @@ public class BoxingEvaluator implements Evaluator{
|
||||
final ClassType wrapperClass = (ClassType)process.findClass(context, wrapperTypeName, null);
|
||||
final String methodSignature = "(" + JVMNameUtil.getPrimitiveSignature(value.type().name()) + ")L" + wrapperTypeName.replace('.', '/') + ";";
|
||||
|
||||
Method method = wrapperClass.concreteMethodByName("valueOf", methodSignature);
|
||||
Method method = DebuggerUtils.findMethod(wrapperClass, "valueOf", methodSignature);
|
||||
if (method == null) { // older JDK version
|
||||
method = wrapperClass.concreteMethodByName(JVMNameUtil.CONSTRUCTOR_NAME, methodSignature);
|
||||
method = DebuggerUtils.findMethod(wrapperClass, JVMNameUtil.CONSTRUCTOR_NAME, methodSignature);
|
||||
}
|
||||
if (method == null) {
|
||||
throw new EvaluateException("Cannot construct wrapper object for value of type " + value.type() + ": Unable to find either valueOf() or constructor method");
|
||||
|
||||
+3
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
* Class LiteralEvaluator
|
||||
@@ -7,6 +7,7 @@
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
@@ -54,7 +55,7 @@ class LiteralEvaluator implements Evaluator {
|
||||
StringReference str = DebuggerUtilsEx.mirrorOfString((String)myValue, vm, context);
|
||||
// intern starting from jdk 7
|
||||
if (Registry.is("debugger.intern.string.literals") && vm.versionHigher("1.7")) {
|
||||
Method internMethod = ((ClassType)str.referenceType()).concreteMethodByName("intern", "()Ljava/lang/String;");
|
||||
Method internMethod = DebuggerUtils.findMethod(str.referenceType(), "intern", "()Ljava/lang/String;");
|
||||
if (internMethod != null) {
|
||||
return (StringReference)context.getDebugProcess().invokeMethod(context, str, internMethod, Collections.emptyList());
|
||||
}
|
||||
|
||||
+3
-16
@@ -1,20 +1,7 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.
|
||||
*/
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -83,7 +70,7 @@ public class UnBoxingEvaluator implements Evaluator {
|
||||
return primitiveValue;
|
||||
}
|
||||
|
||||
Method method = ((ClassType)value.referenceType()).concreteMethodByName(conversionMethodName, conversionMethodSignature);
|
||||
Method method = DebuggerUtils.findMethod(value.referenceType(), conversionMethodName, conversionMethodSignature);
|
||||
if (method == null) {
|
||||
throw new EvaluateException("Cannot convert to primitive value of type " + value.type() + ": Unable to find method " +
|
||||
conversionMethodName + conversionMethodSignature);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.impl;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
@@ -31,7 +31,7 @@ public class ClassLoadingUtils {
|
||||
ArrayType arrayType = (ArrayType)context.getDebugProcess().findClass(context, "java.net.URL[]", context.getClassLoader());
|
||||
ArrayReference emptyUrlArray = DebuggerUtilsEx.mirrorOfArray(arrayType, 0, context);
|
||||
ClassType loaderClass = (ClassType)process.findClass(context, "java.net.URLClassLoader", context.getClassLoader());
|
||||
Method ctorMethod = loaderClass.concreteMethodByName(JVMNameUtil.CONSTRUCTOR_NAME, "([Ljava/net/URL;Ljava/lang/ClassLoader;)V");
|
||||
Method ctorMethod = DebuggerUtils.findMethod(loaderClass, JVMNameUtil.CONSTRUCTOR_NAME, "([Ljava/net/URL;Ljava/lang/ClassLoader;)V");
|
||||
return context.computeAndKeep(() -> (ClassLoaderReference)process
|
||||
.newInstance(context, loaderClass, ctorMethod, Arrays.asList(emptyUrlArray, context.getClassLoader())));
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public class ClassLoadingUtils {
|
||||
try {
|
||||
VirtualMachineProxyImpl proxy = (VirtualMachineProxyImpl)process.getVirtualMachineProxy();
|
||||
Method defineMethod =
|
||||
((ClassType)classLoader.referenceType()).concreteMethodByName("defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;");
|
||||
DebuggerUtils.findMethod(classLoader.referenceType(), "defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;");
|
||||
process.invokeMethod(context, classLoader, defineMethod,
|
||||
Arrays.asList(DebuggerUtilsEx.mirrorOfString(name, proxy, context),
|
||||
mirrorOf(bytes, context, process),
|
||||
|
||||
@@ -1084,18 +1084,4 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Method concreteMethodByName(@NotNull ClassType type, String name, String signature) {
|
||||
//TODO: currently does not include interface default methods
|
||||
while (type != null) {
|
||||
for (Method candidate : type.methods()) {
|
||||
if (candidate.name().equals(name) && candidate.signature().equals(signature) && !candidate.isAbstract()) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
type = type.superclass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
|
||||
@Nullable
|
||||
protected static Value invokeExceptionGetStackTrace(ObjectReference exceptionObj, EvaluationContextImpl evaluationContext)
|
||||
throws EvaluateException {
|
||||
Method method = ((ClassType)exceptionObj.referenceType()).concreteMethodByName("getStackTrace", "()[Ljava/lang/StackTraceElement;");
|
||||
Method method = DebuggerUtils.findMethod(exceptionObj.referenceType(), "getStackTrace", "()[Ljava/lang/StackTraceElement;");
|
||||
if (method != null) {
|
||||
return evaluationContext.getDebugProcess().invokeMethod(evaluationContext, exceptionObj, method, Collections.emptyList());
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.debugger.DebuggerManager;
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
import com.intellij.debugger.engine.DebugProcessListener;
|
||||
import com.intellij.debugger.engine.JVMNameUtil;
|
||||
import com.intellij.debugger.engine.SuspendContext;
|
||||
import com.intellij.debugger.engine.*;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContext;
|
||||
@@ -76,7 +73,7 @@ public class BatchEvaluator {
|
||||
}
|
||||
|
||||
if (batchEvaluatorClass != null) {
|
||||
Method constructor = batchEvaluatorClass.concreteMethodByName(JVMNameUtil.CONSTRUCTOR_NAME, "()V");
|
||||
Method constructor = DebuggerUtils.findMethod(batchEvaluatorClass, JVMNameUtil.CONSTRUCTOR_NAME, "()V");
|
||||
if(constructor != null){
|
||||
ObjectReference evaluator = null;
|
||||
try {
|
||||
@@ -88,7 +85,7 @@ public class BatchEvaluator {
|
||||
myBatchEvaluatorObject = evaluator;
|
||||
|
||||
if(myBatchEvaluatorObject != null) {
|
||||
myBatchEvaluatorMethod = batchEvaluatorClass.concreteMethodByName("evaluate", "([Ljava/lang/Object;)[Ljava/lang/Object;");
|
||||
myBatchEvaluatorMethod = DebuggerUtils.findMethod(batchEvaluatorClass, "evaluate", "([Ljava/lang/Object;)[Ljava/lang/Object;");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ class ClassObjectRenderer extends CompoundReferenceRenderer implements FullValue
|
||||
public void evaluate(@NotNull XFullValueEvaluationCallback callback) {
|
||||
Value value = valueDescriptor.getValue();
|
||||
ClassType type = ((ClassType)value.type());
|
||||
Method nameMethod = type.concreteMethodByName("getName", "()Ljava/lang/String;");
|
||||
Method nameMethod = DebuggerUtils.findMethod(type, "getName", "()Ljava/lang/String;");
|
||||
if (nameMethod != null) {
|
||||
try {
|
||||
final DebugProcessImpl process = evaluationContext.getDebugProcess();
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContext;
|
||||
@@ -33,7 +34,7 @@ class ColorObjectRenderer extends CompoundReferenceRenderer {
|
||||
ReferenceType refType = objRef.referenceType();
|
||||
if (refType instanceof ClassType) {
|
||||
Value rgbValue = null;
|
||||
Method getRGBMethod = ((ClassType)refType).concreteMethodByName("getRGB", "()I");
|
||||
Method getRGBMethod = DebuggerUtils.findMethod(refType, "getRGB", "()I");
|
||||
if (getRGBMethod != null) {
|
||||
ReferenceType rgbMethodDeclaringType = getRGBMethod.declaringType();
|
||||
if (rgbMethodDeclaringType.name().equals(getClassName())) { // getRGB is not overridden
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.FullValueEvaluatorProvider;
|
||||
import com.intellij.debugger.engine.JavaValue;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
@@ -40,7 +41,7 @@ class StackTraceElementObjectRenderer extends CompoundReferenceRenderer implemen
|
||||
public void evaluate(@NotNull XFullValueEvaluationCallback callback) {
|
||||
Value value = valueDescriptor.getValue();
|
||||
ClassType type = ((ClassType)value.type());
|
||||
Method toString = type.concreteMethodByName("toString", "()Ljava/lang/String;");
|
||||
Method toString = DebuggerUtils.findMethod(type, "toString", "()Ljava/lang/String;");
|
||||
if (toString != null) {
|
||||
try {
|
||||
Value res =
|
||||
|
||||
@@ -127,10 +127,9 @@ public class ToStringRenderer extends NodeRendererImpl implements OnDemandRender
|
||||
return overridesToString(type);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private static boolean overridesToString(Type type) {
|
||||
if (type instanceof ClassType) {
|
||||
Method toStringMethod = DebuggerUtilsEx.concreteMethodByName((ClassType)type, "toString", "()Ljava/lang/String;");
|
||||
Method toStringMethod = DebuggerUtils.findMethod((ReferenceType)type, "toString", "()Ljava/lang/String;");
|
||||
return toStringMethod != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(toStringMethod.declaringType().name());
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -162,7 +162,7 @@ public abstract class DebuggerUtils {
|
||||
Method method = null;
|
||||
if (methodSignature != null) {
|
||||
if (refType instanceof ClassType) {
|
||||
method = ((ClassType)refType).concreteMethodByName(methodName, methodSignature);
|
||||
method = concreteMethodByName((ClassType)refType, methodName, methodSignature);
|
||||
}
|
||||
if (method == null) {
|
||||
method = ContainerUtil.getFirstItem(refType.methodsByName(methodName, methodSignature));
|
||||
@@ -174,6 +174,39 @@ public abstract class DebuggerUtils {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized version of {@link com.sun.jdi.ClassType#concreteMethodByName(java.lang.String, java.lang.String)}.
|
||||
* It does not gather all visible methods before checking so can return early
|
||||
*/
|
||||
@Nullable
|
||||
private static Method concreteMethodByName(@NotNull ClassType type, @NotNull String name, @NotNull String signature) {
|
||||
LinkedList<InterfaceType> interfaces = new LinkedList<>();
|
||||
// first check classes
|
||||
while (type != null) {
|
||||
for (Method candidate : type.methods()) {
|
||||
if (candidate.name().equals(name) && candidate.signature().equals(signature)) {
|
||||
return !candidate.isAbstract() ? candidate : null;
|
||||
}
|
||||
}
|
||||
interfaces.addAll(type.interfaces());
|
||||
type = type.superclass();
|
||||
}
|
||||
// then interfaces
|
||||
Set<InterfaceType> checkedInterfaces = new HashSet<>();
|
||||
InterfaceType iface;
|
||||
while ((iface = interfaces.poll()) != null) {
|
||||
if (checkedInterfaces.add(iface)) {
|
||||
for (Method candidate : iface.methods()) {
|
||||
if (candidate.name().equals(name) && candidate.signature().equals(signature) && !candidate.isAbstract()) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
interfaces.addAll(0, iface.superinterfaces());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isNumeric(Value value) {
|
||||
return value != null &&
|
||||
(isInteger(value) ||
|
||||
|
||||
Reference in New Issue
Block a user