style: enforce code style using checkstyle and spotless with eclipse formatter (PR #650)

This commit is contained in:
skylot
2019-04-30 00:04:16 +03:00
committed by GitHub
parent e1dfb4ee59
commit c7890f2468
272 changed files with 1938 additions and 1368 deletions
+1 -5
View File
@@ -7,14 +7,10 @@ insert_final_newline = true
indent_style = tab
tab_width = 4
continuation_indent_size = 8 #IntelliJ Idea specific workaround
continuation_indent_size = 8 #IntelliJ Idea specific workaround
charset = utf-8
trim_trailing_whitespace = true
max_line_length = 120
[*.xml]
indent_size = 1
[*.yml]
indent_style = space
+1
View File
@@ -10,6 +10,7 @@ out/
*.ipr
*.iws
.attach_pid*
*.hprof
**/.DS_Store
+35 -12
View File
@@ -1,7 +1,9 @@
import com.diffplug.spotless.LineEnding
plugins {
id 'org.sonarqube' version '2.7'
id 'com.github.ben-manes.versions' version '0.21.0'
id 'org.ec4j.editorconfig' version '0.0.3'
id "com.diffplug.gradle.spotless" version "3.21.1"
}
ext.jadxVersion = System.getenv('JADX_VERSION') ?: "dev"
@@ -11,6 +13,7 @@ println("jadx version: ${jadxVersion}")
allprojects {
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'checkstyle'
version = jadxVersion
@@ -67,6 +70,11 @@ allprojects {
html.enabled = true
}
}
checkstyleMain {
// exclude all sources in samples module
exclude '**/samples/**'
}
}
sonarqube {
@@ -76,14 +84,32 @@ sonarqube {
}
}
editorconfig {
excludes = ['gradle/'
, 'jadx-test-app/test-app' // ignore issues in submodule
, '**/out/' // IntelliJ Idea build dirs
, '**/certificate-test/' // binary test files (.RSA)
, '**/*.svg'
, '**/*.arsc'
]
spotless {
java {
target fileTree(rootDir).matching {
include 'jadx-cli/src/**/java/**/*.java'
include 'jadx-core/src/**/java/**/*.java'
include 'jadx-gui/src/**/java/**/*.java'
}
importOrderFile 'config/code-formatter/eclipse.importorder'
eclipse().configFile 'config/code-formatter/eclipse.xml'
removeUnusedImports()
lineEndings(LineEnding.UNIX)
encoding("UTF-8")
trimTrailingWhitespace()
endWithNewline()
}
format 'misc', {
target '**/*.gradle', '**/*.md', '**/*.xml', '**/.gitignore', '**/.properties'
targetExclude "jadx-test-app/test-app/**", ".gradle/**", ".idea/**"
lineEndings(LineEnding.UNIX)
encoding("UTF-8")
trimTrailingWhitespace()
endWithNewline()
}
}
dependencyUpdates.resolutionStrategy = {
@@ -138,9 +164,6 @@ task cleanBuildDir(type: Delete) {
delete buildDir
}
check.dependsOn editorconfigCheck
test.dependsOn(samples)
clean.dependsOn(cleanBuildDir)
+116
View File
@@ -0,0 +1,116 @@
<?xml version="1.0" ?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
<property name="fileExtensions" value="java, properties, xml"/>
<property name="charset" value="UTF-8"/>
<module name="TreeWalker">
<property name="tabWidth" value="4"/>
<module name="RegexpSinglelineJava">
<property name="format" value="^\t* "/>
<property name="message" value="Indent must use tab characters"/>
<property name="ignoreComments" value="true"/>
</module>
<module name="RegexpSinglelineJava">
<property name="format" value="^(?!\s+\* $).*?\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowByTailComment" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="EmptyLineSeparator">
<property name="allowNoEmptyLineBetweenFields" value="true"/>
<property name="allowMultipleEmptyLines" value="false"/>
</module>
<!-- whitespaces -->
<module name="SingleSpaceSeparator"/>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround">
<property name="allowEmptyMethods" value="true"/>
</module>
<!-- <module name="EmptyForIteratorPad"/> -->
<!-- <module name="NoWhitespaceAfter"/>-->
<module name="NoLineWrap"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!-- <module name="AvoidStarImport"/> -->
<module name="NeedBraces"/>
<module name="LeftCurly"/>
<module name="RightCurly"/>
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="expected|ignore"/>
</module>
<!-- naming -->
<module name="PackageName"/>
<module name="TypeName"/>
<module name="InterfaceTypeParameterName"/>
<module name="ClassTypeParameterName"/>
<module name="StaticVariableName"/>
<module name="ConstantName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="MethodTypeParameterName"/>
<module name="ParameterName"/>
<module name="LambdaParameterName"/>
<module name="LocalVariableName"/>
<module name="LocalFinalVariableName"/>
<module name="CatchParameterName"/>
<!-- <module name="HiddenField"/> -->
<!-- annotations -->
<module name="AnnotationLocation"/>
<module name="AnnotationUseStyle"/>
<module name="MissingOverride"/>
<!-- <module name="MissingDeprecated"/> -->
<module name="ModifierOrder"/>
<!-- <module name="RedundantModifier"/> -->
<!-- <module name="ParameterNumber"/> -->
<module name="EmptyStatement"/>
<module name="DefaultComesLast"/>
<module name="EqualsHashCode"/>
<module name="FallThrough"/>
<!-- <module name="IllegalCatch"/> -->
<module name="IllegalThrows"/>
<module name="IllegalType"/>
<module name="InnerAssignment"/>
<module name="MultipleVariableDeclarations"/>
<module name="NoClone"/>
<module name="NoFinalizer"/>
<module name="OneStatementPerLine"/>
<module name="PackageDeclaration"/>
<module name="StringLiteralEquality"/>
<!-- misc -->
<module name="ArrayTypeStyle"/>
<module name="OuterTypeFilename"/>
<!-- sizes -->
<module name="OuterTypeNumber"/>
<module name="SuppressWarningsHolder"/>
</module>
<module name="NewlineAtEndOfFile"/>
<module name="SuppressWarningsFilter"/>
</module>
@@ -0,0 +1,8 @@
#Import Order
0=java
1=javax
2=org
3=com
4=
5=jadx
6=\#
+348
View File
@@ -0,0 +1,348 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="16">
<profile kind="CodeFormatterProfile" name="jadx eclipse" version="16">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="separate_lines_if_wrapped"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="140"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>
@@ -16,45 +16,46 @@ import com.beust.jcommander.Parameter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import jadx.api.JadxArgs;
import jadx.api.JadxArgs.RENAME;
import jadx.api.JadxArgs.RenameEnum;
import jadx.api.JadxDecompiler;
import jadx.core.utils.exceptions.JadxException;
import jadx.core.utils.files.FileUtils;
public class JadxCLIArgs {
@Parameter(description = "<input file> (.apk, .dex, .jar or .class)")
@Parameter(description = "<input file> (.apk, .dex, .jar, .class, .smali, .zip, .aar, .arsc)")
protected List<String> files = new ArrayList<>(1);
@Parameter(names = {"-d", "--output-dir"}, description = "output directory")
@Parameter(names = { "-d", "--output-dir" }, description = "output directory")
protected String outDir;
@Parameter(names = {"-ds", "--output-dir-src"}, description = "output directory for sources")
@Parameter(names = { "-ds", "--output-dir-src" }, description = "output directory for sources")
protected String outDirSrc;
@Parameter(names = {"-dr", "--output-dir-res"}, description = "output directory for resources")
@Parameter(names = { "-dr", "--output-dir-res" }, description = "output directory for resources")
protected String outDirRes;
@Parameter(names = {"-r", "--no-res"}, description = "do not decode resources")
@Parameter(names = { "-r", "--no-res" }, description = "do not decode resources")
protected boolean skipResources = false;
@Parameter(names = {"-s", "--no-src"}, description = "do not decompile source code")
@Parameter(names = { "-s", "--no-src" }, description = "do not decompile source code")
protected boolean skipSources = false;
@Parameter(names = {"-e", "--export-gradle"}, description = "save as android gradle project")
@Parameter(names = { "-e", "--export-gradle" }, description = "save as android gradle project")
protected boolean exportAsGradleProject = false;
@Parameter(names = {"-j", "--threads-count"}, description = "processing threads count")
@Parameter(names = { "-j", "--threads-count" }, description = "processing threads count")
protected int threadsCount = JadxArgs.DEFAULT_THREADS_COUNT;
@Parameter(names = {"--show-bad-code"}, description = "show inconsistent code (incorrectly decompiled)")
@Parameter(names = { "--show-bad-code" }, description = "show inconsistent code (incorrectly decompiled)")
protected boolean showInconsistentCode = false;
@Parameter(names = {"--no-imports"}, description = "disable use of imports, always write entire package name")
@Parameter(names = { "--no-imports" }, description = "disable use of imports, always write entire package name")
protected boolean useImports = true;
@Parameter(names = {"--no-debug-info"}, description = "disable debug info")
@Parameter(names = { "--no-debug-info" }, description = "disable debug info")
protected boolean debugInfo = true;
@Parameter(names = { "--no-inline-anonymous" }, description = "disable anonymous classes inline")
@@ -63,47 +64,54 @@ public class JadxCLIArgs {
@Parameter(names = "--no-replace-consts", description = "don't replace constant value with matching constant field")
protected boolean replaceConsts = true;
@Parameter(names = {"--escape-unicode"}, description = "escape non latin characters in strings (with \\u)")
@Parameter(names = { "--escape-unicode" }, description = "escape non latin characters in strings (with \\u)")
protected boolean escapeUnicode = false;
@Parameter(names = {"--respect-bytecode-access-modifiers"}, description = "don't change original access modifiers")
@Parameter(names = { "--respect-bytecode-access-modifiers" }, description = "don't change original access modifiers")
protected boolean respectBytecodeAccessModifiers = false;
@Parameter(names = {"--deobf"}, description = "activate deobfuscation")
@Parameter(names = { "--deobf" }, description = "activate deobfuscation")
protected boolean deobfuscationOn = false;
@Parameter(names = {"--deobf-min"}, description = "min length of name, renamed if shorter")
@Parameter(names = { "--deobf-min" }, description = "min length of name, renamed if shorter")
protected int deobfuscationMinLength = 3;
@Parameter(names = {"--deobf-max"}, description = "max length of name, renamed if longer")
@Parameter(names = { "--deobf-max" }, description = "max length of name, renamed if longer")
protected int deobfuscationMaxLength = 64;
@Parameter(names = {"--deobf-rewrite-cfg"}, description = "force to save deobfuscation map")
@Parameter(names = { "--deobf-rewrite-cfg" }, description = "force to save deobfuscation map")
protected boolean deobfuscationForceSave = false;
@Parameter(names = {"--deobf-use-sourcename"}, description = "use source file name as class name alias")
@Parameter(names = { "--deobf-use-sourcename" }, description = "use source file name as class name alias")
protected boolean deobfuscationUseSourceNameAsAlias = true;
@Parameter(names = {"--cfg"}, description = "save methods control flow graph to dot file")
@Parameter(names = { "--cfg" }, description = "save methods control flow graph to dot file")
protected boolean cfgOutput = false;
@Parameter(names = {"--raw-cfg"}, description = "save methods control flow graph (use raw instructions)")
@Parameter(names = { "--raw-cfg" }, description = "save methods control flow graph (use raw instructions)")
protected boolean rawCfgOutput = false;
@Parameter(names = {"-f", "--fallback"}, description = "make simple dump (using goto instead of 'if', 'for', etc)")
@Parameter(names = { "-f", "--fallback" }, description = "make simple dump (using goto instead of 'if', 'for', etc)")
protected boolean fallbackMode = false;
@Parameter(names = {"--rename-flags"}, description = "what to rename, comma-separated, 'case' for system case sensitivity, 'valid' for java identifiers, 'printable' characters, 'none' or 'all'",
converter = RenameConverter.class)
protected Set<RENAME> renameFlags = EnumSet.allOf(RENAME.class);
@Parameter(
names = { "--rename-flags" },
description = "what to rename, comma-separated,"
+ " 'case' for system case sensitivity,"
+ " 'valid' for java identifiers,"
+ " 'printable' characters,"
+ " 'none' or 'all'",
converter = RenameConverter.class
)
protected Set<RenameEnum> renameFlags = EnumSet.allOf(RenameEnum.class);
@Parameter(names = {"-v", "--verbose"}, description = "verbose output")
@Parameter(names = { "-v", "--verbose" }, description = "verbose output")
protected boolean verbose = false;
@Parameter(names = {"--version"}, description = "print jadx version")
@Parameter(names = { "--version" }, description = "print jadx version")
protected boolean printVersion = false;
@Parameter(names = {"-h", "--help"}, description = "print this help", help = true)
@Parameter(names = { "-h", "--help" }, description = "print this help", help = true)
protected boolean printHelp = false;
public boolean processArgs(String[] args) {
@@ -139,7 +147,7 @@ public class JadxCLIArgs {
}
if (verbose) {
ch.qos.logback.classic.Logger rootLogger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
// remove INFO ThresholdFilter
Appender<ILoggingEvent> appender = rootLogger.getAppender("STDOUT");
if (appender != null) {
@@ -278,42 +286,42 @@ public class JadxCLIArgs {
}
public boolean isRenameCaseSensitive() {
return renameFlags.contains(RENAME.CASE);
return renameFlags.contains(RenameEnum.CASE);
}
public void setRenameCaseSensitive(boolean renameCase) {
if (renameCase && !isRenameCaseSensitive()) {
renameFlags.add(RENAME.CASE);
renameFlags.add(RenameEnum.CASE);
} else if (!renameCase && isRenameCaseSensitive()) {
renameFlags.remove(RENAME.CASE);
renameFlags.remove(RenameEnum.CASE);
}
}
public boolean isRenameValid() {
return renameFlags.contains(RENAME.VALID);
return renameFlags.contains(RenameEnum.VALID);
}
public void setRenameValid(boolean renameValid) {
if (renameValid && !isRenameValid()) {
renameFlags.add(RENAME.VALID);
renameFlags.add(RenameEnum.VALID);
} else if (!renameValid && isRenameValid()) {
renameFlags.remove(RENAME.VALID);
renameFlags.remove(RenameEnum.VALID);
}
}
public boolean isRenamePrintable() {
return renameFlags.contains(RENAME.PRINTABLE);
return renameFlags.contains(RenameEnum.PRINTABLE);
}
public void setRenamePrintable(boolean renamePrintable) {
if (renamePrintable && !isRenamePrintable()) {
renameFlags.add(RENAME.PRINTABLE);
renameFlags.add(RenameEnum.PRINTABLE);
} else if (!renamePrintable && isRenamePrintable()) {
renameFlags.remove(RENAME.PRINTABLE);
renameFlags.remove(RenameEnum.PRINTABLE);
}
}
static class RenameConverter implements IStringConverter<Set<RENAME>> {
static class RenameConverter implements IStringConverter<Set<RenameEnum>> {
private final String paramName;
@@ -322,23 +330,23 @@ public class JadxCLIArgs {
}
@Override
public Set<RENAME> convert(String value) {
Set<RENAME> set = new HashSet<>();
public Set<RenameEnum> convert(String value) {
Set<RenameEnum> set = new HashSet<>();
if (value.equalsIgnoreCase("ALL")) {
set.add(RENAME.CASE);
set.add(RENAME.VALID);
set.add(RENAME.PRINTABLE);
set.add(RenameEnum.CASE);
set.add(RenameEnum.VALID);
set.add(RenameEnum.PRINTABLE);
} else if (!value.equalsIgnoreCase("NONE")) {
for (String s : value.split(",")) {
try {
set.add(RENAME.valueOf(s.toUpperCase(Locale.ROOT)));
set.add(RenameEnum.valueOf(s.toUpperCase(Locale.ROOT)));
} catch (IllegalArgumentException e) {
String values = "'" + RENAME.CASE
+ "', '" + RENAME.VALID
+ "' and '" + RENAME.PRINTABLE + '\'';
String values = "'" + RenameEnum.CASE
+ "', '" + RenameEnum.VALID
+ "' and '" + RenameEnum.PRINTABLE + '\'';
throw new IllegalArgumentException(
s + " is unknown for parameter " + paramName
+ ", possible values are " + values.toLowerCase(Locale.ROOT));
+ ", possible values are " + values.toLowerCase(Locale.ROOT));
}
}
}
@@ -4,8 +4,8 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class JadxCLIArgsTest {
@@ -1,17 +1,17 @@
package jadx.cli;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jadx.api.JadxArgs.RENAME;
import jadx.api.JadxArgs.RenameEnum;
import jadx.cli.JadxCLIArgs.RenameConverter;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RenameConverterTest {
private RenameConverter converter;
@@ -23,16 +23,16 @@ public class RenameConverterTest {
@Test
public void all() {
Set<RENAME> set = converter.convert("all");
Set<RenameEnum> set = converter.convert("all");
assertEquals(3, set.size());
assertTrue(set.contains(RENAME.CASE));
assertTrue(set.contains(RENAME.VALID));
assertTrue(set.contains(RENAME.PRINTABLE));
assertTrue(set.contains(RenameEnum.CASE));
assertTrue(set.contains(RenameEnum.VALID));
assertTrue(set.contains(RenameEnum.PRINTABLE));
}
@Test
public void none() {
Set<RENAME> set = converter.convert("none");
Set<RenameEnum> set = converter.convert("none");
assertTrue(set.isEmpty());
}
-1
View File
@@ -21,4 +21,3 @@ dependencies {
testCompile 'com.google.guava:guava:27.1-jre'
testCompile 'com.beust:jcommander:1.74'
}
+41 -43
View File
@@ -50,9 +50,11 @@ public class JadxArgs {
private boolean fsCaseSensitive;
public enum RENAME {CASE, VALID, PRINTABLE}
public enum RenameEnum {
CASE, VALID, PRINTABLE
}
private Set<RENAME> renameFlags = EnumSet.allOf(RENAME.class);
private Set<RenameEnum> renameFlags = EnumSet.allOf(RenameEnum.class);
public JadxArgs() {
// use default options
@@ -261,66 +263,62 @@ public class JadxArgs {
}
public boolean isRenameCaseSensitive() {
return renameFlags.contains(RENAME.CASE);
return renameFlags.contains(RenameEnum.CASE);
}
public void setRenameCaseSensitive(boolean renameCaseSensitive) {
if (renameCaseSensitive && !isRenameCaseSensitive()) {
renameFlags.add(RENAME.CASE);
} else if (!renameCaseSensitive && isRenameCaseSensitive()) {
renameFlags.remove(RENAME.CASE);
}
updateRenameFlag(renameCaseSensitive, RenameEnum.CASE);
}
public boolean isRenameValid() {
return renameFlags.contains(RENAME.VALID);
return renameFlags.contains(RenameEnum.VALID);
}
public void setRenameValid(boolean renameValid) {
if (renameValid && !isRenameValid()) {
renameFlags.add(RENAME.VALID);
} else if (!renameValid && isRenameValid()) {
renameFlags.remove(RENAME.VALID);
}
updateRenameFlag(renameValid, RenameEnum.VALID);
}
public boolean isRenamePrintable() {
return renameFlags.contains(RENAME.PRINTABLE);
return renameFlags.contains(RenameEnum.PRINTABLE);
}
public void setRenamePrintable(boolean renamePrintable) {
if (renamePrintable && !isRenamePrintable()) {
renameFlags.add(RENAME.PRINTABLE);
} else if (!renamePrintable && isRenamePrintable()) {
renameFlags.remove(RENAME.PRINTABLE);
updateRenameFlag(renamePrintable, RenameEnum.PRINTABLE);
}
private void updateRenameFlag(boolean enabled, RenameEnum flag) {
if (enabled) {
renameFlags.add(flag);
} else {
renameFlags.remove(flag);
}
}
@Override
public String toString() {
return "JadxArgs{" + "inputFiles=" + inputFiles +
", outDir=" + outDir +
", outDirSrc=" + outDirSrc +
", outDirRes=" + outDirRes +
", threadsCount=" + threadsCount +
", cfgOutput=" + cfgOutput +
", rawCFGOutput=" + rawCFGOutput +
", fallbackMode=" + fallbackMode +
", showInconsistentCode=" + showInconsistentCode +
", useImports=" + useImports +
", skipResources=" + skipResources +
", skipSources=" + skipSources +
", deobfuscationOn=" + deobfuscationOn +
", deobfuscationForceSave=" + deobfuscationForceSave +
", useSourceNameAsClassAlias=" + useSourceNameAsClassAlias +
", deobfuscationMinLength=" + deobfuscationMinLength +
", deobfuscationMaxLength=" + deobfuscationMaxLength +
", escapeUnicode=" + escapeUnicode +
", replaceConsts=" + replaceConsts +
", respectBytecodeAccModifiers=" + respectBytecodeAccModifiers +
", exportAsGradleProject=" + exportAsGradleProject +
", fsCaseSensitive=" + fsCaseSensitive +
", renameFlags=" + renameFlags +
'}';
return "JadxArgs{" + "inputFiles=" + inputFiles
+ ", outDir=" + outDir
+ ", outDirSrc=" + outDirSrc
+ ", outDirRes=" + outDirRes
+ ", threadsCount=" + threadsCount
+ ", cfgOutput=" + cfgOutput
+ ", rawCFGOutput=" + rawCFGOutput
+ ", fallbackMode=" + fallbackMode
+ ", showInconsistentCode=" + showInconsistentCode
+ ", useImports=" + useImports
+ ", skipResources=" + skipResources
+ ", skipSources=" + skipSources
+ ", deobfuscationOn=" + deobfuscationOn
+ ", deobfuscationForceSave=" + deobfuscationForceSave
+ ", useSourceNameAsClassAlias=" + useSourceNameAsClassAlias
+ ", deobfuscationMinLength=" + deobfuscationMinLength
+ ", deobfuscationMaxLength=" + deobfuscationMaxLength
+ ", escapeUnicode=" + escapeUnicode
+ ", replaceConsts=" + replaceConsts
+ ", respectBytecodeAccModifiers=" + respectBytecodeAccModifiers
+ ", exportAsGradleProject=" + exportAsGradleProject
+ ", fsCaseSensitive=" + fsCaseSensitive
+ ", renameFlags=" + renameFlags
+ '}';
}
}
@@ -1,11 +1,8 @@
package jadx.api;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -15,20 +12,17 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.baksmali.Baksmali;
import org.jf.baksmali.BaksmaliOptions;
import org.jf.dexlib2.DexFileFactory;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.dexbacked.DexBackedClassDef;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.util.IndentingWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,15 +38,15 @@ import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.dex.visitors.SaveCode;
import jadx.core.export.ExportGradleProject;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.files.DexFile;
import jadx.core.utils.files.FileUtils;
import jadx.core.utils.files.InputFile;
import jadx.core.xmlgen.BinaryXMLParser;
import jadx.core.xmlgen.ResourcesSaver;
/**
* Jadx API usage example:
* <pre><code>
*
* <pre>
* <code>
* JadxArgs args = new JadxArgs();
* args.getInputFiles().add(new File("test.apk"));
* args.setOutDir(new File("jadx-test-output"));
@@ -60,14 +54,18 @@ import jadx.core.xmlgen.ResourcesSaver;
* JadxDecompiler jadx = new JadxDecompiler(args);
* jadx.load();
* jadx.save();
* </code></pre>
* </code>
* </pre>
* <p>
* Instead of 'save()' you can iterate over decompiled classes:
* <pre><code>
*
* <pre>
* <code>
* for(JavaClass cls : jadx.getClasses()) {
* System.out.println(cls.getCode());
* }
* </code></pre>
* </code>
* </pre>
*/
public final class JadxDecompiler {
private static final Logger LOG = LoggerFactory.getLogger(JadxDecompiler.class);
@@ -90,7 +90,7 @@ public final class ResourcesLoader {
}
private static ResContainer loadContent(JadxDecompiler jadxRef, ResourceFile rf,
InputStream inputStream) throws IOException {
InputStream inputStream) throws IOException {
switch (rf.getType()) {
case MANIFEST:
case XML:
@@ -49,7 +49,9 @@ public class ClsSet {
private static final NClass[] EMPTY_NCLASS_ARRAY = new NClass[0];
private enum ARG_TYPE {WILDCARD, GENERIC, GENERIC_TYPE, OBJECT, ARRAY, PRIMITIVE}
private enum TypeEnum {
WILDCARD, GENERIC, GENERIC_TYPE, OBJECT, ARRAY, PRIMITIVE
}
private NClass[] classes;
@@ -97,12 +99,9 @@ public class ClsSet {
List<ArgType> args = new ArrayList<>();
boolean genericArg = false;
for (RegisterArg r: m.getArguments(false)) {
for (RegisterArg r : m.getArguments(false)) {
ArgType argType = r.getType();
if (argType.isGeneric()) {
args.add(argType);
genericArg = true;
} else if (argType.isGenericType()) {
if (argType.isGeneric() || argType.isGenericType()) {
args.add(argType);
genericArg = true;
} else {
@@ -121,8 +120,8 @@ public class ClsSet {
methods.add(new NMethod(
m.getMethodInfo().getShortId(),
args.isEmpty()
? new ArgType[0]
: args.toArray(new ArgType[args.size()]),
? new ArgType[0]
: args.toArray(new ArgType[args.size()]),
retType,
varArgs));
}
@@ -229,7 +228,7 @@ public class ClsSet {
out.writeByte(argCount);
// last argument first
for (int i = argTypes.length - 1; i >=0 ; i--) {
for (int i = argTypes.length - 1; i >= 0; i--) {
ArgType argType = argTypes[i];
if (argType != null) {
out.writeByte(i);
@@ -249,14 +248,14 @@ public class ClsSet {
private static void writeArgType(DataOutputStream out, ArgType argType, Map<String, NClass> names) throws IOException {
if (argType.getWildcardType() != null) {
out.writeByte(ARG_TYPE.WILDCARD.ordinal());
out.writeByte(TypeEnum.WILDCARD.ordinal());
int bounds = argType.getWildcardBounds();
out.writeByte(bounds);
if (bounds != 0) {
writeArgType(out, argType.getWildcardType(), names);
}
} else if (argType.isGeneric()) {
out.writeByte(ARG_TYPE.GENERIC.ordinal());
out.writeByte(TypeEnum.GENERIC.ordinal());
out.writeInt(names.get(argType.getObject()).getId());
ArgType[] types = argType.getGenericTypes();
if (types == null) {
@@ -268,16 +267,16 @@ public class ClsSet {
}
}
} else if (argType.isGenericType()) {
out.writeByte(ARG_TYPE.GENERIC_TYPE.ordinal());
out.writeByte(TypeEnum.GENERIC_TYPE.ordinal());
writeString(out, argType.getObject());
} else if (argType.isObject()) {
out.writeByte(ARG_TYPE.OBJECT.ordinal());
out.writeByte(TypeEnum.OBJECT.ordinal());
out.writeInt(names.get(argType.getObject()).getId());
} else if (argType.isArray()) {
out.writeByte(ARG_TYPE.ARRAY.ordinal());
out.writeByte(TypeEnum.ARRAY.ordinal());
writeArgType(out, argType.getArrayElement(), names);
} else if (argType.isPrimitive()) {
out.writeByte(ARG_TYPE.PRIMITIVE.ordinal());
out.writeByte(TypeEnum.PRIMITIVE.ordinal());
out.writeByte(argType.getPrimitiveType().getShortName().charAt(0));
} else {
throw new JadxRuntimeException("Cannot save type: " + argType);
@@ -367,7 +366,7 @@ public class ClsSet {
private ArgType readArgType(DataInputStream in) throws IOException {
int ordinal = in.readByte();
switch(ARG_TYPE.values()[ordinal]) {
switch (TypeEnum.values()[ordinal]) {
case WILDCARD:
int bounds = in.readByte();
return bounds == 0
@@ -394,25 +393,25 @@ public class ClsSet {
return ArgType.array(readArgType(in));
case PRIMITIVE:
int shortName = in.readByte();
switch(shortName) {
case 'Z':
return ArgType.BOOLEAN;
case 'C':
return ArgType.CHAR;
case 'B':
return ArgType.BYTE;
case 'S':
return ArgType.SHORT;
case 'I':
return ArgType.INT;
case 'F':
return ArgType.FLOAT;
case 'J':
return ArgType.LONG;
case 'D':
return ArgType.DOUBLE;
default:
return ArgType.VOID;
switch (shortName) {
case 'Z':
return ArgType.BOOLEAN;
case 'C':
return ArgType.CHAR;
case 'B':
return ArgType.BYTE;
case 'S':
return ArgType.SHORT;
case 'I':
return ArgType.INT;
case 'F':
return ArgType.FLOAT;
case 'J':
return ArgType.LONG;
case 'D':
return ArgType.DOUBLE;
default:
return ArgType.VOID;
}
default:
throw new JadxRuntimeException("Unsupported Arg Type: " + ordinal);
@@ -84,7 +84,7 @@ public class AnnotationGen {
Map<String, Object> vl = a.getValues();
if (!vl.isEmpty()) {
code.add('(');
for (Iterator<Entry<String, Object>> it = vl.entrySet().iterator(); it.hasNext(); ) {
for (Iterator<Entry<String, Object>> it = vl.entrySet().iterator(); it.hasNext();) {
Entry<String, Object> e = it.next();
String paramName = getParamName(annCls, e.getKey());
if (paramName.equals("value") && vl.size() == 1) {
@@ -119,7 +119,7 @@ public class AnnotationGen {
if (an != null) {
Object exs = an.getDefaultValue();
code.add(" throws ");
for (Iterator<ArgType> it = ((List<ArgType>) exs).iterator(); it.hasNext(); ) {
for (Iterator<ArgType> it = ((List<ArgType>) exs).iterator(); it.hasNext();) {
ArgType ex = it.next();
classGen.useType(code, ex);
if (it.hasNext()) {
@@ -162,7 +162,7 @@ public class ClassGen {
} else {
clsCode.add("implements ");
}
for (Iterator<ArgType> it = cls.getInterfaces().iterator(); it.hasNext(); ) {
for (Iterator<ArgType> it = cls.getInterfaces().iterator(); it.hasNext();) {
ArgType interf = it.next();
useClass(clsCode, interf);
if (it.hasNext()) {
@@ -194,7 +194,7 @@ public class ClassGen {
}
if (list != null && !list.isEmpty()) {
code.add(" extends ");
for (Iterator<ArgType> it = list.iterator(); it.hasNext(); ) {
for (Iterator<ArgType> it = list.iterator(); it.hasNext();) {
ArgType g = it.next();
if (g.isGenericType()) {
code.add(g.getObject());
@@ -345,7 +345,7 @@ public class ClassGen {
List<String> warns = node.getAll(AType.JADX_WARN);
if (!warns.isEmpty()) {
warns.stream().distinct().sorted()
.forEach(warn -> code.startLine("/* JADX WARNING: ").addMultiLine(warn).add(" */"));
.forEach(warn -> code.startLine("/* JADX WARNING: ").addMultiLine(warn).add(" */"));
}
}
@@ -399,7 +399,7 @@ public class ClassGen {
return;
}
InsnGen igen = null;
for (Iterator<EnumField> it = enumFields.getFields().iterator(); it.hasNext(); ) {
for (Iterator<EnumField> it = enumFields.getFields().iterator(); it.hasNext();) {
EnumField f = it.next();
code.startLine(f.getField().getAlias());
ConstructorInsn constrInsn = f.getConstrInsn();
@@ -1,7 +1,5 @@
package jadx.core.codegen;
import static jadx.core.utils.android.AndroidResourcesUtils.handleAppResField;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
@@ -56,6 +54,8 @@ import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.CodegenException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.utils.android.AndroidResourcesUtils.handleAppResField;
public class InsnGen {
private static final Logger LOG = LoggerFactory.getLogger(InsnGen.class);
@@ -234,8 +234,8 @@ public class InsnGen {
code.add(';');
}
}
} catch (Exception th) {
throw new CodegenException(mth, "Error generate insn: " + insn, th);
} catch (Exception e) {
throw new CodegenException(mth, "Error generate insn: " + insn, e);
}
}
@@ -416,7 +416,7 @@ public class InsnGen {
if (wrap) {
code.add('(');
}
for (Iterator<InsnArg> it = insn.getArguments().iterator(); it.hasNext(); ) {
for (Iterator<InsnArg> it = insn.getArguments().iterator(); it.hasNext();) {
addArg(code, it.next());
if (it.hasNext()) {
code.add(" + ");
@@ -701,7 +701,7 @@ public class InsnGen {
}
void generateMethodArguments(CodeWriter code, InsnNode insn, int startArgNum,
@Nullable MethodNode callMth) throws CodegenException {
@Nullable MethodNode callMth) throws CodegenException {
int k = startArgNum;
if (callMth != null && callMth.contains(AFlag.SKIP_FIRST_ARG)) {
k++;
@@ -3,10 +3,11 @@ package jadx.core.codegen;
import java.util.Iterator;
import java.util.List;
import com.android.dx.rop.code.AccessFlags;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.android.dx.rop.code.AccessFlags;
import jadx.core.Consts;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
@@ -50,8 +50,7 @@ public class NameGen {
"java.lang.Long", "l",
"java.lang.Double", "d",
"java.lang.StringBuilder", "sb",
"java.lang.Exception", "exc"
);
"java.lang.Exception", "exc");
}
public NameGen(MethodNode mth, boolean fallback) {
@@ -1,7 +1,5 @@
package jadx.core.deobf;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
@@ -19,6 +17,8 @@ import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.info.MethodInfo;
import static java.nio.charset.StandardCharsets.UTF_8;
class DeobfPresets {
private static final Logger LOG = LoggerFactory.getLogger(DeobfPresets.class);
@@ -287,7 +287,8 @@ public class Deobfuscator {
*
* @param fullPkgName full package name
* @param create if {@code true} then will create all absent objects
* @return package node object or {@code null} if no package found and <b>create</b> set to {@code false}
* @return package node object or {@code null} if no package found and <b>create</b> set to
* {@code false}
*/
private PackageNode getPackageNode(String fullPkgName, boolean create) {
if (fullPkgName.isEmpty() || fullPkgName.equals(CLASS_NAME_SEPARATOR)) {
@@ -69,9 +69,7 @@ public class NameMapper {
"try",
"void",
"volatile",
"while"
)
);
"while"));
public static boolean isReserved(String str) {
return RESERVED_NAMES.contains(str);
@@ -113,15 +111,19 @@ public class NameMapper {
/**
* Return modified string with removed:
* <p><ul>
* <li> not printable chars (including unicode)
* <li> chars not valid for java identifier part
* </ul><p>
* <p>
* <ul>
* <li>not printable chars (including unicode)
* <li>chars not valid for java identifier part
* </ul>
* <p>
* Note: this 'middle' method must be used with prefixed string:
* <p><ul>
* <li> can leave invalid chars for java identifier start (i.e numbers)
* <li> result not checked for reserved words
* </ul><p>
* <p>
* <ul>
* <li>can leave invalid chars for java identifier start (i.e numbers)
* <li>result not checked for reserved words
* </ul>
* <p>
*/
public static String removeInvalidCharsMiddle(String name) {
if (isValidIdentifier(name)) {
@@ -106,6 +106,7 @@ public final class ClassInfo implements Comparable<ClassInfo> {
this.alias = newAlias;
}
}
public boolean isRenamed() {
return alias != this;
}
@@ -120,14 +120,13 @@ public class InsnDecoder {
constStrInsn.setResult(InsnArg.reg(insn, 0, ArgType.STRING));
return constStrInsn;
case Opcodes.CONST_CLASS:
{
case Opcodes.CONST_CLASS: {
ArgType clsType = dex.getType(insn.getIndex());
InsnNode constClsInsn = new ConstClassNode(clsType);
constClsInsn.setResult(
InsnArg.reg(insn, 0, ArgType.generic(Consts.CLASS_CLASS, clsType)));
return constClsInsn;
}
}
case Opcodes.MOVE:
case Opcodes.MOVE_16:
@@ -233,9 +233,9 @@ public abstract class ArgType {
/**
* Return wildcard bounds:
* <ul>
* <li> 1 for upper bound (? extends A) </li>
* <li> 0 no bounds (?) </li>
* <li>-1 for lower bound (? super A) </li>
* <li>1 for upper bound (? extends A)</li>
* <li>0 no bounds (?)</li>
* <li>-1 for lower bound (? super A)</li>
* </ul>
*/
@Override
@@ -306,7 +306,7 @@ public abstract class ArgType {
}
private static final class ArrayArg extends KnownType {
private static final PrimitiveType[] ARRAY_POSSIBLES = new PrimitiveType[]{PrimitiveType.ARRAY};
private static final PrimitiveType[] ARRAY_POSSIBLES = new PrimitiveType[] { PrimitiveType.ARRAY };
private final ArgType arrayElement;
public ArrayArg(ArgType arrayElement) {
@@ -3,11 +3,12 @@ package jadx.core.dex.instructions.args;
import java.util.ArrayList;
import java.util.List;
import com.android.dx.io.instructions.DecodedInstruction;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.android.dx.io.instructions.DecodedInstruction;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.utils.InsnUtils;
@@ -1,7 +1,5 @@
package jadx.core.dex.nodes;
import static jadx.core.dex.nodes.ProcessState.UNLOADED;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -38,6 +36,8 @@ import jadx.core.dex.nodes.parser.StaticValuesParser;
import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.dex.nodes.ProcessState.UNLOADED;
public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
private static final Logger LOG = LoggerFactory.getLogger(ClassNode.class);
@@ -355,7 +355,8 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
/**
* Return first method by original short name
* Note: methods are not unique by name (class can have several methods with same name but different signature)
* Note: methods are not unique by name (class can have several methods with same name but different
* signature)
*/
@Nullable
public MethodNode searchMethodByShortName(String name) {
@@ -7,6 +7,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.android.dex.ClassData;
import com.android.dex.ClassData.Method;
import com.android.dex.ClassDef;
@@ -17,8 +20,6 @@ import com.android.dex.FieldId;
import com.android.dex.MethodId;
import com.android.dex.ProtoId;
import com.android.dex.TypeList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.info.FieldInfo;
@@ -8,4 +8,3 @@ public interface IDexNode {
RootNode root();
}
@@ -7,15 +7,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.android.dex.ClassData.Method;
import com.android.dex.Code;
import com.android.dex.Code.CatchHandler;
import com.android.dex.Code.Try;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.android.dex.ClassData.Method;
import com.android.dex.Code;
import com.android.dex.Code.CatchHandler;
import com.android.dex.Code.Try;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.JumpInfo;
@@ -154,7 +155,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
for (RegisterArg arg : list) {
if (arg.getRegNum() >= regsCount) {
throw new JadxRuntimeException("Incorrect register number in instruction: " + insnNode
+ ", expected to be less than " + regsCount);
+ ", expected to be less than " + regsCount);
}
}
}
@@ -234,26 +234,25 @@ public final class IfCondition {
if (arithOp == ArithOp.OR || arithOp == ArithOp.AND) {
IfOp ifOp = c.getInsn().getOp();
boolean isTrue = ifOp == IfOp.NE && lit == 0
|| ifOp == IfOp.EQ && lit == 1;
|| ifOp == IfOp.EQ && lit == 1;
IfOp op = isTrue ? IfOp.NE : IfOp.EQ;
Mode mode = isTrue && arithOp == ArithOp.OR ||
!isTrue && arithOp == ArithOp.AND ? Mode.OR : Mode.AND;
Mode mode = isTrue && arithOp == ArithOp.OR
|| !isTrue && arithOp == ArithOp.AND ? Mode.OR : Mode.AND;
IfNode if1 = new IfNode(op, -1, wrapInsn.getArg(0), LiteralArg.FALSE);
IfNode if2 = new IfNode(op, -1, wrapInsn.getArg(1), LiteralArg.FALSE);
return new IfCondition(mode,
Arrays.asList(new IfCondition(new Compare(if1)),
new IfCondition(new Compare(if2))));
Arrays.asList(new IfCondition(new Compare(if1)),
new IfCondition(new Compare(if2))));
}
}
break;
break;
default:
break;
default:
break;
}
return null;
}
@@ -300,7 +299,7 @@ public final class IfCondition {
String op = mode == Mode.OR ? " || " : " && ";
StringBuilder sb = new StringBuilder();
sb.append('(');
for (Iterator<IfCondition> it = args.iterator(); it.hasNext(); ) {
for (Iterator<IfCondition> it = args.iterator(); it.hasNext();) {
IfCondition arg = it.next();
sb.append(arg);
if (it.hasNext()) {
@@ -326,7 +325,7 @@ public final class IfCondition {
return false;
}
return Objects.equals(args, other.args)
&& Objects.equals(compare, other.compare);
&& Objects.equals(compare, other.compare);
}
@Override
@@ -24,7 +24,7 @@ public final class IfInfo {
}
private IfInfo(IfCondition condition, BlockNode thenBlock, BlockNode elseBlock,
Set<BlockNode> mergedBlocks, Set<BlockNode> skipBlocks) {
Set<BlockNode> mergedBlocks, Set<BlockNode> skipBlocks) {
this.condition = condition;
this.thenBlock = thenBlock;
this.elseBlock = elseBlock;
@@ -147,14 +147,14 @@ public class ExceptionHandler {
return false;
}
ExceptionHandler that = (ExceptionHandler) o;
return handleOffset == that.handleOffset &&
catchTypes.equals(that.catchTypes) &&
Objects.equals(tryBlock, that.tryBlock);
return handleOffset == that.handleOffset
&& catchTypes.equals(that.catchTypes)
&& Objects.equals(tryBlock, that.tryBlock);
}
@Override
public int hashCode() {
return Objects.hash(catchTypes, handleOffset /*, tryBlock*/);
return Objects.hash(catchTypes, handleOffset /* , tryBlock */);
}
public String catchTypeStr() {
@@ -53,7 +53,7 @@ public class TryCatchBlock {
}
public void removeHandler(MethodNode mth, ExceptionHandler handler) {
for (Iterator<ExceptionHandler> it = handlers.iterator(); it.hasNext(); ) {
for (Iterator<ExceptionHandler> it = handlers.iterator(); it.hasNext();) {
ExceptionHandler h = it.next();
if (h == handler) {
unbindHandler(h);
@@ -85,7 +85,7 @@ public class TryCatchBlock {
private void removeWholeBlock(MethodNode mth) {
// self destruction
for (Iterator<ExceptionHandler> it = handlers.iterator(); it.hasNext(); ) {
for (Iterator<ExceptionHandler> it = handlers.iterator(); it.hasNext();) {
ExceptionHandler h = it.next();
unbindHandler(h);
it.remove();
@@ -5,7 +5,7 @@ import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.utils.exceptions.JadxException;
public class AbstractVisitor implements IDexTreeVisitor {
public abstract class AbstractVisitor implements IDexTreeVisitor {
@Override
public void init(RootNode root) throws JadxException {
@@ -34,7 +34,7 @@ import jadx.core.utils.exceptions.JadxException;
@JadxVisitor(
name = "EnumVisitor",
desc = "Restore enum classes",
runAfter = {CodeShrinkVisitor.class, ModVisitor.class}
runAfter = { CodeShrinkVisitor.class, ModVisitor.class }
)
public class EnumVisitor extends AbstractVisitor {
@@ -59,8 +59,8 @@ public class MarkFinallyVisitor extends AbstractVisitor {
visitor.init(mth.root());
DepthTraversal.visit(visitor, mth);
}
} catch (Exception ee) {
LOG.error("Undo finally extract failed, mth: {}", mth, e);
} catch (Exception excInner) {
LOG.error("Undo finally extract failed, mth: {}", mth, excInner);
}
}
}
@@ -343,7 +343,7 @@ public class MarkFinallyVisitor extends AbstractVisitor {
return null;
}
// TODO: add additional slices checks
// and try to extract common part if found difference
// and try to extract common part if found difference
} else {
for (InsnNode finallyInsn : finallyInsns) {
finallySlice.addInsn(finallyInsn, finallyBlock);
@@ -369,7 +369,7 @@ public class MarkFinallyVisitor extends AbstractVisitor {
}
private static boolean checkBlocksTree(BlockNode dupBlock, BlockNode finallyBlock,
InsnsSlice dupSlice, FinallyExtractInfo extractInfo) {
InsnsSlice dupSlice, FinallyExtractInfo extractInfo) {
InsnsSlice finallySlice = extractInfo.getFinallyInsnsSlice();
List<BlockNode> finallyCS = finallyBlock.getCleanSuccessors();
@@ -1,7 +1,5 @@
package jadx.core.dex.visitors;
import static jadx.core.utils.BlockUtils.replaceInsn;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
@@ -48,6 +46,8 @@ import jadx.core.utils.InsnRemover;
import jadx.core.utils.InsnUtils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.utils.BlockUtils.replaceInsn;
/**
* Visitor for modify method instructions
* (remove, replace, process exception handlers)
@@ -168,8 +168,9 @@ public class ModVisitor extends AbstractVisitor {
IfCondition condition = IfCondition.fromIfNode(ifNode);
InsnArg zero = new LiteralArg(0, type);
InsnArg one = new LiteralArg(
type == ArgType.DOUBLE ? Double.doubleToLongBits(1) :
type == ArgType.FLOAT ? Float.floatToIntBits(1) : 1, type);
type == ArgType.DOUBLE ? Double.doubleToLongBits(1)
: type == ArgType.FLOAT ? Float.floatToIntBits(1) : 1,
type);
TernaryInsn ternary = new TernaryInsn(condition, insn.getResult(), one, zero);
replaceInsn(block, i, ternary);
}
@@ -325,8 +326,7 @@ public class ModVisitor extends AbstractVisitor {
if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
ErrorsCounter.methodWarn(mth,
"Incorrect type for fill-array insn " + InsnUtils.formatOffset(insn.getOffset())
+ ", element type: " + elType + ", insn element type: " + insnElementType
);
+ ", element type: " + elType + ", insn element type: " + insnElementType);
}
if (!elType.isTypeKnown()) {
LOG.warn("Unknown array element type: {} in mth: {}", elType, mth);
@@ -29,7 +29,7 @@ import jadx.core.utils.exceptions.JadxException;
@JadxVisitor(
name = "PrepareForCodeGen",
desc = "Prepare instructions for code generation pass",
runAfter = {CodeShrinkVisitor.class, ClassModifier.class, ProcessVariables.class}
runAfter = { CodeShrinkVisitor.class, ClassModifier.class, ProcessVariables.class }
)
public class PrepareForCodeGen extends AbstractVisitor {
@@ -70,8 +70,7 @@ public class PrepareForCodeGen extends AbstractVisitor {
break;
case MOVE:
// remove redundant moves:
// unused result and same args names (a = a;)
// remove redundant moves: unused result and same args names (a = a;)
RegisterArg result = insn.getResult();
if (result.getSVar().getUseCount() == 0
&& result.isNameEquals(insn.getArg(0))) {
@@ -32,8 +32,8 @@ import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.visitors.shrink.CodeShrinkVisitor;
import jadx.core.utils.InsnList;
import jadx.core.utils.InsnUtils;
import jadx.core.utils.InsnRemover;
import jadx.core.utils.InsnUtils;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxException;
@@ -92,7 +92,7 @@ public class ReSugarCode extends AbstractVisitor {
* Replace new array and sequence of array-put to new filled-array instruction.
*/
private static void processNewArray(MethodNode mth, NewArrayNode newArrayInsn,
List<InsnNode> instructions, InsnRemover remover) {
List<InsnNode> instructions, InsnRemover remover) {
InsnArg arrLenArg = newArrayInsn.getArg(0);
if (!arrLenArg.isLiteral()) {
return;
@@ -10,7 +10,8 @@ import jadx.core.utils.exceptions.JadxRuntimeException;
public class SaveCode {
private SaveCode() {}
private SaveCode() {
}
public static void save(File dir, JadxArgs args, ClassNode cls) {
if (cls.contains(AFlag.DONT_GENERATE)) {
@@ -231,11 +231,8 @@ public class SimplifyVisitor extends AbstractVisitor {
* Simplify chains of calls to StringBuilder#append() plus constructor of StringBuilder.
* Those chains are usually automatically generated by the Java compiler when you create String
* concatenations like <code>"text " + 1 + " text"</code>.
*
* @param mth
* @param insn
* @return
*/
@SuppressWarnings("InnerAssignment") // TODO
private static InsnNode convertInvoke(MethodNode mth, InvokeNode insn) {
MethodInfo callMth = insn.getCallMth();
@@ -246,42 +243,42 @@ public class SimplifyVisitor extends AbstractVisitor {
&& insn.getArg(0).isInsnWrap()) {
try {
List<InsnNode> chain = flattenInsnChain(insn);
int constrIndex = -1; //RAF
int constrIndex = -1; // RAF
// Case where new StringBuilder() is called with NO args (the entire
// string is created using .append() calls:
if (chain.size() > 1 && chain.get(0).getType() == InsnType.CONSTRUCTOR) {
constrIndex = 0;
} else if (chain.size() > 2 && chain.get(1).getType() == InsnType.CONSTRUCTOR) {
//RAF Case where the first string element is String arg to the
// RAF Case where the first string element is String arg to the
// new StringBuilder("xxx") constructor
constrIndex = 1;
} else if (chain.size() > 3 && chain.get(2).getType() == InsnType.CONSTRUCTOR) {
//RAF Case where the first string element is String.valueOf() arg
// RAF Case where the first string element is String.valueOf() arg
// to the new StringBuilder(String.valueOf(zzz)) constructor
constrIndex = 2;
}
if (constrIndex != -1) { // If we found a CONSTRUCTOR, is it a StringBuilder?
if (constrIndex != -1) { // If we found a CONSTRUCTOR, is it a StringBuilder?
ConstructorInsn constr = (ConstructorInsn) chain.get(constrIndex);
if (constr.getClassType().getFullName().equals(Consts.CLASS_STRING_BUILDER)) {
int len = chain.size();
int argInd = 1;
InsnNode concatInsn = new InsnNode(InsnType.STR_CONCAT, len - 1);
InsnNode argInsn;
if (constrIndex > 0) { // There was an arg to the StringBuilder constr
if (constrIndex > 0) { // There was an arg to the StringBuilder constr
InsnWrapArg iwa;
if (constrIndex == 2
&& (argInsn = chain.get(1)).getType() == InsnType.INVOKE
&& ((InvokeNode) argInsn).getCallMth().getName().compareTo("valueOf") == 0) {
// The argument of new StringBuilder() is a String.valueOf(chainElement0)
iwa = (InsnWrapArg) argInsn.getArg(0);
argInd = 3; // Cause for loop below to skip to after the constructor
argInd = 3; // Cause for loop below to skip to after the constructor
} else {
InsnNode firstNode = chain.get(0);
if (firstNode instanceof ConstStringNode) {
ConstStringNode csn = (ConstStringNode) firstNode;
iwa = new InsnWrapArg(csn);
argInd = 2; // Cause for loop below to skip to after the constructor
argInd = 2; // Cause for loop below to skip to after the constructor
} else {
return null;
}
@@ -289,7 +286,7 @@ public class SimplifyVisitor extends AbstractVisitor {
concatInsn.addArg(iwa);
}
for (; argInd < len; argInd++) { // Add the .append(xxx) arg string to concat
for (; argInd < len; argInd++) { // Add the .append(xxx) arg string to concat
InsnNode node = chain.get(argInd);
MethodInfo method = ((CallMthInterface) node).getCallMth();
if (!(node.getArgsCount() < 2 && method.isConstructor() || method.getName().equals("append"))) {
@@ -30,13 +30,12 @@ public class BlockSplitter extends AbstractVisitor {
// leave these instructions alone in block node
private static final Set<InsnType> SEPARATE_INSNS = EnumSet.of(
InsnType.RETURN,
InsnType.IF,
InsnType.SWITCH,
InsnType.MONITOR_ENTER,
InsnType.MONITOR_EXIT,
InsnType.THROW
);
InsnType.RETURN,
InsnType.IF,
InsnType.SWITCH,
InsnType.MONITOR_ENTER,
InsnType.MONITOR_EXIT,
InsnType.THROW);
public static boolean makeSeparate(InsnType insnType) {
return SEPARATE_INSNS.contains(insnType);
@@ -88,8 +87,8 @@ public class BlockSplitter extends AbstractVisitor {
if (prevInsn != null) {
InsnType type = prevInsn.getType();
if (type == InsnType.GOTO
|| type == InsnType.THROW
|| makeSeparate(type)) {
|| type == InsnType.THROW
|| makeSeparate(type)) {
if (type == InsnType.RETURN || type == InsnType.THROW) {
mth.addExitBlock(curBlock);
@@ -102,11 +101,11 @@ public class BlockSplitter extends AbstractVisitor {
startNew = true;
} else {
startNew = isSplitByJump(prevInsn, insn)
|| makeSeparate(insn.getType())
|| isDoWhile(blocksMap, curBlock, insn)
|| insn.contains(AType.EXC_HANDLER)
|| prevInsn.contains(AFlag.TRY_LEAVE)
|| prevInsn.getType() == InsnType.MOVE_EXCEPTION;
|| makeSeparate(insn.getType())
|| isDoWhile(blocksMap, curBlock, insn)
|| insn.contains(AType.EXC_HANDLER)
|| prevInsn.contains(AFlag.TRY_LEAVE)
|| prevInsn.getType() == InsnType.MOVE_EXCEPTION;
if (startNew) {
curBlock = connectNewBlock(mth, curBlock, insn.getOffset());
}
@@ -154,7 +153,7 @@ public class BlockSplitter extends AbstractVisitor {
* For try/catch make empty (splitter) block for connect handlers
*/
private static BlockNode insertSplitterBlock(MethodNode mth, Map<Integer, BlockNode> blocksMap,
BlockNode curBlock, InsnNode insn, boolean startNew) {
BlockNode curBlock, InsnNode insn, boolean startNew) {
BlockNode splitterBlock;
if (insn.getOffset() == 0 || startNew) {
splitterBlock = curBlock;
@@ -241,7 +240,7 @@ public class BlockSplitter extends AbstractVisitor {
}
private static void connectExceptionHandlers(BlockNode block, InsnNode insn,
Map<Integer, BlockNode> blocksMap) {
Map<Integer, BlockNode> blocksMap) {
CatchAttr catches = insn.get(AType.CATCH_BLOCK);
SplitterBlockAttr spl = block.get(AType.SPLITTER_BLOCK);
if (catches == null || spl == null) {
@@ -329,11 +328,9 @@ public class BlockSplitter extends AbstractVisitor {
}
static boolean removeEmptyDetachedBlocks(MethodNode mth) {
return mth.getBasicBlocks().removeIf(block ->
block.getInstructions().isEmpty()
&& block.getPredecessors().isEmpty()
&& block.getSuccessors().isEmpty()
);
return mth.getBasicBlocks().removeIf(block -> block.getInstructions().isEmpty()
&& block.getPredecessors().isEmpty()
&& block.getSuccessors().isEmpty());
}
private void removeJumpAttributes(InsnNode[] insnArr) {
@@ -357,7 +354,7 @@ public class BlockSplitter extends AbstractVisitor {
int insnsCount = toRemove.stream().mapToInt(block -> block.getInstructions().size()).sum();
mth.addAttr(AType.COMMENTS, "JADX INFO: unreachable blocks removed: " + toRemove.size()
+ ", instructions: " + insnsCount);
+ ", instructions: " + insnsCount);
}
}
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import com.android.dex.Dex.Section;
import jadx.core.dex.attributes.nodes.SourceFileAttr;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.DexNode;
@@ -105,7 +105,7 @@ public class IfRegionVisitor extends AbstractVisitor {
private static void moveReturnToThenBlock(MethodNode mth, IfRegion ifRegion) {
if (!mth.getReturnType().equals(ArgType.VOID)
&& hasSimpleReturnBlock(ifRegion.getElseRegion())
/*&& insnsCount(ifRegion.getThenRegion()) < 2*/) {
/* && insnsCount(ifRegion.getThenRegion()) < 2 */) {
invertIfRegion(ifRegion);
}
}
@@ -43,7 +43,7 @@ import jadx.core.utils.exceptions.JadxOverflowException;
@JadxVisitor(
name = "LoopRegionVisitor",
desc = "Convert 'while' loops to 'for' loops (indexed or for-each)",
runBefore = {ProcessVariables.class}
runBefore = ProcessVariables.class
)
public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor {
private static final Logger LOG = LoggerFactory.getLogger(LoopRegionVisitor.class);
@@ -136,7 +136,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
}
private static LoopType checkArrayForEach(MethodNode mth, LoopRegion loopRegion, InsnNode initInsn, InsnNode incrInsn,
IfCondition condition) {
IfCondition condition) {
if (!(incrInsn instanceof ArithNode)) {
return null;
}
@@ -512,7 +512,7 @@ public class RegionMaker {
}
private static boolean canInsertContinue(BlockNode pred, List<BlockNode> predecessors, BlockNode loopEnd,
Set<BlockNode> loopExitNodes) {
Set<BlockNode> loopExitNodes) {
if (!pred.contains(AFlag.SYNTHETIC)
|| BlockUtils.checkLastInsnType(pred, InsnType.CONTINUE)) {
return false;
@@ -604,7 +604,7 @@ public class RegionMaker {
* Traverse from monitor-enter thru successors and collect blocks contains monitor-exit
*/
private static void traverseMonitorExits(SynchronizedRegion region, InsnArg arg, BlockNode block, Set<BlockNode> exits,
Set<BlockNode> visited) {
Set<BlockNode> visited) {
visited.add(block);
for (InsnNode insn : block.getInstructions()) {
if (insn.getType() == InsnType.MONITOR_EXIT
@@ -881,7 +881,7 @@ public class RegionMaker {
}
private boolean isBadCasesOrder(Map<BlockNode, List<Object>> blocksMap,
Map<BlockNode, BlockNode> fallThroughCases) {
Map<BlockNode, BlockNode> fallThroughCases) {
BlockNode nextCaseBlock = null;
for (BlockNode caseBlock : blocksMap.keySet()) {
if (nextCaseBlock != null && !caseBlock.equals(nextCaseBlock)) {
@@ -893,7 +893,7 @@ public class RegionMaker {
}
private Map<BlockNode, List<Object>> reOrderSwitchCases(Map<BlockNode, List<Object>> blocksMap,
Map<BlockNode, BlockNode> fallThroughCases) {
Map<BlockNode, BlockNode> fallThroughCases) {
List<BlockNode> list = new ArrayList<>(blocksMap.size());
list.addAll(blocksMap.keySet());
list.sort((a, b) -> {
@@ -44,7 +44,7 @@ public class ProcessVariables extends AbstractVisitor {
return;
}
checkCodeVars(mth, codeVars);
// TODO: reduce code vars by name if debug info applied. Need checks for variable scopes before reduce
// TODO: reduce code vars by name if debug info applied (need checks for variable scopes)
// collect all variables usage
CollectUsageRegionVisitor usageCollector = new CollectUsageRegionVisitor();
@@ -42,9 +42,6 @@ public class UsePlace {
@Override
public String toString() {
return "UsePlace{" +
"region=" + region +
", block=" + block +
'}';
return "UsePlace{region=" + region + ", block=" + block + '}';
}
}
@@ -25,7 +25,7 @@ import jadx.core.utils.exceptions.JadxRuntimeException;
@JadxVisitor(
name = "CodeShrinkVisitor",
desc = "Inline variables for make code smaller",
runAfter = {ModVisitor.class}
runAfter = { ModVisitor.class }
)
public class CodeShrinkVisitor extends AbstractVisitor {
@@ -63,9 +63,9 @@ public class CodeShrinkVisitor extends AbstractVisitor {
ListIterator<RegisterArg> it = args.listIterator(args.size());
while (it.hasPrevious()) {
RegisterArg arg = it.previous();
// if (arg.getName() != null) {
// continue;
// }
// if (arg.getName() != null) {
// continue;
// }
SSAVar sVar = arg.getSVar();
// allow inline only one use arg
if (sVar == null
@@ -122,7 +122,7 @@ public class CodeShrinkVisitor extends AbstractVisitor {
}
private static boolean canMoveBetweenBlocks(InsnNode assignInsn, BlockNode assignBlock,
BlockNode useBlock, InsnNode useInsn) {
BlockNode useBlock, InsnNode useInsn) {
if (!BlockUtils.isPathExists(assignBlock, useBlock)) {
return false;
}
@@ -20,8 +20,7 @@ final class RenameState {
mth,
mth.getEnterBlock(),
new SSAVar[regsCount],
new int[regsCount]
);
new int[regsCount]);
for (RegisterArg arg : mth.getArguments(true)) {
SSAVar ssaVar = state.startVar(arg);
ssaVar.add(AFlag.METHOD_ARGUMENT);
@@ -34,8 +33,7 @@ final class RenameState {
state.mth,
block,
Arrays.copyOf(state.vars, state.vars.length),
state.versions
);
state.versions);
}
private RenameState(MethodNode mth, BlockNode block, SSAVar[] vars, int[] versions) {
@@ -213,7 +213,7 @@ public class SSATransform extends AbstractVisitor {
if (parentInsn != null
&& parentInsn.getResult() != null
&& parentInsn.contains(AFlag.TRY_LEAVE)
&& phi.removeArg(arg) /* TODO: fix registers removing*/) {
&& phi.removeArg(arg) /* TODO: fix registers removing */) {
argsCount--;
continue;
}
@@ -10,7 +10,6 @@ public final class TypeBoundConst implements ITypeBound {
private final ArgType type;
private final RegisterArg arg;
public TypeBoundConst(BoundEnum bound, ArgType type) {
this(bound, type, null);
}
@@ -45,8 +44,7 @@ public final class TypeBoundConst implements ITypeBound {
return false;
}
TypeBoundConst that = (TypeBoundConst) o;
return bound == that.bound &&
Objects.equals(type, that.type);
return bound == that.bound && Objects.equals(type, that.type);
}
@Override
@@ -59,7 +59,7 @@ public class TypeCompare {
// both arrays
return compareTypes(first.getArrayElement(), second.getArrayElement());
}
if (!firstKnown /*&& !secondKnown*/) {
if (!firstKnown /* && !secondKnown */) {
int variantLen = Integer.compare(first.getPossibleTypes().length, second.getPossibleTypes().length);
return variantLen > 0 ? WIDER : NARROW;
}
@@ -188,7 +188,7 @@ public class TypeCompare {
return NARROW_BY_GENERIC;
}
// TODO: fill extendTypes
// return CONFLICT;
// return CONFLICT;
return NARROW_BY_GENERIC;
}
@@ -42,12 +42,12 @@ import jadx.core.utils.BlockUtils;
import jadx.core.utils.Utils;
@JadxVisitor(
name = "Type Inference",
desc = "Calculate best types for SSA variables",
runAfter = {
SSATransform.class,
ConstInlineVisitor.class
}
name = "Type Inference",
desc = "Calculate best types for SSA variables",
runAfter = {
SSATransform.class,
ConstInlineVisitor.class
}
)
public final class TypeInferenceVisitor extends AbstractVisitor {
private static final Logger LOG = LoggerFactory.getLogger(TypeInferenceVisitor.class);
@@ -77,8 +77,8 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
for (SSAVar var : mth.getSVars()) {
ArgType type = var.getTypeInfo().getType();
if (!type.isTypeKnown()
&& !var.getAssign().isTypeImmutable()
&& !tryDeduceType(mth, var, type)) {
&& !var.getAssign().isTypeImmutable()
&& !tryDeduceType(mth, var, type)) {
resolved = false;
}
}
@@ -180,9 +180,9 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
private Optional<ArgType> selectBestTypeFromBounds(Set<ITypeBound> bounds) {
return bounds.stream()
.map(ITypeBound::getType)
.filter(Objects::nonNull)
.max(typeUpdate.getArgTypeComparator());
.map(ITypeBound::getType)
.filter(Objects::nonNull)
.max(typeUpdate.getArgTypeComparator());
}
private void attachBounds(SSAVar var) {
@@ -383,36 +383,36 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
private void processIncompatiblePrimitives(MethodNode mth, SSAVar var) {
if (var.getAssign().getType() == ArgType.BOOLEAN) {
for (ITypeBound bound : var.getTypeInfo().getBounds()) {
if (bound.getBound() == BoundEnum.USE
&& bound.getType().isPrimitive() && bound.getType() != ArgType.BOOLEAN) {
InsnNode insn = bound.getArg().getParentInsn();
if (insn.getType() == InsnType.CAST) {
continue;
};
for (ITypeBound bound : var.getTypeInfo().getBounds()) {
if (bound.getBound() == BoundEnum.USE
&& bound.getType().isPrimitive() && bound.getType() != ArgType.BOOLEAN) {
InsnNode insn = bound.getArg().getParentInsn();
if (insn.getType() == InsnType.CAST) {
continue;
}
IndexInsnNode castNode = new IndexInsnNode(InsnType.CAST, bound.getType(), 1);
castNode.addArg(bound.getArg());
castNode.setResult(InsnArg.reg(bound.getArg().getRegNum(), bound.getType()));
IndexInsnNode castNode = new IndexInsnNode(InsnType.CAST, bound.getType(), 1);
castNode.addArg(bound.getArg());
castNode.setResult(InsnArg.reg(bound.getArg().getRegNum(), bound.getType()));
SSAVar newVar = mth.makeNewSVar(castNode.getResult().getRegNum(), castNode.getResult());
CodeVar codeVar = new CodeVar();
codeVar.setType(bound.getType());
newVar.setCodeVar(codeVar);
newVar.getTypeInfo().setType(bound.getType());
SSAVar newVar = mth.makeNewSVar(castNode.getResult().getRegNum(), castNode.getResult());
CodeVar codeVar = new CodeVar();
codeVar.setType(bound.getType());
newVar.setCodeVar(codeVar);
newVar.getTypeInfo().setType(bound.getType());
for (int i = insn.getArgsCount() - 1; i >= 0; i--) {
if (insn.getArg(i) == bound.getArg()) {
insn.setArg(i, castNode.getResult().duplicate());
break;
}
}
for (int i = insn.getArgsCount() - 1; i >= 0; i--) {
if (insn.getArg(i) == bound.getArg()) {
insn.setArg(i, castNode.getResult().duplicate());
break;
}
}
BlockNode blockNode = BlockUtils.getBlockByInsn(mth, insn);
List<InsnNode> insnList = blockNode.getInstructions();
insnList.add(insnList.indexOf(insn), castNode);
}
}
BlockNode blockNode = BlockUtils.getBlockByInsn(mth, insn);
List<InsnNode> insnList = blockNode.getInstructions();
insnList.add(insnList.indexOf(insn), castNode);
}
}
}
}
}
@@ -27,9 +27,6 @@ public class TypeInfo {
@Override
public String toString() {
return "TypeInfo{" +
"type=" + type +
", bounds=" + bounds +
'}';
return "TypeInfo{type=" + type + ", bounds=" + bounds + '}';
}
}
@@ -48,7 +48,7 @@ public final class TypeUpdate {
if (candidateType == null) {
return REJECT;
}
if (!candidateType.isTypeKnown()/* && ssaVar.getTypeInfo().getType().isTypeKnown()*/) {
if (!candidateType.isTypeKnown()/* && ssaVar.getTypeInfo().getType().isTypeKnown() */) {
return REJECT;
}
@@ -23,8 +23,7 @@ public class ExportGradleProject {
private static final Set<String> IGNORE_CLS_NAMES = new HashSet<>(Arrays.asList(
"R",
"BuildConfig"
));
"BuildConfig"));
private final RootNode root;
private final File outDir;
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
public final class ImmutableList<E> implements List<E>, RandomAccess {
private final E[] arr;
@SuppressWarnings({"unchecked", "SuspiciousArrayCast"})
@SuppressWarnings({ "unchecked", "SuspiciousArrayCast" })
public ImmutableList(Collection<E> col) {
this((E[]) Objects.requireNonNull(col).toArray());
}
@@ -15,7 +15,7 @@ public final class InsnList implements Iterable<InsnNode> {
}
public static void remove(List<InsnNode> list, InsnNode insn) {
for (Iterator<InsnNode> iterator = list.iterator(); iterator.hasNext(); ) {
for (Iterator<InsnNode> iterator = list.iterator(); iterator.hasNext();) {
InsnNode next = iterator.next();
if (next == insn) {
iterator.remove();
@@ -1,10 +1,11 @@
package jadx.core.utils;
import com.android.dx.io.instructions.DecodedInstruction;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.android.dx.io.instructions.DecodedInstruction;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.info.FieldInfo;
import jadx.core.dex.instructions.ConstClassNode;
@@ -5,12 +5,13 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import com.android.dx.rop.code.AccessFlags;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.android.dx.rop.code.AccessFlags;
import jadx.core.codegen.ClassGen;
import jadx.core.codegen.CodeWriter;
import jadx.core.deobf.NameMapper;
@@ -103,8 +104,7 @@ public class AndroidResourcesUtils {
final String resTypeName = resource.getTypeName();
ClassNode typeCls = innerClsMap.computeIfAbsent(
resTypeName,
name -> addClassForResType(resCls, rClsExists, name)
);
name -> addClassForResType(resCls, rClsExists, name));
final String resName;
if ("style".equals(resTypeName)) {
resName = resource.getKeyName().replace('.', '_');
@@ -81,6 +81,7 @@ public class ExtDataInput extends DataInputDelegate {
* requested (this is similar to DataInputStream's wrapper).
*/
@Override
@SuppressWarnings("InnerAssignment")
public final int skipBytes(int n) throws IOException {
int total = 0;
int cur = 0;
@@ -16,7 +16,6 @@
package jadx.core.utils.android;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.DataInput;
@@ -24,6 +23,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import org.apache.commons.io.IOUtils;
import jadx.core.utils.exceptions.JadxException;
@@ -110,7 +111,7 @@ public class Res9patchStreamDecoder {
public final int[] yDivs;
public NinePatch(int padLeft, int padRight, int padTop, int padBottom,
int[] xDivs, int[] yDivs) {
int[] xDivs, int[] yDivs) {
this.padLeft = padLeft;
this.padRight = padRight;
this.padTop = padTop;
@@ -1,8 +1,5 @@
package jadx.core.utils.files;
import static jadx.core.utils.files.FileUtils.isApkFile;
import static jadx.core.utils.files.FileUtils.isZipDexFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -31,6 +28,9 @@ import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.utils.files.FileUtils.isApkFile;
import static jadx.core.utils.files.FileUtils.isZipDexFile;
public class InputFile {
private static final Logger LOG = LoggerFactory.getLogger(InputFile.class);
@@ -117,7 +117,7 @@ public class InputFile {
// we should consider the input file could contain only one single dex, multi-dex,
// or instantRun support dex for Android .apk files
String instantRunDexSuffix = "classes" + ext;
for (Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements(); ) {
for (Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements();) {
ZipEntry entry = e.nextElement();
if (!ZipSecurity.isValidZipEntry(entry)) {
continue;
@@ -39,27 +39,27 @@ public class JavaToDex {
public List<Path> convert(Path jar) throws JadxException {
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream errOut = new ByteArrayOutputStream()) {
ByteArrayOutputStream errOut = new ByteArrayOutputStream()) {
DxContext context = new DxContext(out, errOut);
Path dir = Files.createTempDirectory("jadx");
DxArgs args = new DxArgs(
context,
dir.toAbsolutePath().toString(),
new String[]{jar.toAbsolutePath().toString()});
new String[] { jar.toAbsolutePath().toString() });
int result = new Main(context).runDx(args);
dxErrors = errOut.toString(CHARSET_NAME);
if (result != 0) {
throw new JadxException("Java to dex conversion error, code: " + result);
}
List<Path> list = new ArrayList<>();
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir)) {
for (Path child : ds) {
list.add(child);
child.toFile().deleteOnExit();
}
}
dir.toFile().deleteOnExit();
return list;
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir)) {
for (Path child : ds) {
list.add(child);
child.toFile().deleteOnExit();
}
}
dir.toFile().deleteOnExit();
return list;
} catch (Exception e) {
throw new JadxException("dx exception: " + e.getMessage(), e);
}
@@ -13,7 +13,8 @@ public class ZipSecurity {
// size of uncompressed zip entry shouldn't be bigger of compressed in MAX_SIZE_DIFF times
private static final int MAX_SIZE_DIFF = 100;
private ZipSecurity() {}
private ZipSecurity() {
}
private static boolean isInSubDirectoryInternal(File baseDir, File canonFile) {
if (canonFile == null) {
@@ -20,16 +20,17 @@ import jadx.core.utils.StringUtils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.xmlgen.entry.ValuesParser;
/* TODO:
Don't die when error occurs
Check error cases, maybe checked const values are not always the same
Better error messages
What to do, when Binary XML Manifest is > size(int)?
Check for missing chunk size types
Implement missing data types
Use line numbers to recreate EXACT AndroidManifest
Check Element chunk size
*/
/*
* TODO:
* Don't die when error occurs
* Check error cases, maybe checked const values are not always the same
* Better error messages
* What to do, when Binary XML Manifest is > size(int)?
* Check for missing chunk size types
* Implement missing data types
* Use line numbers to recreate EXACT AndroidManifest
* Check Element chunk size
*/
@SuppressWarnings("unused")
public class BinaryXMLParser extends CommonBinaryParser {
@@ -74,8 +75,8 @@ public class BinaryXMLParser extends CommonBinaryParser {
for (Field f : rStyleCls.getFields()) {
styleMap.put(f.getInt(f.getType()), f.getName());
}
} catch (Exception th) {
LOG.error("Android R class loading failed", th);
} catch (Exception e) {
LOG.error("Android R class loading failed", e);
}
}
@@ -330,7 +331,7 @@ public class BinaryXMLParser extends CommonBinaryParser {
}
private String generateNameForNS(String attrUrl) {
for (int i = 1; ; i++) {
for (int i = 1;; i++) {
String attrName = "ns" + i;
if (!nsMap.containsValue(attrName) && !nsMapGenerated.contains(attrName)) {
nsMapGenerated.add(attrName);
@@ -369,7 +370,7 @@ public class BinaryXMLParser extends CommonBinaryParser {
}
private void decodeAttribute(int attributeNS, int attrValDataType, int attrValData,
String shortNsName, String attrName) {
String shortNsName, String attrName) {
if (attrValDataType == TYPE_REFERENCE) {
// reference custom processing
String name = styleMap.get(attrValData);
@@ -422,9 +423,9 @@ public class BinaryXMLParser extends CommonBinaryParser {
} else {
writer.startLine("</");
writer.attachSourceLine(endLineNumber);
// if (elementNS != -1) {
// writer.add(getString(elementNS)).add(':');
// }
// if (elementNS != -1) {
// writer.add(getString(elementNS)).add(':');
// }
writer.add(elemName).add('>');
}
isLastEnd = true;
@@ -443,8 +444,7 @@ public class BinaryXMLParser extends CommonBinaryParser {
String generated;
do {
generated = generateTagAttrName();
}
while (tagAttrDeobfNames.containsValue(generated));
} while (tagAttrDeobfNames.containsValue(generated));
tagAttrDeobfNames.put(originalName, generated);
return generated;
}
@@ -1,11 +1,12 @@
package jadx.core.xmlgen;
import javax.xml.parsers.DocumentBuilder;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
@@ -71,7 +71,7 @@ public class ParserConstants {
// ...end of integer flavors.
protected static final int TYPE_LAST_INT = 0x1f;
// Where the unit type information is. This gives us 16 possible
// Where the unit type information is. This gives us 16 possible
// types, as defined below.
protected static final int COMPLEX_UNIT_SHIFT = 0;
protected static final int COMPLEX_UNIT_MASK = 0xf;
@@ -95,7 +95,7 @@ public class ParserConstants {
protected static final int COMPLEX_UNIT_FRACTION_PARENT = 1;
// Where the radix information is, telling where the decimal place
// appears in the mantissa. This give us 4 possible fixed point
// appears in the mantissa. This give us 4 possible fixed point
// representations as defined below.
protected static final int COMPLEX_RADIX_SHIFT = 4;
protected static final int COMPLEX_RADIX_MASK = 0x3;
@@ -109,13 +109,13 @@ public class ParserConstants {
// The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
protected static final int COMPLEX_RADIX_0P23 = 3;
// Where the actual value is. This gives us 23 bits of
// precision. The top bit is the sign.
// Where the actual value is. This gives us 23 bits of
// precision. The top bit is the sign.
protected static final int COMPLEX_MANTISSA_SHIFT = 8;
protected static final int COMPLEX_MANTISSA_MASK = 0xffffff;
protected static final double MANTISSA_MULT = 1.0f / (1 << COMPLEX_MANTISSA_SHIFT);
protected static final double[] RADIX_MULTS = new double[]{
protected static final double[] RADIX_MULTS = new double[] {
1.0f * MANTISSA_MULT,
1.0f / (1 << 7) * MANTISSA_MULT,
1.0f / (1 << 15) * MANTISSA_MULT,
@@ -187,7 +187,7 @@ public class ParserConstants {
protected static final int ATTR_TYPE_REFERENCE = 1;
// Attribute holds a generic string.
protected static final int ATTR_TYPE_STRING = 1 << 1;
// Attribute holds an integer value. ATTR_MIN and ATTR_MIN can
// Attribute holds an integer value. ATTR_MIN and ATTR_MIN can
// optionally specify a constrained range of possible integer values.
protected static final int ATTR_TYPE_INTEGER = 1 << 2;
// Attribute holds a boolean integer.
@@ -200,10 +200,10 @@ public class ParserConstants {
protected static final int ATTR_TYPE_DIMENSION = 1 << 6;
// Attribute holds a fraction value, such as "20%".
protected static final int ATTR_TYPE_FRACTION = 1 << 7;
// Attribute holds an enumeration. The enumeration values are
// Attribute holds an enumeration. The enumeration values are
// supplied as additional entries in the map.
protected static final int ATTR_TYPE_ENUM = 1 << 16;
// Attribute holds a bitmaks of flags. The flag bit values are
// Attribute holds a bitmaks of flags. The flag bit values are
// supplied as additional entries in the map.
protected static final int ATTR_TYPE_FLAGS = 1 << 17;
@@ -80,7 +80,7 @@ public class ResTableParser extends CommonBinaryParser {
for (ResourceEntry ri : resStorage.getResources()) {
if (addedValues.add(ri.getTypeName() + '.' + ri.getKeyName())) {
String format = String.format("<public type=\"%s\" name=\"%s\" id=\"%s\" />",
ri.getTypeName(), ri.getKeyName(), ri.getId());
ri.getTypeName(), ri.getKeyName(), ri.getId());
writer.startLine(format);
}
}
@@ -101,7 +101,7 @@ public class ResTableParser extends CommonBinaryParser {
void decodeTableChunk() throws IOException {
is.checkInt16(RES_TABLE_TYPE, "Not a table chunk");
is.checkInt16(0x000c, "Unexpected table header size");
/*int size = */
/* int size = */
is.readInt32();
int pkgCount = is.readInt32();
@@ -167,7 +167,7 @@ public class ResTableParser extends CommonBinaryParser {
@SuppressWarnings("unused")
private void parseTypeSpecChunk() throws IOException {
is.checkInt16(0x0010, "Unexpected type spec header size");
/*int size = */
/* int size = */
is.readInt32();
int id = is.readInt8();
@@ -179,9 +179,9 @@ public class ResTableParser extends CommonBinaryParser {
}
private void parseTypeChunk(long start, PackageChunk pkg) throws IOException {
/*int headerSize = */
/* int headerSize = */
is.readInt16();
/*int size = */
/* int size = */
is.readInt32();
int id = is.readInt8();
@@ -221,7 +221,7 @@ public class ResTableParser extends CommonBinaryParser {
int resRef = pkg.getId() << 24 | typeId << 16 | entryId;
String typeName = pkg.getTypeStrings()[typeId - 1];
String keyName = pkg.getKeyStrings()[key];
if(keyName.isEmpty()) {
if (keyName.isEmpty()) {
keyName = "RES_" + resRef; // autogenerate key name
}
ResourceEntry ri = new ResourceEntry(resRef, pkg.getName(), typeName, keyName);
@@ -317,11 +317,11 @@ public class ResTableParser extends CommonBinaryParser {
is.skipToPos(start + size, "Config skip trailing bytes");
return new EntryConfig(mcc, mnc, language, country,
orientation, touchscreen, density, keyboard, navigation,
inputFlags, screenWidth, screenHeight, sdkVersion,
screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp,
screenHeightDp, localeScript, localeVariant, screenLayout2,
colorMode, false, size);
orientation, touchscreen, density, keyboard, navigation,
inputFlags, screenWidth, screenHeight, sdkVersion,
screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp,
screenHeightDp, localeScript, localeVariant, screenLayout2,
colorMode, false, size);
}
private char[] unpackLocaleOrRegion(byte in0, byte in1, char base) {
@@ -333,9 +333,9 @@ public class ResTableParser extends CommonBinaryParser {
// since this function handles languages & regions, we add the value(s) to the base char
// which is usually 'a' or '0' depending on language or region.
return new char[]{(char) (first + base), (char) (second + base), (char) (third + base)};
return new char[] { (char) (first + base), (char) (second + base), (char) (third + base) };
}
return new char[]{(char) in0, (char) in1};
return new char[] { (char) in0, (char) in1 };
}
private String readScriptOrVariantChar(int length) throws IOException {
@@ -22,8 +22,7 @@ public class ResXmlGen {
private static final Set<String> SKIP_RES_TYPES = new HashSet<>(Arrays.asList(
"layout",
"mipmap",
"id"
));
"id"));
private final ResourceStorage resStorage;
private final ValuesParser vp;
@@ -1,13 +1,11 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* 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.
@@ -37,7 +35,7 @@ import java.util.Arrays;
* @author Glenn Marcy, IBM
* @author Andy Clark, IBM
* @author Eric Ye, IBM
* @author Arnaud Le Hors, IBM
* @author Arnaud Le Hors, IBM
* @author Michael Glavassevich, IBM
* @author Rahul Srivastava, Sun Microsystems Inc.
* @version $Id: XMLChar.java 674378 2008-07-07 00:52:45Z mrglavas $
@@ -799,8 +797,8 @@ public class XMLChar {
* @param c The character to check.
*/
public static boolean isValid(int c) {
return (c < 0x10000 && (CHARS[c] & MASK_VALID) != 0) ||
(0x10000 <= c && c <= 0x10FFFF);
return (c < 0x10000 && (CHARS[c] & MASK_VALID) != 0)
|| (0x10000 <= c && c <= 0x10FFFF);
} // isValid(int):boolean
/**
@@ -818,8 +816,8 @@ public class XMLChar {
* @param c The character to check.
*/
public static boolean isContent(int c) {
return (c < 0x10000 && (CHARS[c] & MASK_CONTENT) != 0) ||
(0x10000 <= c && c <= 0x10FFFF);
return (c < 0x10000 && (CHARS[c] & MASK_CONTENT) != 0)
|| (0x10000 <= c && c <= 0x10FFFF);
} // isContent(int):boolean
/**
@@ -999,9 +997,9 @@ public class XMLChar {
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
for (int i = 1; i < length; i++) {
c = ianaEncoding.charAt(i);
if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
(c < '0' || c > '9') && c != '.' && c != '_' &&
c != '-') {
if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')
&& (c < '0' || c > '9') && c != '.' && c != '_'
&& c != '-') {
return false;
}
}
@@ -1026,9 +1024,9 @@ public class XMLChar {
if (length > 0) {
for (int i = 1; i < length; i++) {
char c = javaEncoding.charAt(i);
if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
(c < '0' || c > '9') && c != '.' && c != '_' &&
c != '-') {
if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')
&& (c < '0' || c > '9') && c != '.' && c != '_'
&& c != '-') {
return false;
}
}
@@ -1046,7 +1044,7 @@ public class XMLChar {
*
* @param value the string to be trimmed
* @return the given string with the space characters trimmed
* from both ends
* from both ends
*/
public static String trim(String value) {
int start;
@@ -11,12 +11,13 @@ import jadx.core.dex.nodes.RootNode;
* but were changed during deobfuscation
*/
public class XmlDeobf {
private static final Map<String, String> deobfMap = new HashMap<>();
private static final Map<String, String> DEOBF_MAP = new HashMap<>();
private XmlDeobf() {}
private XmlDeobf() {
}
public static String deobfClassName(RootNode rootNode, String potencialClassName,
String packageName) {
String packageName) {
if (packageName != null && potencialClassName.startsWith(".")) {
potencialClassName = packageName + potencialClassName;
@@ -25,17 +26,17 @@ public class XmlDeobf {
}
private static String getNewClassName(RootNode rootNode, String old) {
if (deobfMap.isEmpty()) {
if (DEOBF_MAP.isEmpty()) {
for (ClassNode classNode : rootNode.getClasses(true)) {
if (classNode.getAlias() != null) {
String oldName = classNode.getClassInfo().getFullName();
String newName = classNode.getAlias().getFullName();
if (!oldName.equals(newName)) {
deobfMap.put(oldName, newName);
DEOBF_MAP.put(oldName, newName);
}
}
}
}
return deobfMap.get(old);
return DEOBF_MAP.get(old);
}
}
@@ -7,7 +7,8 @@ public class XmlSecurity {
private static DocumentBuilderFactory secureDbf = null;
private XmlSecurity() {}
private XmlSecurity() {
}
public static DocumentBuilderFactory getSecureDbf() throws ParserConfigurationException {
synchronized (XmlSecurity.class) {
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jadx.core.xmlgen.entry;
import org.slf4j.Logger;
@@ -21,7 +22,8 @@ import org.slf4j.LoggerFactory;
/**
* Original source code can be found
* <a href="https://raw.githubusercontent.com/iBotPeaches/Apktool/master/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java">here</a>
* <a href=
* "https://raw.githubusercontent.com/iBotPeaches/Apktool/master/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResConfigFlags.java">here</a>
*/
public class EntryConfig {
@@ -64,13 +66,13 @@ public class EntryConfig {
private final int size;
public EntryConfig(short mcc, short mnc, char[] language,
char[] region, byte orientation,
byte touchscreen, int density, byte keyboard, byte navigation,
byte inputFlags, short screenWidth, short screenHeight,
short sdkVersion, byte screenLayout, byte uiMode,
short smallestScreenWidthDp, short screenWidthDp,
short screenHeightDp, char[] localeScript, char[] localeVariant,
byte screenLayout2, byte colorMode, boolean isInvalid, int size) {
char[] region, byte orientation,
byte touchscreen, int density, byte keyboard, byte navigation,
byte inputFlags, short screenWidth, short screenHeight,
short sdkVersion, byte screenLayout, byte uiMode,
short smallestScreenWidthDp, short screenWidthDp,
short screenHeightDp, char[] localeScript, char[] localeVariant,
byte screenLayout2, byte colorMode, boolean isInvalid, int size) {
if (orientation < 0 || orientation > 3) {
LOG.warn("Invalid orientation value: {}", orientation);
orientation = 0;
@@ -394,7 +396,8 @@ public class EntryConfig {
}
private short getNaturalSdkVersionRequirement() {
if ((uiMode & MASK_UI_MODE_TYPE) == UI_MODE_TYPE_VR_HEADSET || (colorMode & COLOR_WIDE_MASK) != 0 || ((colorMode & COLOR_HDR_MASK) != 0)) {
if ((uiMode & MASK_UI_MODE_TYPE) == UI_MODE_TYPE_VR_HEADSET || (colorMode & COLOR_WIDE_MASK) != 0
|| ((colorMode & COLOR_HDR_MASK) != 0)) {
return SDK_OREO;
}
if ((screenLayout2 & MASK_SCREENROUND) != 0) {
@@ -421,8 +424,8 @@ public class EntryConfig {
// check for old style non BCP47 tags
// allows values-xx-rXX, values-xx, values-xxx-rXX
// denies values-xxx, anything else
if (localeVariant == null && localeScript == null && (region[0] != '\00' || language[0] != '\00') &&
region.length != 3) {
if (localeVariant == null && localeScript == null && (region[0] != '\00' || language[0] != '\00')
&& region.length != 3) {
sb.append('-').append(language);
if (region[0] != '\00') {
sb.append("-r").append(region);
@@ -8,10 +8,13 @@ import java.lang.annotation.Target;
/**
* Indicates a test which is known to fail.
*
* <p>This would cause a failure to be considered as success and a success as failure,
* with the benefit of updating the related issue when it has been resolved even unintentionally.</p>
* <p>
* This would cause a failure to be considered as success and a success as failure,
* with the benefit of updating the related issue when it has been resolved even unintentionally.
* </p>
*
* <p>To have an effect, the test class must be annotated with:
* <p>
* To have an effect, the test class must be annotated with:
*
* <code>
* &#064;ExtendWith(NotYetImplementedExtension.class)
@@ -19,7 +22,7 @@ import java.lang.annotation.Target;
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Target({ ElementType.TYPE, ElementType.METHOD })
public @interface NotYetImplemented {
String value() default "";
}
@@ -1,8 +1,9 @@
package jadx.core.dex.info;
import com.android.dx.rop.code.AccessFlags;
import org.junit.jupiter.api.Test;
import com.android.dx.rop.code.AccessFlags;
import jadx.core.dex.info.AccessInfo.AFType;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -1,5 +1,25 @@
package jadx.tests.api;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.jar.JarOutputStream;
import org.junit.jupiter.api.BeforeEach;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.api.JadxInternalAccess;
@@ -19,25 +39,6 @@ import jadx.core.xmlgen.entry.ResourceEntry;
import jadx.tests.api.compiler.DynamicCompiler;
import jadx.tests.api.compiler.StaticCompiler;
import jadx.tests.api.utils.TestUtils;
import org.junit.jupiter.api.BeforeEach;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.jar.JarOutputStream;
import static jadx.core.utils.files.FileUtils.addFileToJar;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -60,8 +61,10 @@ public abstract class IntegrationTest extends TestUtils {
/**
* Run auto check method if defined:
*
* <pre>
* public void check() {}
* public void check() {
* }
* </pre>
*/
private static final String CHECK_METHOD_NAME = "check";
@@ -1,8 +1,9 @@
package jadx.tests.api.compiler;
import javax.tools.SimpleJavaFileObject;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
public class CharSequenceJavaFileObject extends SimpleJavaFileObject {
private CharSequence content;
@@ -1,13 +1,13 @@
package jadx.tests.api.compiler;
import java.security.SecureClassLoader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import java.io.IOException;
import java.security.SecureClassLoader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static javax.tools.JavaFileObject.Kind;
@@ -21,8 +21,7 @@ public class ClassFileManager extends ForwardingJavaFileManager<StandardJavaFile
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className,
Kind kind, FileObject sibling) throws IOException {
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) {
JavaClassObject clsObject = new JavaClassObject(className, kind);
classLoader.getClsMap().put(className, clsObject);
return clsObject;
@@ -1,12 +1,13 @@
package jadx.tests.api.compiler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1,11 +1,12 @@
package jadx.tests.api.compiler;
import javax.tools.SimpleJavaFileObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
public class JavaClassObject extends SimpleJavaFileObject {
protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();
@@ -1,16 +1,5 @@
package jadx.tests.api.compiler;
import jadx.core.utils.files.FileUtils;
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -20,11 +9,25 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import jadx.core.utils.files.FileUtils;
public class StaticCompiler {
private static final List<String> COMMON_ARGS = Arrays.asList("-source 1.8 -target 1.8".split(" "));
public static List<File> compile(List<File> files, File outDir, boolean includeDebugInfo, boolean useEclipseCompiler) throws IOException {
public static List<File> compile(List<File> files, File outDir, boolean includeDebugInfo, boolean useEclipseCompiler)
throws IOException {
JavaCompiler compiler;
if (useEclipseCompiler) {
compiler = new EclipseCompiler();
@@ -54,7 +54,7 @@ public abstract class BaseExternalTest extends IntegrationTest {
if (clsPatternStr == null) {
processAll(jadx);
// jadx.saveSources();
// jadx.saveSources();
} else {
processByPatterns(jadx, clsPatternStr, mthPatternStr);
}
@@ -161,8 +161,7 @@ public abstract class BaseExternalTest extends IntegrationTest {
LOG.info("Print method: {}\n{}\n{}\n{}", mth.getMethodInfo().getShortId(),
dashLine,
mthCode,
dashLine
);
dashLine);
}
}
}
@@ -48,7 +48,7 @@ class SignatureParserTest {
checkType("La/b/C<Ld/E<Lf/G;>;>;", generic("La/b/C;", generic("Ld/E;", object("Lf/G;"))));
checkType("La<TD;>.c;", genericInner(generic("La;", genericType("D")), "c", null));
checkType("La<TD;>.c/d;", genericInner(generic("La;", genericType("D")), "c.d", null));
checkType("La<Lb;>.c<TV;>;", genericInner(generic("La;", object("Lb;")), "c", new ArgType[]{genericType("V")}));
checkType("La<Lb;>.c<TV;>;", genericInner(generic("La;", object("Lb;")), "c", new ArgType[] { genericType("V") }));
}
@Test
@@ -13,6 +13,7 @@ class StringUtilsTest {
private StringUtils stringUtils;
@Test
@SuppressWarnings("AvoidEscapedUnicodeCharacters")
public void testStringUnescape() {
JadxArgs args = new JadxArgs();
args.setEscapeUnicode(true);
@@ -18,7 +18,7 @@ public class TestClassGen extends IntegrationTest {
public int test3();
}
public static abstract class A {
public abstract static class A {
public abstract int test2();
}
}
@@ -14,7 +14,7 @@ public class TestFloatValue extends IntegrationTest {
public static class TestCls {
public float[] method() {
float[] fa = {0.55f};
float[] fa = { 0.55f };
fa[0] /= 2;
return fa;
}
@@ -56,7 +56,8 @@ public class TestReturnWrapping extends IntegrationTest {
assertThat(code, containsString("return arg0 + 1;"));
// TODO: reduce code vars by name
// assertThat(code, containsString("return i > 128 ? arg0.toString() + ret.toString() : Integer.valueOf(i);"));
// assertThat(code, containsString("return i > 128 ? arg0.toString() + ret.toString() :
// Integer.valueOf(i);"));
assertThat(code, containsString("return i2 > 128 ? arg0.toString() + ret.toString() : Integer.valueOf(i2);"));
assertThat(code, containsString("return arg0 + 2;"));
@@ -12,18 +12,18 @@ import static org.hamcrest.MatcherAssert.assertThat;
public class TestStaticFieldsInit extends IntegrationTest {
public static class TestCls {
public static final String s1 = "1";
public static final String s2 = "12".substring(1);
public static final String s3 = null;
public static final String s4;
public static final String s5 = "5";
public static final String S1 = "1";
public static final String S2 = "12".substring(1);
public static final String S3 = null;
public static final String S4;
public static final String S5 = "5";
public static String s6 = "6";
static {
if (s5.equals("?")) {
s4 = "?";
if (S5.equals("?")) {
S4 = "?";
} else {
s4 = "4";
S4 = "4";
}
}
}
@@ -33,7 +33,7 @@ public class TestStaticFieldsInit extends IntegrationTest {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, not(containsString("public static final String s2 = null;")));
assertThat(code, containsString("public static final String s3 = null;"));
assertThat(code, not(containsString("public static final String S2 = null;")));
assertThat(code, containsString("public static final String S3 = null;"));
}
}
@@ -18,8 +18,8 @@ public class TestStringBuilderElimination2 extends IntegrationTest {
public static class TestCls1 {
public String test() {
return new StringBuilder("[init]").append("a1").append('c').append(2).append(0L).append(1.0f).
append(2.0d).append(true).toString();
return new StringBuilder("[init]").append("a1").append('c').append(2).append(0L).append(1.0f).append(2.0d).append(true)
.toString();
}
}
@@ -41,8 +41,7 @@ public class TestStringBuilderElimination2 extends IntegrationTest {
float f = 1.0f;
double d = 2.0d;
boolean b = true;
return new StringBuilder(sInit).append(s).append(c).append(i).append(l).append(f).
append(d).append(b).toString();
return new StringBuilder(sInit).append(s).append(c).append(i).append(l).append(f).append(d).append(b).toString();
}
}
@@ -39,8 +39,7 @@ public class TestWrongCode extends IntegrationTest {
assertThat(code, containsLines(2,
"if (a == 0) {",
"}",
"return a;"
));
"return a;"));
}
@Test
@@ -17,7 +17,7 @@ public class TestAnnotations2 extends IntegrationTest {
public static class TestCls {
@Target({ElementType.TYPE})
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface A {
int i();
@@ -56,12 +56,14 @@ public class TestAnnotationsMix extends IntegrationTest {
return Arrays.asList(a);
}
@MyAnnotation(name = "b",
@MyAnnotation(
name = "b",
num = 7,
cls = Exception.class,
doubles = {0.0, 1.1},
doubles = { 0.0, 1.1 },
value = 9.87f,
simple = @SimpleAnnotation(false))
simple = @SimpleAnnotation(false)
)
public static Object test(String[] a) {
return Arrays.asList(a);
}
@@ -20,7 +20,7 @@ public class TestAnnotationsRename extends IntegrationTest {
public static class TestCls {
@Target({ElementType.METHOD})
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface A {
int x();
@@ -18,7 +18,7 @@ public class TestAnnotationsRenameDef extends IntegrationTest {
public static class TestCls {
@Target({ElementType.METHOD})
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface A {
int value();
@@ -17,7 +17,7 @@ public class TestParamAnnotations extends IntegrationTest {
public static class TestCls {
@Target({ElementType.PARAMETER})
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public static @interface A {
int i() default 7;
@@ -1,14 +1,14 @@
package jadx.tests.integration.arith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import org.junit.jupiter.api.Test;
import jadx.NotYetImplemented;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
public class TestArith extends IntegrationTest {
public static class TestCls {
@@ -25,7 +25,8 @@ public class TestArith extends IntegrationTest {
return a;
}
private static void use(int i) {}
private static void use(int i) {
}
}
@Test
@@ -1,14 +1,14 @@
package jadx.tests.integration.arith;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.jupiter.api.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
public class TestArith2 extends IntegrationTest {
public static class TestCls {

Some files were not shown because too many files have changed in this diff Show More