Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
keyescgm
jadx
提交
950fbbaa
J
jadx
项目概览
keyescgm
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
950fbbaa
编写于
3月 17, 2023
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: restore missing type parameter declarations (#1800)
上级
912c4315
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
222 addition
and
8 deletion
+222
-8
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+2
-6
jadx-core/src/main/java/jadx/core/dex/visitors/SignatureProcessor.java
.../main/java/jadx/core/dex/visitors/SignatureProcessor.java
+47
-2
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+5
-0
jadx-core/src/test/java/jadx/tests/integration/inline/TestInstanceLambda.java
...ava/jadx/tests/integration/inline/TestInstanceLambda.java
+72
-0
jadx-core/src/test/smali/inline/TestInstanceLambda/Lambda.smali
...ore/src/test/smali/inline/TestInstanceLambda/Lambda.smali
+40
-0
jadx-core/src/test/smali/inline/TestInstanceLambda/TestCls.smali
...re/src/test/smali/inline/TestInstanceLambda/TestCls.smali
+56
-0
未找到文件。
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
浏览文件 @
950fbbaa
...
...
@@ -13,8 +13,6 @@ import java.util.stream.Collectors;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.DecompilationMode
;
import
jadx.api.ICodeCache
;
...
...
@@ -56,8 +54,6 @@ import static jadx.core.dex.nodes.ProcessState.LOADED;
import
static
jadx
.
core
.
dex
.
nodes
.
ProcessState
.
NOT_LOADED
;
public
class
ClassNode
extends
NotificationAttrNode
implements
ILoadable
,
ICodeNode
,
Comparable
<
ClassNode
>
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ClassNode
.
class
);
private
final
RootNode
root
;
private
final
IClassData
clsData
;
...
...
@@ -174,10 +170,10 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
return
ArgType
.
object
(
superType
);
}
public
void
updateGenericClsData
(
ArgType
superClass
,
List
<
ArgType
>
interfaces
,
List
<
ArgType
>
generics
)
{
public
void
updateGenericClsData
(
List
<
ArgType
>
generics
,
ArgType
superClass
,
List
<
ArgType
>
interfaces
)
{
this
.
generics
=
generics
;
this
.
superClass
=
superClass
;
this
.
interfaces
=
interfaces
;
this
.
generics
=
generics
;
}
private
static
void
processAttributes
(
ClassNode
cls
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/SignatureProcessor.java
浏览文件 @
950fbbaa
...
...
@@ -2,8 +2,12 @@ package jadx.core.dex.visitors;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Set
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.core.dex.info.MethodInfo
;
import
jadx.core.dex.instructions.args.ArgType
;
...
...
@@ -18,7 +22,6 @@ import jadx.core.utils.Utils;
import
jadx.core.utils.exceptions.JadxException
;
public
class
SignatureProcessor
extends
AbstractVisitor
{
private
RootNode
root
;
@Override
...
...
@@ -55,12 +58,54 @@ public class SignatureProcessor extends AbstractVisitor {
break
;
}
}
cls
.
updateGenericClsData
(
superClass
,
interfaces
,
generics
);
generics
=
fixTypeParamDeclarations
(
cls
,
generics
,
superClass
,
interfaces
);
cls
.
updateGenericClsData
(
generics
,
superClass
,
interfaces
);
}
catch
(
Exception
e
)
{
cls
.
addWarnComment
(
"Failed to parse class signature: "
+
sp
.
getSignature
(),
e
);
}
}
/**
* Add missing type parameters from super type and interfaces to make code compilable
*/
private
static
List
<
ArgType
>
fixTypeParamDeclarations
(
ClassNode
cls
,
List
<
ArgType
>
generics
,
ArgType
superClass
,
List
<
ArgType
>
interfaces
)
{
if
(
interfaces
.
isEmpty
()
&&
superClass
.
equals
(
ArgType
.
OBJECT
))
{
return
generics
;
}
Set
<
String
>
typeParams
=
new
HashSet
<>();
superClass
.
visitTypes
(
t
->
addGenericType
(
typeParams
,
t
));
interfaces
.
forEach
(
i
->
i
.
visitTypes
(
t
->
addGenericType
(
typeParams
,
t
)));
if
(
typeParams
.
isEmpty
())
{
return
generics
;
}
List
<
ArgType
>
knownTypeParams
;
if
(
cls
.
isInner
())
{
knownTypeParams
=
new
ArrayList
<>(
generics
);
cls
.
visitParentClasses
(
p
->
knownTypeParams
.
addAll
(
p
.
getGenericTypeParameters
()));
}
else
{
knownTypeParams
=
generics
;
}
for
(
ArgType
declTypeParam
:
knownTypeParams
)
{
typeParams
.
remove
(
declTypeParam
.
getObject
());
}
if
(
typeParams
.
isEmpty
())
{
return
generics
;
}
cls
.
addInfoComment
(
"Add missing generic type declarations: "
+
typeParams
);
List
<
ArgType
>
fixedGenerics
=
new
ArrayList
<>(
generics
.
size
()
+
typeParams
.
size
());
fixedGenerics
.
addAll
(
generics
);
typeParams
.
stream
().
sorted
().
map
(
ArgType:
:
genericType
).
forEach
(
fixedGenerics:
:
add
);
return
fixedGenerics
;
}
private
static
@Nullable
Object
addGenericType
(
Set
<
String
>
usedTypeParameters
,
ArgType
t
)
{
if
(
t
.
isGenericType
())
{
usedTypeParameters
.
add
(
t
.
getObject
());
}
return
null
;
}
private
ArgType
validateClsType
(
ClassNode
cls
,
ArgType
candidateType
,
ArgType
currentType
)
{
if
(!
candidateType
.
isObject
())
{
cls
.
addWarnComment
(
"Incorrect class signature, class is not object: "
+
SignatureParser
.
getSignature
(
cls
));
...
...
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
浏览文件 @
950fbbaa
...
...
@@ -224,6 +224,11 @@ public abstract class IntegrationTest extends TestUtils {
return
sortedClsNodes
;
}
@NotNull
public
ClassNode
searchTestCls
(
List
<
ClassNode
>
list
,
String
shortClsName
)
{
return
searchCls
(
list
,
getTestPkg
()
+
'.'
+
shortClsName
);
}
@NotNull
public
ClassNode
searchCls
(
List
<
ClassNode
>
list
,
String
clsName
)
{
for
(
ClassNode
cls
:
list
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/inline/TestInstanceLambda.java
0 → 100644
浏览文件 @
950fbbaa
package
jadx.tests.integration.inline
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
import
org.junit.jupiter.api.Test
;
import
jadx.NotYetImplemented
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestInstanceLambda
extends
SmaliTest
{
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
,
"SameParameterValue"
})
public
static
class
TestCls
{
public
<
T
>
Map
<
T
,
T
>
test
(
List
<?
extends
T
>
list
)
{
return
toMap
(
list
,
Lambda
.
INSTANCE
);
}
/**
* Smali test missing 'T' definition in 'Lambda<T>'
*/
private
static
class
Lambda
<
T
>
implements
Function
<
T
,
T
>
{
public
static
final
Lambda
INSTANCE
=
new
Lambda
();
@Override
public
T
apply
(
T
t
)
{
return
t
;
}
}
private
static
<
T
>
Map
<
T
,
T
>
toMap
(
List
<?
extends
T
>
list
,
Function
<
T
,
T
>
valueMap
)
{
return
list
.
stream
().
collect
(
Collectors
.
toMap
(
k
->
k
,
valueMap
));
}
}
@Test
public
void
test
()
{
noDebugInfo
();
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
();
}
@Test
public
void
testSmaliDisableInline
()
{
args
.
setInlineAnonymousClasses
(
false
);
List
<
ClassNode
>
classNodes
=
loadFromSmaliFiles
();
assertThat
(
searchTestCls
(
classNodes
,
"Lambda"
))
.
code
()
.
containsOne
(
"class Lambda<T> implements Function<T, T> {"
);
assertThat
(
searchTestCls
(
classNodes
,
"TestCls"
))
.
code
()
.
containsOne
(
"Lambda.INSTANCE"
);
}
@NotYetImplemented
(
"Inline lambda by instance field"
)
@Test
public
void
testSmali
()
{
List
<
ClassNode
>
classNodes
=
loadFromSmaliFiles
();
assertThat
(
classNodes
)
.
describedAs
(
"Expect lambda to be inlined"
)
.
hasSize
(
1
);
assertThat
(
searchTestCls
(
classNodes
,
"TestCls"
))
.
code
()
.
doesNotContain
(
"Lambda.INSTANCE"
);
}
}
jadx-core/src/test/smali/inline/TestInstanceLambda/Lambda.smali
0 → 100644
浏览文件 @
950fbbaa
.class public Linline/Lambda;
.super Ljava/lang/Object;
.implements Ljava/util/function/Function;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Object;",
"Ljava/util/function/Function",
"<TT;TT;>;"
}
.end annotation
.field public static final INSTANCE:Linline/Lambda;
.method static constructor <clinit>()V
.registers 1
new-instance v0, Linline/Lambda;
invoke-direct {v0}, Linline/Lambda;-><init>()V
sput-object v0, Linline/Lambda;->INSTANCE:Linline/Lambda;
return-void
.end method
.method private constructor <init>()V
.registers 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public final apply(Ljava/lang/Object;)Ljava/lang/Object;
.registers 2
.annotation system Ldalvik/annotation/Signature;
value = {
"(TT;)TT;"
}
.end annotation
return-object p1
.end method
jadx-core/src/test/smali/inline/TestInstanceLambda/TestCls.smali
0 → 100644
浏览文件 @
950fbbaa
.class public Linline/TestCls;
.super Ljava/lang/Object;
.method public test(Ljava/util/List;)Ljava/util/Map;
.registers 3
.annotation system Ldalvik/annotation/Signature;
value = {
"<T:",
"Ljava/lang/Object;",
">(",
"Ljava/util/List",
"<+TT;>;)",
"Ljava/util/Map",
"<TT;TT;>;"
}
.end annotation
sget-object v0, Linline/Lambda;->INSTANCE:Linline/Lambda;
invoke-static {p1, v0}, Linline/TestCls;->toMap(Ljava/util/List;Ljava/util/function/Function;)Ljava/util/Map;
move-result-object v0
return-object v0
.end method
.method private static synthetic lambda$toMap$0(Ljava/lang/Object;)Ljava/lang/Object;
.registers 1
return-object p0
.end method
.method private static toMap(Ljava/util/List;Ljava/util/function/Function;)Ljava/util/Map;
.registers 4
.annotation system Ldalvik/annotation/Signature;
value = {
"<T:",
"Ljava/lang/Object;",
">(",
"Ljava/util/List",
"<+TT;>;",
"Ljava/util/function/Function",
"<TT;TT;>;)",
"Ljava/util/Map",
"<TT;TT;>;"
}
.end annotation
invoke-interface {p0}, Ljava/util/List;->stream()Ljava/util/stream/Stream;
move-result-object v0
invoke-custom {}, call_site_0("apply", ()Ljava/util/function/Function;, (Ljava/lang/Object;)Ljava/lang/Object;, invoke-static@Linline/TestCls;->lambda$toMap$0(Ljava/lang/Object;)Ljava/lang/Object;, (Ljava/lang/Object;)Ljava/lang/Object;)@Ljava/lang/invoke/LambdaMetafactory;->metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
move-result-object v1
invoke-static {v1, p1}, Ljava/util/stream/Collectors;->toMap(Ljava/util/function/Function;Ljava/util/function/Function;)Ljava/util/stream/Collector;
move-result-object v1
invoke-interface {v0, v1}, Ljava/util/stream/Stream;->collect(Ljava/util/stream/Collector;)Ljava/lang/Object;
move-result-object v0
check-cast v0, Ljava/util/Map;
return-object v0
.end method
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录