diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java index c5eb7951615e..7b4a6f97c812 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BoxingEvaluator.java @@ -24,7 +24,6 @@ import com.intellij.psi.impl.PsiJavaParserFacadeImpl; import com.sun.jdi.*; import java.util.Collections; -import java.util.List; /** * @author Eugene Zhuravlev @@ -59,14 +58,14 @@ 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('.', '/') + ";"; - List methods = wrapperClass.methodsByName("valueOf", methodSignature); - if (methods.size() == 0) { // older JDK version - methods = wrapperClass.methodsByName(JVMNameUtil.CONSTRUCTOR_NAME, methodSignature); + Method method = wrapperClass.concreteMethodByName("valueOf", methodSignature); + if (method == null) { // older JDK version + method = wrapperClass.concreteMethodByName(JVMNameUtil.CONSTRUCTOR_NAME, methodSignature); } - if (methods.size() == 0) { + if (method == null) { throw new EvaluateException("Cannot construct wrapper object for value of type " + value.type() + ": Unable to find either valueOf() or constructor method"); } - return process.invokeMethod(context, wrapperClass, methods.get(0), Collections.singletonList(value)); + return process.invokeMethod(context, wrapperClass, method, Collections.singletonList(value)); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java index 1d949dd7bbca..218202733794 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LiteralEvaluator.java @@ -26,6 +26,11 @@ import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.sun.jdi.ClassType; +import com.sun.jdi.Method; +import com.sun.jdi.StringReference; + +import java.util.Collections; class LiteralEvaluator implements Evaluator { private final Object myValue; @@ -57,7 +62,13 @@ class LiteralEvaluator implements Evaluator { return DebuggerUtilsEx.createValue(vm, myExpectedType, ((Number)myValue).longValue()); } if (myValue instanceof String) { - return vm.mirrorOf((String)myValue); + StringReference str = vm.mirrorOf((String)myValue); + // intern + Method internMethod = ((ClassType)str.referenceType()).concreteMethodByName("intern", "()Ljava/lang/String;"); + if (internMethod != null) { + return context.getDebugProcess().invokeMethod(context, str, internMethod, Collections.emptyList()); + } + return str; } throw EvaluateExceptionUtil .createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", myExpectedType)); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java index 1fc91c33179c..7dce81bf675c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java @@ -29,7 +29,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; -import java.util.List; import java.util.Map; /** @@ -80,12 +79,12 @@ public class UnBoxingEvaluator implements Evaluator{ String conversionMethodSignature) throws EvaluateException { final DebugProcessImpl process = context.getDebugProcess(); final ClassType wrapperClass = (ClassType)value.referenceType(); - final List methods = wrapperClass.methodsByName(conversionMethodName, conversionMethodSignature); - if (methods.size() == 0) { + Method method = wrapperClass.concreteMethodByName(conversionMethodName, conversionMethodSignature); + if (method == null) { throw new EvaluateException("Cannot convert to primitive value of type " + value.type() + ": Unable to find method " + conversionMethodName + conversionMethodSignature); } - return process.invokeMethod(context, value, methods.get(0), Collections.emptyList()); + return process.invokeMethod(context, value, method, Collections.emptyList()); } } \ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java b/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java index f4933f23a717..f8b06bfd24bc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java @@ -16,6 +16,7 @@ package com.intellij.debugger.jdi; import com.intellij.Patches; +import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.jdi.VirtualMachineProxy; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.openapi.util.Ref; @@ -23,7 +24,6 @@ import com.intellij.util.ReflectionUtil; import com.intellij.util.ThrowableConsumer; import com.intellij.util.containers.ContainerUtil; import com.sun.jdi.*; -import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.org.objectweb.asm.*; @@ -242,9 +242,12 @@ public class MethodBytecodeUtil { visit(applicableMethods.get(0), new MethodVisitor(Opcodes.API_VERSION) { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - ReferenceType cls = ContainerUtil.getFirstItem(vm.classesByName(owner)); + ReferenceType cls = ContainerUtil.getFirstItem(vm.classesByName(owner.replace("/", "."))); if (cls != null) { - cls.methodsByName(name, desc).stream().findFirst().ifPresent(methodRef::set); + Method method = DebuggerUtils.findMethod(cls, name, desc); + if (method != null) { + methodRef.setIfNull(method); + } } } }, false); @@ -262,14 +265,18 @@ public class MethodBytecodeUtil { public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { ReferenceType declaringType = method.declaringType(); ReferenceType cls = null; - if (declaringType.name().equals(owner.replace("/", "."))) { + owner = owner.replace("/", "."); + if (declaringType.name().equals(owner)) { cls = declaringType; } - else if (!"java/lang/AbstractMethodError".equals(owner)) { + else if (!"java.lang.AbstractMethodError".equals(owner)) { cls = ContainerUtil.getFirstItem(vm.classesByName(owner)); } if (cls != null) { - StreamEx.of(cls.methodsByName(name, desc)).findFirst().ifPresent(methodRef::set); + Method method = DebuggerUtils.findMethod(cls, name, desc); + if (method != null) { + methodRef.setIfNull(method); + } } } }, false); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java index 98158cdbb9f0..874c0f7a4bdd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -47,7 +47,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Collections; -import java.util.List; import java.util.Map; public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements ValueDescriptor{ @@ -235,11 +234,11 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements final ObjectReference exceptionObj = ex.getExceptionFromTargetVM(); if (exceptionObj != null && evaluationContext != null) { try { - final ReferenceType refType = exceptionObj.referenceType(); - final List methods = refType.methodsByName("getStackTrace", "()[Ljava/lang/StackTraceElement;"); - if (methods.size() > 0) { + ClassType refType = (ClassType)exceptionObj.referenceType(); + Method method = refType.concreteMethodByName("getStackTrace", "()[Ljava/lang/StackTraceElement;"); + if (method != null) { final DebugProcessImpl process = evaluationContext.getDebugProcess(); - process.invokeMethod(evaluationContext, exceptionObj, methods.get(0), Collections.emptyList()); + process.invokeMethod(evaluationContext, exceptionObj, method, Collections.emptyList()); // print to console as well @@ -260,9 +259,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements } } } - catch (EvaluateException ignored) { - } - catch (ClassNotLoadedException ignored) { + catch (EvaluateException | ClassNotLoadedException ignored) { } catch (Throwable e) { LOG.info(e); // catch all exceptions to ensure the method returns gracefully diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java index 2864c656b6e8..609154b28440 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java @@ -133,8 +133,8 @@ public class ToStringRenderer extends NodeRendererImpl { @SuppressWarnings({"HardCodedStringLiteral"}) private static boolean overridesToString(Type type) { if (type instanceof ClassType) { - return ((ClassType)type).methodsByName("toString", "()Ljava/lang/String;").stream() - .anyMatch(method -> !CommonClassNames.JAVA_LANG_OBJECT.equals(method.declaringType().name())); + return !CommonClassNames.JAVA_LANG_OBJECT + .equals(((ClassType)type).concreteMethodByName("toString", "()Ljava/lang/String;").declaringType().name()); } return false; } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryImpl.java b/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryImpl.java index e6b27c265831..b1143a77086f 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryImpl.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -13,12 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.history.integration; import com.intellij.history.*; import com.intellij.history.core.*; -import com.intellij.history.core.tree.RootEntry; import com.intellij.history.integration.ui.models.DirectoryHistoryDialogModel; import com.intellij.history.integration.ui.models.EntireFileHistoryDialogModel; import com.intellij.history.integration.ui.models.HistoryDialogModel; @@ -26,11 +24,10 @@ import com.intellij.history.utils.LocalHistoryLog; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Clock; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.ShutDownTracker; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; @@ -39,7 +36,6 @@ import com.intellij.openapi.vfs.VirtualFileListener; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; @@ -104,24 +100,6 @@ public class LocalHistoryImpl extends LocalHistory implements ApplicationCompone VirtualFileManager fm = VirtualFileManager.getInstance(); fm.addVirtualFileManagerListener(myEventDispatcher); - - if (ApplicationManager.getApplication().isInternal() && !ApplicationManager.getApplication().isUnitTestMode()) { - ApplicationManager.getApplication().executeOnPooledThread(() -> validateStorage()); - } - } - - private void validateStorage() { - if (ApplicationManager.getApplication().isInternal() && !ApplicationManager.getApplication().isUnitTestMode()) { - LocalHistoryLog.LOG.info("Checking local history storage..."); - try { - long before = Clock.getTime(); - myVcs.getChangeListInTests().getChangesInTests(); - LocalHistoryLog.LOG.info("Local history storage seems to be ok (took " + ((Clock.getTime() - before) / 1000) + " sec)"); - } - catch (Exception e) { - LocalHistoryLog.LOG.error(e); - } - } } public File getStorageDir() { @@ -144,12 +122,8 @@ public class LocalHistoryImpl extends LocalHistory implements ApplicationCompone fm.removeVirtualFileManagerListener(myEventDispatcher); CommandProcessor.getInstance().removeCommandListener(myEventDispatcher); - - validateStorage(); LocalHistoryLog.LOG.debug("Purging local history..."); myChangeList.purgeObsolete(period); - validateStorage(); - myChangeList.close(); LocalHistoryLog.LOG.debug("Local history storage successfully closed."); @@ -179,7 +153,7 @@ public class LocalHistoryImpl extends LocalHistory implements ApplicationCompone return label(myVcs.putUserLabel(name, getProjectId(p))); } - private String getProjectId(Project p) { + private static String getProjectId(Project p) { return p.getLocationHash(); } @@ -203,13 +177,7 @@ public class LocalHistoryImpl extends LocalHistory implements ApplicationCompone @Override public ByteContent getByteContent(final String path) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public ByteContent compute() { - RootEntry root = myGateway.createTransientRootEntryForPathOnly(path); - return impl.getByteContent(root, path); - } - }); + return ReadAction.compute(() -> impl.getByteContent(myGateway.createTransientRootEntryForPathOnly(path), path)); } }; } @@ -219,12 +187,7 @@ public class LocalHistoryImpl extends LocalHistory implements ApplicationCompone public byte[] getByteContent(final VirtualFile f, final FileRevisionTimestampComparator c) { if (!isInitialized()) return null; if (!myGateway.areContentChangesVersioned(f)) return null; - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public byte[] compute() { - return new ByteContentRetriever(myGateway, myVcs, f, c).getResult(); - } - }); + return ReadAction.compute(() -> new ByteContentRetriever(myGateway, myVcs, f, c).getResult()); } @Override @@ -237,7 +200,6 @@ public class LocalHistoryImpl extends LocalHistory implements ApplicationCompone } @Override - @NonNls @NotNull public String getComponentName() { return "Local History"; @@ -270,4 +232,4 @@ public class LocalHistoryImpl extends LocalHistory implements ApplicationCompone throw new LocalHistoryException(String.format("Couldn't revert %s to local history label.", f.getName()), e); } } -} +} \ No newline at end of file diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ValidateHistoryAction.kt b/platform/lvcs-impl/src/com/intellij/history/integration/ValidateHistoryAction.kt new file mode 100644 index 000000000000..53bd0343486b --- /dev/null +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ValidateHistoryAction.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2016 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.history.integration + +import com.intellij.history.core.changes.ChangeSet +import com.intellij.history.core.changes.ChangeVisitor +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.progress.ProcessCanceledException +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.progress.Task +import com.intellij.openapi.ui.Messages +import com.intellij.util.ExceptionUtil + +class ValidateHistoryAction : AnAction() { + override fun update(e: AnActionEvent) { + e.presentation.isEnabledAndVisible = ApplicationManager.getApplication().isInternal + } + + override fun actionPerformed(e: AnActionEvent) { + object : Task.Modal(e.project, "Checking local history storage", true) { + override fun run(indicator: ProgressIndicator) { + val t = System.currentTimeMillis() + + try { + LocalHistoryImpl.getInstanceImpl().facade?.accept(object : ChangeVisitor() { + private var count = 0 + + override fun end(c: ChangeSet) { + indicator.checkCanceled() + if (++count % 10 == 0) { + indicator.text = "${count} records checked" + } + } + + override fun finished() { + val message = "Local history storage seems to be OK (checked ${count} records in ${System.currentTimeMillis() - t} ms)" + ApplicationManager.getApplication().invokeLater { Messages.showInfoMessage(e.project, message, "Local History Validation") } + } + }) + } + catch(ex: ProcessCanceledException) { throw ex } + catch(ex: Exception) { + Messages.showErrorDialog(e.project, ExceptionUtil.getThrowableText(ex), "Local History Validation Error") + } + } + }.queue() + } +} \ No newline at end of file diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml index 3a9085738066..09b1b710554f 100644 --- a/resources/src/idea/RichPlatformActions.xml +++ b/resources/src/idea/RichPlatformActions.xml @@ -152,6 +152,8 @@ + +