Commit aa2b95f2 authored by Egor.Ushakov's avatar Egor.Ushakov
Browse files

IDEA-149093 Decompiled code: invocation of static method on class with $ in name - fix prototype

parent 89151b22
Branches unavailable Tags unavailable
No related merge requests found
Showing with 74 additions and 5 deletions
+74 -5
......@@ -19,6 +19,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeSourceMapper;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.main.collectors.ImportCollector;
import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector;
import org.jetbrains.java.decompiler.main.extern.IClassNameHelper;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor;
......@@ -46,6 +47,7 @@ public class DecompilerContext {
private PoolInterceptor poolInterceptor;
private IFernflowerLogger logger;
private BytecodeSourceMapper bytecodeSourceMapper;
private IClassNameHelper classNameProvider;
private DecompilerContext(Map<String, Object> properties) {
this.properties = properties;
......@@ -135,6 +137,14 @@ public class DecompilerContext {
getCurrentContext().bytecodeSourceMapper = bytecodeSourceMapper;
}
public static IClassNameHelper getClassNameProvider() {
return getCurrentContext().classNameProvider;
}
public static void setClassNameProvider(IClassNameHelper classNameProvider) {
getCurrentContext().classNameProvider = classNameProvider;
}
public static IFernflowerLogger getLogger() {
return getCurrentContext().logger;
}
......
/*
* 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.
......@@ -73,9 +73,6 @@ public class ImportCollector {
return retname;
}
}
else {
fullname = fullname.replace('$', '.');
}
String nshort = fullname;
String npackage = "";
......
/*
* Copyright 2000-2014 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.
......@@ -15,8 +15,10 @@
*/
package org.jetbrains.java.decompiler.main.decompiler;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.Fernflower;
import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider;
import org.jetbrains.java.decompiler.main.extern.IClassNameHelper;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
......@@ -36,6 +38,10 @@ public class BaseDecompiler {
fernflower.getStructContext().addSpace(file, isOwn);
}
public void setClassNameProvider(IClassNameHelper provider) {
DecompilerContext.setClassNameProvider(provider);
}
public void decompileContext() {
try {
fernflower.decompileContext();
......
/*
* 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 org.jetbrains.java.decompiler.main.extern;
/**
* Helper class to provide short name of ambiguous jvm class names like org.my/A$B
*/
public interface IClassNameHelper {
/**
* Check class fqn like org.my/A$B
* and return org.my.A.B if it is an inner class
* or org.my.A$B if it is a real class name with $ inside
* or null if unknown
*/
String getClassName(String fqName);
}
......@@ -22,6 +22,7 @@ import org.jetbrains.java.decompiler.code.cfg.BasicBlock;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.extern.IClassNameHelper;
import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode;
......@@ -776,6 +777,14 @@ public class ExprProcessor implements CodeConstants {
}
public static String buildJavaClassName(String name) {
IClassNameHelper classNameProvider = DecompilerContext.getClassNameProvider();
if (classNameProvider != null) {
String res = classNameProvider.getClassName(name);
if (res != null) {
return res;
}
}
String res = name.replace('/', '.');
if (res.contains("$")) { // attempt to invoke foreign member
......
......@@ -29,6 +29,7 @@ import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.DefaultProjectFactory
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.registry.Registry
......@@ -36,9 +37,11 @@ import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.newvfs.RefreshQueue
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
import com.intellij.psi.PsiManager
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
import com.intellij.psi.compiled.ClassFileDecompilers
import com.intellij.psi.impl.compiled.ClsFileImpl
import com.intellij.psi.util.ClassUtil
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.annotations.TestOnly
import org.jetbrains.java.decompiler.main.decompiler.BaseDecompiler
......@@ -157,6 +160,21 @@ class IdeaDecompiler : ClassFileDecompilers.Light() {
val saver = MyResultSaver()
val decompiler = BaseDecompiler(provider, saver, options, myLogger.value)
files.keys.forEach { path -> decompiler.addSpace(File(path), true) }
ApplicationManager.getApplication().runReadAction {
val openProjects = ProjectManager.getInstance().openProjects
val project = openProjects.filter { p -> PsiManager.getInstance(p).findFile(file) != null }.firstOrNull()
project?.let {
decompiler.setClassNameProvider {
fqn ->
ApplicationManager.getApplication().runReadAction<String> {
ClassUtil.findPsiClass(PsiManager.getInstance(project), fqn.replace("/", "."), null, true)?.qualifiedName
}
}
}
}
decompiler.decompileContext()
val mapping = saver.myMapping
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment