Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76393173
jadx
提交
1c60e5e3
J
jadx
项目概览
2301_76393173
/
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 搜索 >>
提交
1c60e5e3
编写于
12月 13, 2013
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core: inline anonymous classes
上级
a9290f31
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
136 addition
and
56 deletion
+136
-56
jadx-core/src/main/java/jadx/core/Consts.java
jadx-core/src/main/java/jadx/core/Consts.java
+1
-0
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+1
-1
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+11
-5
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+49
-39
jadx-core/src/main/java/jadx/core/dex/attributes/AttributeFlag.java
...src/main/java/jadx/core/dex/attributes/AttributeFlag.java
+1
-0
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
+5
-1
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+11
-7
jadx-core/src/test/java/jadx/api/InternalJadxTest.java
jadx-core/src/test/java/jadx/api/InternalJadxTest.java
+2
-0
jadx-core/src/test/java/jadx/tests/internal/TestAnonymousClass.java
...src/test/java/jadx/tests/internal/TestAnonymousClass.java
+41
-0
jadx-core/src/test/java/jadx/tests/internal/TestLoopCondition.java
.../src/test/java/jadx/tests/internal/TestLoopCondition.java
+0
-2
jadx-samples/src/main/java/jadx/samples/TestInner.java
jadx-samples/src/main/java/jadx/samples/TestInner.java
+14
-1
未找到文件。
jadx-core/src/main/java/jadx/core/Consts.java
浏览文件 @
1c60e5e3
...
...
@@ -20,4 +20,5 @@ public class Consts {
public
static
final
String
DALVIK_ANNOTATION_DEFAULT
=
"dalvik.annotation.AnnotationDefault"
;
public
static
final
String
DEFAULT_PACKAGE_NAME
=
"defpackage"
;
public
static
final
String
ANONYMOUS_CLASS_PREFIX
=
"AnonymousClass_"
;
}
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
浏览文件 @
1c60e5e3
...
...
@@ -243,7 +243,7 @@ public class ClassGen {
mthGen
.
makeMethodDump
(
code
);
}
mthGen
.
addDefinition
(
code
);
code
.
add
(
" {"
);
code
.
add
(
'{'
);
insertSourceFileInfo
(
code
,
mth
);
code
.
add
(
mthGen
.
makeInstructions
(
code
.
getIndent
()));
code
.
startLine
(
'}'
);
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
浏览文件 @
1c60e5e3
...
...
@@ -33,6 +33,7 @@ import jadx.core.dex.nodes.MethodNode;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.RegionUtils
;
import
jadx.core.utils.StringUtils
;
import
jadx.core.utils.exceptions.CodegenException
;
...
...
@@ -523,13 +524,18 @@ public class InsnGen {
if
(
cls
!=
null
&&
cls
.
isAnonymous
())
{
// anonymous class construction
ClassInfo
parent
;
if
(
cls
.
getSuperClass
()
!=
null
&&
!
cls
.
getSuperClass
().
getFullName
().
equals
(
"java.lang.Object"
))
if
(
cls
.
getSuperClass
()
!=
null
&&
!
cls
.
getSuperClass
().
isObject
())
{
parent
=
cls
.
getSuperClass
();
else
}
else
{
parent
=
cls
.
getInterfaces
().
get
(
0
);
code
.
add
(
"new "
).
add
(
useClass
(
parent
)).
add
(
"()"
);
}
MethodNode
defCtr
=
cls
.
getDefaultConstructor
();
if
(
RegionUtils
.
notEmpty
(
defCtr
.
getRegion
()))
{
defCtr
.
getAttributes
().
add
(
AttributeFlag
.
ANONYMOUS_CONSTRUCTOR
);
}
else
{
defCtr
.
getAttributes
().
add
(
AttributeFlag
.
DONT_GENERATE
);
}
code
.
add
(
"new "
).
add
(
useClass
(
parent
)).
add
(
"() "
);
code
.
incIndent
(
2
);
new
ClassGen
(
cls
,
mgen
.
getClassGen
().
getParentGen
(),
fallback
).
makeClassBody
(
code
);
code
.
decIndent
(
2
);
...
...
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
浏览文件 @
1c60e5e3
package
jadx.core.codegen
;
import
jadx.core.Consts
;
import
jadx.core.dex.attributes.AttributeFlag
;
import
jadx.core.dex.attributes.AttributeType
;
import
jadx.core.dex.attributes.AttributesList
;
import
jadx.core.dex.attributes.JadxErrorAttr
;
...
...
@@ -57,52 +58,61 @@ public class MethodGen {
}
public
void
addDefinition
(
CodeWriter
code
)
{
if
(
mth
.
getMethodInfo
().
isClassInit
())
{
code
.
startLine
(
"static"
);
}
else
{
annotationGen
.
addForMethod
(
code
,
mth
);
AccessInfo
clsAccFlags
=
mth
.
getParentClass
().
getAccessFlags
();
AccessInfo
ai
=
mth
.
getAccessFlags
();
// don't add 'abstract' to methods in interface
if
(
clsAccFlags
.
isInterface
())
{
ai
=
ai
.
remove
(
AccessFlags
.
ACC_ABSTRACT
);
}
// don't add 'public' for annotations
if
(
clsAccFlags
.
isAnnotation
())
{
ai
=
ai
.
remove
(
AccessFlags
.
ACC_PUBLIC
);
}
code
.
startLine
(
ai
.
makeString
());
code
.
attachAnnotation
(
mth
);
return
;
}
if
(
mth
.
getAttributes
().
contains
(
AttributeFlag
.
ANONYMOUS_CONSTRUCTOR
))
{
// don't add method name and arguments
code
.
startLine
();
code
.
attachAnnotation
(
mth
);
return
;
}
annotationGen
.
addForMethod
(
code
,
mth
);
if
(
classGen
.
makeGenericMap
(
code
,
mth
.
getGenericMap
()))
code
.
add
(
' '
);
AccessInfo
clsAccFlags
=
mth
.
getParentClass
().
getAccessFlags
();
AccessInfo
ai
=
mth
.
getAccessFlags
();
// don't add 'abstract' to methods in interface
if
(
clsAccFlags
.
isInterface
())
{
ai
=
ai
.
remove
(
AccessFlags
.
ACC_ABSTRACT
);
}
// don't add 'public' for annotations
if
(
clsAccFlags
.
isAnnotation
())
{
ai
=
ai
.
remove
(
AccessFlags
.
ACC_PUBLIC
);
}
code
.
startLine
(
ai
.
makeString
());
if
(
mth
.
getAccessFlags
().
isConstructor
())
{
code
.
add
(
classGen
.
getClassNode
().
getShortName
());
// constructor
if
(
classGen
.
makeGenericMap
(
code
,
mth
.
getGenericMap
()))
{
code
.
add
(
' '
);
}
if
(
mth
.
getAccessFlags
().
isConstructor
())
{
code
.
add
(
classGen
.
getClassNode
().
getShortName
());
// constructor
}
else
{
code
.
add
(
TypeGen
.
translate
(
classGen
,
mth
.
getReturnType
()));
code
.
add
(
' '
);
code
.
add
(
mth
.
getName
());
}
code
.
add
(
'('
);
List
<
RegisterArg
>
args
=
mth
.
getArguments
(
false
);
if
(
mth
.
getMethodInfo
().
isConstructor
()
&&
mth
.
getParentClass
().
getAttributes
().
contains
(
AttributeType
.
ENUM_CLASS
))
{
if
(
args
.
size
()
==
2
)
{
args
.
clear
();
}
else
if
(
args
.
size
()
>
2
)
{
args
=
args
.
subList
(
2
,
args
.
size
());
}
else
{
code
.
add
(
TypeGen
.
translate
(
classGen
,
mth
.
getReturnType
()));
code
.
add
(
' '
);
code
.
add
(
mth
.
getName
(
));
LOG
.
warn
(
ErrorsCounter
.
formatErrorMsg
(
mth
,
"Incorrect number of args for enum constructor: "
+
args
.
size
()
+
" (expected >= 2)"
));
}
code
.
add
(
'('
);
List
<
RegisterArg
>
args
=
mth
.
getArguments
(
false
);
if
(
mth
.
getMethodInfo
().
isConstructor
()
&&
mth
.
getParentClass
().
getAttributes
().
contains
(
AttributeType
.
ENUM_CLASS
))
{
if
(
args
.
size
()
==
2
)
args
.
clear
();
else
if
(
args
.
size
()
>
2
)
args
=
args
.
subList
(
2
,
args
.
size
());
else
LOG
.
warn
(
ErrorsCounter
.
formatErrorMsg
(
mth
,
"Incorrect number of args for enum constructor: "
+
args
.
size
()
+
" (expected >= 2)"
));
}
code
.
add
(
makeArguments
(
args
));
code
.
add
(
")"
);
annotationGen
.
addThrows
(
mth
,
code
);
}
code
.
add
(
makeArguments
(
args
));
code
.
add
(
") "
);
annotationGen
.
addThrows
(
mth
,
code
);
code
.
attachAnnotation
(
mth
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AttributeFlag.java
浏览文件 @
1c60e5e3
...
...
@@ -17,6 +17,7 @@ public enum AttributeFlag {
SKIP
,
SKIP_FIRST_ARG
,
ANONYMOUS_CONSTRUCTOR
,
INCONSISTENT_CODE
,
// warning about incorrect decompilation
}
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
浏览文件 @
1c60e5e3
...
...
@@ -80,7 +80,7 @@ public final class ClassInfo {
char
firstChar
=
name
.
charAt
(
0
);
if
(
Character
.
isDigit
(
firstChar
))
{
name
=
"AnonymousClass_"
+
name
;
name
=
Consts
.
ANONYMOUS_CLASS_PREFIX
+
name
;
}
else
if
(
firstChar
==
'$'
)
{
name
=
"_"
+
name
;
}
...
...
@@ -101,6 +101,10 @@ public final class ClassInfo {
return
fullName
;
}
public
boolean
isObject
()
{
return
fullName
.
equals
(
Consts
.
CLASS_OBJECT
);
}
public
String
getShortName
()
{
return
name
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
浏览文件 @
1c60e5e3
...
...
@@ -338,15 +338,19 @@ public class ClassNode extends LineAttrNode implements ILoadable {
}
public
boolean
isAnonymous
()
{
boolean
simple
=
false
;
for
(
MethodNode
m
:
methods
)
{
MethodInfo
mi
=
m
.
getMethodInfo
();
if
(
mi
.
isConstructor
()
&&
mi
.
getArgumentsTypes
().
size
()
==
0
)
{
simple
=
true
;
break
;
MethodNode
defConstrExists
=
getDefaultConstructor
();
return
defConstrExists
!=
null
&&
getShortName
().
startsWith
(
Consts
.
ANONYMOUS_CLASS_PREFIX
);
}
public
MethodNode
getDefaultConstructor
()
{
for
(
MethodNode
mth
:
methods
)
{
if
(
mth
.
getAccessFlags
().
isConstructor
()
&&
mth
.
getMethodInfo
().
isConstructor
()
&&
mth
.
getArguments
(
false
).
isEmpty
())
{
return
mth
;
}
}
return
simple
&&
Character
.
isDigit
(
getShortName
().
charAt
(
0
))
;
return
null
;
}
public
AccessInfo
getAccessFlags
()
{
...
...
jadx-core/src/test/java/jadx/api/InternalJadxTest.java
浏览文件 @
1c60e5e3
...
...
@@ -140,6 +140,8 @@ public abstract class InternalJadxTest {
}
}
// Use only for debug purpose
@Deprecated
protected
void
setOutputCFG
()
{
this
.
outputCFG
=
true
;
}
...
...
jadx-core/src/test/java/jadx/tests/internal/TestAnonymousClass.java
0 → 100644
浏览文件 @
1c60e5e3
package
jadx.tests.internal
;
import
jadx.api.InternalJadxTest
;
import
jadx.core.dex.nodes.ClassNode
;
import
java.io.File
;
import
java.io.FilenameFilter
;
import
org.junit.Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestAnonymousClass
extends
InternalJadxTest
{
public
static
class
TestCls
{
public
int
test
()
{
String
[]
files
=
new
File
(
"a"
).
list
(
new
FilenameFilter
()
{
@Override
public
boolean
accept
(
File
dir
,
String
name
)
{
return
name
.
equals
(
"a"
);
}
});
return
files
.
length
;
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsString
(
"new File(\"a\").list(new FilenameFilter()"
));
assertThat
(
code
,
not
(
containsString
(
"synthetic"
)));
assertThat
(
code
,
not
(
containsString
(
"this"
)));
assertThat
(
code
,
not
(
containsString
(
"null"
)));
assertThat
(
code
,
not
(
containsString
(
"AnonymousClass_"
)));
}
}
jadx-core/src/test/java/jadx/tests/internal/TestLoopCondition.java
浏览文件 @
1c60e5e3
...
...
@@ -53,8 +53,6 @@ public class TestLoopCondition extends InternalJadxTest {
@Test
public
void
test
()
{
setOutputCFG
();
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
...
...
jadx-samples/src/main/java/jadx/samples/TestInner.java
浏览文件 @
1c60e5e3
...
...
@@ -51,6 +51,18 @@ public class TestInner extends AbstractTest {
}.
run
();
}
public
void
func2
()
{
new
Runnable
()
{
{
count
+=
5
;
}
@Override
public
void
run
()
{
count
+=
6
;
}
}.
run
();
}
@SuppressWarnings
(
"serial"
)
public
static
class
MyException
extends
Exception
{
public
MyException
(
String
str
,
Exception
e
)
{
...
...
@@ -63,6 +75,7 @@ public class TestInner extends AbstractTest {
TestInner
c
=
new
TestInner
();
TestInner
.
count
=
0
;
c
.
func
();
c
.
func2
();
Runnable
myRunnable
=
new
Runnable
()
{
@Override
...
...
@@ -81,6 +94,6 @@ public class TestInner extends AbstractTest {
thread
.
join
();
thread2
.
join
();
return
TestInner
.
count
==
15
;
return
TestInner
.
count
==
26
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录