mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
IJ-CR-108265 [java-decompiler] IDEA-198397 add cancelled checks for java-decompiler. Refresh api
GitOrigin-RevId: 0edb31b19b393df6981c3785d2a7368226c70114
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d795671583
commit
59b359c191
@@ -8,24 +8,18 @@ import org.jetbrains.annotations.NotNull;
|
||||
public interface CancellationManager {
|
||||
/**
|
||||
* @throws CanceledException if the process has been canceled.
|
||||
* @throws TimeExceedException if limit timeout is exceeded.
|
||||
*/
|
||||
void checkCanceled() throws CanceledException, TimeExceedException;
|
||||
void checkCanceled() throws CanceledException;
|
||||
|
||||
/**
|
||||
* @param sec - limit timeout (seconds)
|
||||
* Called every time the body of a new method is started to be decompiled
|
||||
*/
|
||||
void setMaxSec(int sec);
|
||||
void startMethod(String className, String methodName);
|
||||
|
||||
/**
|
||||
* Call to start counting down the timeout
|
||||
* Called every time the method decompilation is finished
|
||||
*/
|
||||
void startMethod();
|
||||
|
||||
/**
|
||||
* Call to reset timer
|
||||
*/
|
||||
void finishMethod();
|
||||
void finishMethod(String className, String methodName);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
class CanceledException extends RuntimeException {
|
||||
@@ -33,22 +27,30 @@ public interface CancellationManager {
|
||||
public CanceledException(@NotNull Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public CanceledException() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
class TimeExceedException extends RuntimeException {
|
||||
class TimeExceedException extends CanceledException {
|
||||
}
|
||||
|
||||
static CancellationManager getSimpleWithTimeout() {
|
||||
return new SimpleWithTimeoutCancellationManager();
|
||||
static CancellationManager getSimpleWithTimeout(int maxMethodTimeoutSec) {
|
||||
return new TimeoutCancellationManager(maxMethodTimeoutSec);
|
||||
}
|
||||
|
||||
class SimpleWithTimeoutCancellationManager implements CancellationManager {
|
||||
private long maxMilis = 0;
|
||||
class TimeoutCancellationManager implements CancellationManager {
|
||||
private final long maxMilis;
|
||||
private long startMilis = 0;
|
||||
|
||||
protected TimeoutCancellationManager(int maxMethodTimeoutSec) {
|
||||
this.maxMilis = maxMethodTimeoutSec * 1000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCanceled() throws CanceledException, TimeExceedException {
|
||||
public void checkCanceled() throws CanceledException {
|
||||
if (maxMilis <= 0 || startMilis <= 0) {
|
||||
return;
|
||||
}
|
||||
@@ -59,17 +61,12 @@ public interface CancellationManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxSec(int sec) {
|
||||
maxMilis = sec * 1_000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMethod() {
|
||||
public void startMethod(String className, String methodName) {
|
||||
startMilis = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishMethod() {
|
||||
public void finishMethod(String className, String methodName) {
|
||||
startMilis = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +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.
|
||||
package org.jetbrains.java.decompiler.main;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.java.decompiler.main.collectors.BytecodeSourceMapper;
|
||||
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
|
||||
import org.jetbrains.java.decompiler.main.collectors.ImportCollector;
|
||||
@@ -19,36 +21,46 @@ public class DecompilerContext {
|
||||
public static final String CURRENT_CLASS_NODE = "CURRENT_CLASS_NODE";
|
||||
public static final String CURRENT_METHOD_WRAPPER = "CURRENT_METHOD_WRAPPER";
|
||||
|
||||
@NotNull
|
||||
private final Map<String, Object> properties;
|
||||
@NotNull
|
||||
private final IFernflowerLogger logger;
|
||||
@NotNull
|
||||
private final StructContext structContext;
|
||||
@NotNull
|
||||
private final ClassesProcessor classProcessor;
|
||||
@Nullable
|
||||
private final PoolInterceptor poolInterceptor;
|
||||
@NotNull
|
||||
private final CancellationManager cancellationManager;
|
||||
private ImportCollector importCollector;
|
||||
private VarProcessor varProcessor;
|
||||
private CounterContainer counterContainer;
|
||||
private BytecodeSourceMapper bytecodeSourceMapper;
|
||||
|
||||
public DecompilerContext(Map<String, Object> properties,
|
||||
IFernflowerLogger logger,
|
||||
StructContext structContext,
|
||||
ClassesProcessor classProcessor,
|
||||
PoolInterceptor interceptor) {
|
||||
this(properties, logger, structContext, classProcessor, interceptor, CancellationManager.getSimpleWithTimeout());
|
||||
public DecompilerContext(@NotNull Map<String, Object> properties,
|
||||
@NotNull IFernflowerLogger logger,
|
||||
@NotNull StructContext structContext,
|
||||
@NotNull ClassesProcessor classProcessor,
|
||||
@Nullable PoolInterceptor interceptor) {
|
||||
this(properties, logger, structContext, classProcessor, interceptor, null);
|
||||
}
|
||||
|
||||
public DecompilerContext(Map<String, Object> properties,
|
||||
IFernflowerLogger logger,
|
||||
StructContext structContext,
|
||||
ClassesProcessor classProcessor,
|
||||
PoolInterceptor interceptor,
|
||||
CancellationManager cancellationManager) {
|
||||
public DecompilerContext(@NotNull Map<String, Object> properties,
|
||||
@NotNull IFernflowerLogger logger,
|
||||
@NotNull StructContext structContext,
|
||||
@NotNull ClassesProcessor classProcessor,
|
||||
@Nullable PoolInterceptor interceptor,
|
||||
@Nullable CancellationManager cancellationManager) {
|
||||
Objects.requireNonNull(properties);
|
||||
Objects.requireNonNull(logger);
|
||||
Objects.requireNonNull(structContext);
|
||||
Objects.requireNonNull(classProcessor);
|
||||
Objects.requireNonNull(cancellationManager);
|
||||
if (cancellationManager == null) {
|
||||
Object object = properties.get(IFernflowerPreferences.MAX_PROCESSING_METHOD);
|
||||
object = object == null ? "0" : object;
|
||||
cancellationManager = CancellationManager.getSimpleWithTimeout(Integer.parseInt(object.toString()));
|
||||
}
|
||||
|
||||
this.properties = properties;
|
||||
this.logger = logger;
|
||||
@@ -118,16 +130,9 @@ public class DecompilerContext {
|
||||
public static ClassesProcessor getClassProcessor() {
|
||||
return getCurrentContext().classProcessor;
|
||||
}
|
||||
public static CancellationManager getCancellationManager() {
|
||||
DecompilerContext context = getCurrentContext();
|
||||
if (context != null) {
|
||||
return context.cancellationManager;
|
||||
}
|
||||
|
||||
CancellationManager simpleWithTimeout = CancellationManager.getSimpleWithTimeout();
|
||||
int maxSec = Integer.parseInt(getProperty(IFernflowerPreferences.MAX_PROCESSING_METHOD).toString());
|
||||
simpleWithTimeout.setMaxSec(maxSec);
|
||||
return simpleWithTimeout;
|
||||
public static CancellationManager getCancellationManager() {
|
||||
return getCurrentContext().cancellationManager;
|
||||
}
|
||||
|
||||
public static PoolInterceptor getPoolInterceptor() {
|
||||
|
||||
@@ -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.
|
||||
package org.jetbrains.java.decompiler.main;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
|
||||
import org.jetbrains.java.decompiler.main.extern.*;
|
||||
import org.jetbrains.java.decompiler.modules.renamer.ConverterHelper;
|
||||
@@ -25,12 +26,9 @@ public class Fernflower implements IDecompiledData {
|
||||
|
||||
public Fernflower(IBytecodeProvider provider,
|
||||
IResultSaver saver,
|
||||
Map<String, Object> customProperties,
|
||||
@Nullable Map<String, Object> customProperties,
|
||||
IFernflowerLogger logger,
|
||||
CancellationManager cancellationManager) {
|
||||
if (cancellationManager == null) {
|
||||
cancellationManager = CancellationManager.getSimpleWithTimeout();
|
||||
}
|
||||
@Nullable CancellationManager cancellationManager) {
|
||||
Map<String, Object> properties = new HashMap<>(IFernflowerPreferences.DEFAULTS);
|
||||
if (customProperties != null) {
|
||||
properties.putAll(customProperties);
|
||||
@@ -63,7 +61,7 @@ public class Fernflower implements IDecompiledData {
|
||||
}
|
||||
|
||||
public Fernflower(IBytecodeProvider provider, IResultSaver saver, Map<String, Object> customProperties, IFernflowerLogger logger) {
|
||||
this(provider, saver, customProperties, logger, CancellationManager.getSimpleWithTimeout());
|
||||
this(provider, saver, customProperties, logger, null);
|
||||
}
|
||||
|
||||
private static IIdentifierRenamer loadHelper(String className, IFernflowerLogger logger) {
|
||||
|
||||
@@ -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.
|
||||
package org.jetbrains.java.decompiler.main.decompiler;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.java.decompiler.main.CancellationManager;
|
||||
import org.jetbrains.java.decompiler.main.Fernflower;
|
||||
import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider;
|
||||
@@ -14,12 +15,12 @@ import java.util.Map;
|
||||
public class BaseDecompiler {
|
||||
private final Fernflower engine;
|
||||
|
||||
public BaseDecompiler(IBytecodeProvider provider, IResultSaver saver, Map<String, Object> options, IFernflowerLogger logger) {
|
||||
this(provider, saver, options, logger, CancellationManager.getSimpleWithTimeout());
|
||||
public BaseDecompiler(IBytecodeProvider provider, IResultSaver saver, @Nullable Map<String, Object> options, IFernflowerLogger logger) {
|
||||
this(provider, saver, options, logger, null);
|
||||
}
|
||||
|
||||
public BaseDecompiler(IBytecodeProvider provider, IResultSaver saver, Map<String, Object> options, IFernflowerLogger logger,
|
||||
CancellationManager cancellationManager) {
|
||||
public BaseDecompiler(IBytecodeProvider provider, IResultSaver saver, @Nullable Map<String, Object> options, IFernflowerLogger logger,
|
||||
@Nullable CancellationManager cancellationManager) {
|
||||
engine = new Fernflower(provider, saver, options, logger, cancellationManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.java.decompiler.main.rels;
|
||||
|
||||
import org.jetbrains.java.decompiler.code.CodeConstants;
|
||||
@@ -42,15 +42,8 @@ public class ClassWrapper {
|
||||
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_WRAPPER, this);
|
||||
DecompilerContext.getLogger().startClass(classStruct.qualifiedName);
|
||||
|
||||
int maxSec = Integer.parseInt(DecompilerContext.getProperty(IFernflowerPreferences.MAX_PROCESSING_METHOD).toString());
|
||||
boolean testMode = DecompilerContext.getOption(IFernflowerPreferences.UNIT_TEST_MODE);
|
||||
CancellationManager cancellationManager = DecompilerContext.getCancellationManager();
|
||||
if (testMode) {
|
||||
cancellationManager.setMaxSec(0);
|
||||
}
|
||||
else {
|
||||
cancellationManager.setMaxSec(maxSec);
|
||||
}
|
||||
for (StructMethod mt : classStruct.getMethods()) {
|
||||
cancellationManager.checkCanceled();
|
||||
DecompilerContext.getLogger().startMethod(mt.getName() + " " + mt.getDescriptor());
|
||||
@@ -68,13 +61,13 @@ public class ClassWrapper {
|
||||
|
||||
try {
|
||||
if (mt.containsCode()) {
|
||||
if (maxSec == 0 || testMode) {
|
||||
if (testMode) {
|
||||
root = MethodProcessorRunnable.codeToJava(classStruct, mt, md, varProc);
|
||||
}
|
||||
else {
|
||||
DecompilerContext context = DecompilerContext.getCurrentContext();
|
||||
try {
|
||||
cancellationManager.startMethod();
|
||||
cancellationManager.startMethod(classStruct.qualifiedName, mt.getName());
|
||||
MethodProcessorRunnable mtProc =
|
||||
new MethodProcessorRunnable(classStruct, mt, md, varProc, DecompilerContext.getCurrentContext());
|
||||
mtProc.run();
|
||||
@@ -83,7 +76,7 @@ public class ClassWrapper {
|
||||
}
|
||||
finally {
|
||||
DecompilerContext.setCurrentContext(context);
|
||||
cancellationManager.finishMethod();
|
||||
cancellationManager.finishMethod(classStruct.qualifiedName, mt.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,19 +39,15 @@ public class CancellableTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxSec(int sec) {
|
||||
public void startMethod(String className, String methodName) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startMethod() {
|
||||
public void finishMethod(String className, String methodName) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishMethod() {
|
||||
|
||||
}
|
||||
|
||||
private void check() {
|
||||
if (myAtomicInteger.incrementAndGet() > MIN_CALL_NUMBERS) {
|
||||
|
||||
@@ -7,10 +7,14 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.java.decompiler.main.CancellationManager;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public class IdeaCancellationManager extends CancellationManager.SimpleWithTimeoutCancellationManager {
|
||||
public class IdeaCancellationManager extends CancellationManager.TimeoutCancellationManager {
|
||||
|
||||
public IdeaCancellationManager(int maxMethodTimeoutSec) {
|
||||
super(maxMethodTimeoutSec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCanceled() throws CanceledException, TimeExceedException {
|
||||
public void checkCanceled() throws CanceledException {
|
||||
try {
|
||||
ProgressManager.checkCanceled();
|
||||
}
|
||||
|
||||
@@ -147,8 +147,9 @@ class IdeaDecompiler : ClassFileDecompilers.Light() {
|
||||
val provider = MyBytecodeProvider(files)
|
||||
val saver = MyResultSaver()
|
||||
|
||||
val maxSecProcessingMethod = options[IFernflowerPreferences.MAX_PROCESSING_METHOD]?.toString()?.toIntOrNull() ?: 0
|
||||
val decompiler = BaseDecompiler(provider, saver, options, myLogger.value,
|
||||
IdeaCancellationManager())
|
||||
IdeaCancellationManager(maxSecProcessingMethod))
|
||||
files.forEach { decompiler.addSource(File(it.path)) }
|
||||
try {
|
||||
decompiler.decompileContext()
|
||||
|
||||
Reference in New Issue
Block a user