diff --git a/base/base.iml b/base/base.iml
index 8a5781d6..9602528f 100644
--- a/base/base.iml
+++ b/base/base.iml
@@ -6,6 +6,9 @@
+
+
+
diff --git a/buildscripts/README b/buildscripts/README
index 68999793..8e7e3c36 100644
--- a/buildscripts/README
+++ b/buildscripts/README
@@ -3,25 +3,17 @@ ProGuard, Java class file shrinker, optimizer, obfuscator, and preverifier
This directory contains a number of alternative ways to build ProGuard:
-- build.sh: a shell script for GNU/Linux
-
- ./build.sh
-
-- makefile: a makefile for GNU/Linux
-
- make clean all
-
- build.gradle : a Gradle build file for all platforms
- gradle clean assemble
-
-- build.xml: an Ant build file for all platforms
-
- ant clean all
+ gradle clean assemble
- pom.xml: a Maven POM for building the Maven artifacts
- mvn clean package
+ mvn clean package
+
+- build.sh: a simple and fast shell script for GNU/Linux.
+
+ ./build.sh
Pick your favorite build tool and enjoy!
diff --git a/buildscripts/pom.xml b/buildscripts/pom.xml
index facc09ea..620bf85b 100644
--- a/buildscripts/pom.xml
+++ b/buildscripts/pom.xml
@@ -40,13 +40,13 @@
- SourceForge.net Tracker
- https://sourceforge.net/p/proguard/bugs/
+ Github Tracker
+ https://github.com/Guardsquare/proguard/issues
- https://hg.code.sf.net/p/proguard/code
- scm:hg:https://hg.code.sf.net/p/proguard/code
+ https://github.com/Guardsquare/proguard.git
+ scm:git:https://github.com/Guardsquare/proguard.git
@@ -65,6 +65,21 @@
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.0.1
+
+
+ attach-sources
+ package
+
+ jar
+
+
+
+
+
org.apache.maven.plugins
maven-compiler-plugin
@@ -74,6 +89,7 @@
1.8
+
org.apache.maven.plugins
maven-javadoc-plugin
@@ -97,20 +113,6 @@
-
- org.apache.maven.plugins
- maven-source-plugin
- 3.0.1
-
-
- attach-sources
- package
-
- jar
-
-
-
-
org.apache.maven.plugins
@@ -129,14 +131,6 @@
-
-
- sonatype-nexus-staging
- Nexus Release Repository
- https://oss.sonatype.org/service/local/staging/deploy/maven2
-
-
-
../core
../base
@@ -160,4 +154,12 @@
+
+
+
+ sonatype-nexus-staging
+ Nexus Release Repository
+ https://oss.sonatype.org/service/local/staging/deploy/maven2
+
+
diff --git a/core/build.sh b/core/build.sh
index d860e210..2f7970c6 100755
--- a/core/build.sh
+++ b/core/build.sh
@@ -4,7 +4,11 @@
cd $(dirname "$0")
-source ../buildscripts/functions.sh
+if [ -f ../buildscripts/functions.sh ]; then
+ source ../buildscripts/functions.sh
+else
+ source functions.sh
+fi
MAIN_CLASS=proguard.*
diff --git a/core/docs/md/analyzing.md b/core/docs/md/analyzing.md
new file mode 100644
index 00000000..63b82162
--- /dev/null
+++ b/core/docs/md/analyzing.md
@@ -0,0 +1,106 @@
+## Analyzing all instructions
+
+If you want to analyze bytecode, you'll probably want to visit specified
+instructions of specified code attributes of specified methods of specified
+classes. The visitor classes and filters quickly get you to the right place:
+
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new AllAttributeVisitor(
+ new AllInstructionVisitor(
+ new MyInstructionAnalyzer()))));
+
+You then only need to implement the visitor methods to analyze the
+instructions:
+
+ class MyInstructionAnalyzer
+ implements InstructionVisitor
+ {
+ public void visitSimpleInstruction(Clazz clazz, .....) ...
+ public void visitVariableInstruction(Clazz clazz, .....) ...
+ public void visitConstantInstruction(Clazz clazz, .....) ...
+ public void visitBranchInstruction(Clazz clazz, .....) ...
+ public void visitTableSwitchInstruction(Clazz clazz, .....) ...
+ public void visitLookUpSwitchInstruction(Clazz clazz, .....) ...
+ }
+
+The library already provides classes to analyze the code for you, finding
+branching information, performing partial evaluation, finding the control flow
+and data flow, etc, as introduced in the following sections.
+
+Complete example: EvaluateCode.java
+
+## Collecting basic branching information
+
+You can extract basic information about branches in a method with the class
+BranchTargetFinder. The results are defined at the instruction level: each
+instruction is properly labeled as a branch target, branch origin, exception
+handler, etc.
+
+ BranchTargetFinder branchTargetFinder =
+ new BranchTargetFinder();
+
+ branchTargetFinder.visitCodeAttribute(clazz, method, codeAttribute);
+
+ if (branchTargetFinder.isBranchOrigin(offset)) ...
+
+ if (branchTargetFinder.isBranchTarget(offset)) ...
+
+Complete example: ApplyPeepholeOptimizations.java
+
+## Basic control flow analysis
+
+You can extract a basic control flow graph of the instructions in a method
+with partial evaluation (often called abstract evaluation). The core class is
+PartialEvaluator. Its results are defined at the instruction level: each
+instruction is labeled with potential branch targets and branch origins.
+
+ ValueFactory valueFactory =
+ new BasicValueFactory();
+
+ PartialEvaluator partialEvaluator =
+ new PartialEvaluator(
+ new BasicInvocationUnit(valueFactory),
+ false);
+
+ partialEvaluator.visitCodeAttribute(clazz, method, codeAttribute);
+
+ InstructionOffsetValue branchOrigins = partialEvaluator.branchOrigins(offset));
+ InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset));
+
+Complete example: VisualizeControlFlow.java
+
+## Partial evaluation
+
+You can extract a lot more information from a method with the same
+PartialEvaluator, by tuning the precision of the partial evaluation with
+different value factories and different invocation units:
+
+- A ValueFactory defines the level of detail in representing values like
+ integers or reference types. The values can be very generic (any primitive
+ integer, a reference to any object) or more precise (the integer 42, or an
+ integer between 0 and 5, or a non-null reference to an instance of
+ java/lang/String).
+
+- An InvocationUnit defines the values returned from retrieved fields and
+ invoked methods. The values can again be very generic (any integer) or they
+ can also be values that were cached in prior evaluations of the code base.
+
+You can pass them to the PartialEvaluator, apply it to the code, and retrieve
+the results:
+
+ ValueFactory valueFactory =
+ new RangeValueFactory(
+ new ArrayReferenceValueFactory());
+
+ PartialEvaluator partialEvaluator =
+ new PartialEvaluator(
+ new BasicInvocationUnit(valueFactory),
+ false);
+
+ partialEvaluator.visitCodeAttribute(clazz, method, codeAttribute);
+
+ TracedStack stack = partialEvaluator.getStackAfter(offset);
+ Value value = stack.getTop(index);
+
+Complete example: EvaluateCode.java
diff --git a/core/docs/md/building.md b/core/docs/md/building.md
new file mode 100644
index 00000000..0329e405
--- /dev/null
+++ b/core/docs/md/building.md
@@ -0,0 +1,23 @@
+If you've downloaded the source code of the **ProGuard Core** library, you can
+build it in a number of ways:
+
+- build.gradle : a Gradle build file for all platforms.
+
+ gradle clean assemble
+
+- pom.xml: a Maven POM for all platforms.
+
+ mvn clean package
+
+- build.sh: a simple and fast shell script for GNU/Linux.
+
+ ./build.sh
+
+Once built, you can include the library and its dependencies in your own
+projects.
+
+You can also build the complete API documentation with
+
+ gradle javadoc
+
+You can then find the [API documentation](../api/index.html) in `docs/api`.
diff --git a/core/docs/md/creating.md b/core/docs/md/creating.md
new file mode 100644
index 00000000..035c554e
--- /dev/null
+++ b/core/docs/md/creating.md
@@ -0,0 +1,33 @@
+The easiest way to create a new class from scratch is with ClassBuilder. It
+provides a fluent API to add fields and methods. For example, to create a
+class that prints out "Hello, world!":
+
+ ProgramClass programClass =
+ new ClassBuilder(
+ VersionConstants.CLASS_VERSION_1_8,
+ AccessConstants.PUBLIC,
+ "HelloWorld",
+ ClassConstants.NAME_JAVA_LANG_OBJECT)
+
+ .addMethod(
+ AccessConstants.PUBLIC |
+ AccessConstants.STATIC,
+ "main",
+ "([Ljava/lang/String;)V",
+ 50,
+
+ code -> code
+ .getstatic("java/lang/System", "out", "Ljava/io/PrintStream;")
+ .ldc("Hello, world!")
+ .invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V")
+ .return_())
+
+ .getProgramClass();
+
+You can also use it to add fields and methods to an existing class:
+
+ ProgramClass programClass =
+ new ClassBuilder(existingClass)
+ .....
+
+Complete example: CreateHelloWorldClass.java
diff --git a/core/docs/md/downloads.md b/core/docs/md/downloads.md
new file mode 100644
index 00000000..36d8b51c
--- /dev/null
+++ b/core/docs/md/downloads.md
@@ -0,0 +1,18 @@
+The **ProGuard Core** library is distributed under the terms of the Apache
+License Version 2.0. Please consult the [license page](license.md) for more
+details.
+
+ProGuard Core is written in Java, so it requires a Java Runtime Environment
+(JRE 1.8 or higher).
+
+You can download the library in various forms:
+
+- [Pre-built artifacts](https://bintray.com/guardsquare/proguard) at JCenter
+- [Pre-built artifacts](https://search.maven.org/search?q=g:net.sf.proguard) at Maven Central
+- A [Git repository of the source code](https://github.com/Guardsquare/proguard-core) at Github
+
+You can find major releases, minor releases with important bug fixes, and
+beta releases with the latest new features and any less urgent bug fixes.
+
+If you're still working with an older version of the library, check out the
+[release notes](releasenotes.md), to see if you're missing something essential.
diff --git a/core/docs/md/editing.md b/core/docs/md/editing.md
new file mode 100644
index 00000000..a5006be1
--- /dev/null
+++ b/core/docs/md/editing.md
@@ -0,0 +1,62 @@
+## Editing classes
+
+You can edit existing classes with ClassEditor and related editors like
+InterfacesEditor, AttributesEditor, and ConstantPoolEditor.
+
+ ClassEditor classEditor =
+ new ClassEditor(targetClass);
+
+ classEditor.addField(field);
+
+ classEditor.addMethod(method);
+
+If you want to create and add new fields or methods from scratch, you can use
+the more convenient ClassBuilder:
+
+ ProgramClass programClass =
+ new ClassBuilder(existingClass)
+ .addField(
+ AccessConstants.PUBLIC |
+ AccessConstants.STATIC,
+ "someField",
+ TypeConstants.INT);
+
+ .addMethod(
+ AccessConstants.PUBLIC |
+ AccessConstants.STATIC,
+ "main",
+ "([Ljava/lang/String;)V",
+ 50,
+
+ code -> code
+ .getstatic("java/lang/System", "out", "Ljava/io/PrintStream;")
+ .ldc("Hello, world!")
+ .invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V")
+ .return_())
+
+ .getProgramClass();
+
+## Editing code
+
+Perhaps more interestingly, you can edit the bytecode of method bodies with
+CodeAttributeEditor.
+
+ CodeAttributeEditor codeAttributeEditor =
+ new CodeAttributeEditor();
+
+ InstructionSequenceBuilder builder =
+ new InstructionSequenceBuilder(targetClass);
+
+ Instructions[] replacementInstructions = builder
+ .getstatic("java/lang/System", "out", "Ljava/io/
+ .ldc("Hello")
+ .invokevirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V" .instructions();
+
+ // Prepare the editor for this code.
+ codeAttributeEditor.reset(codeAttribute.u4codeLength);
+
+ // Insert the instruction sequence before a specified offset.
+ codeAttributeEditor.insertBeforeOffset(offset, replacementInstructions);
+
+ // Apply the changes.
+ codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
diff --git a/core/docs/md/img/core.png b/core/docs/md/img/core.png
new file mode 100644
index 00000000..1bdc14a4
Binary files /dev/null and b/core/docs/md/img/core.png differ
diff --git a/core/docs/md/img/guardsquare.png b/core/docs/md/img/guardsquare.png
new file mode 100644
index 00000000..0cb2529e
Binary files /dev/null and b/core/docs/md/img/guardsquare.png differ
diff --git a/core/docs/md/index.md b/core/docs/md/index.md
new file mode 100644
index 00000000..a20f67cb
--- /dev/null
+++ b/core/docs/md/index.md
@@ -0,0 +1,71 @@
+**ProGuard Core** is a free library to read, analyze, modify, and write Java
+class files. It is the core of the well-known shrinker, optimizer, and
+obfuscator [ProGuard](https://www.guardsquare.com/proguard) and of the
+[ProGuard Assembler and
+Disassembler](https://github.com/guardsquare/proguardassembler).
+
+Typical applications:
+
+- Perform peephole optimizations in Java bytecode.
+- Search for instruction patterns.
+- Analyze code with abstract evaluation.
+- Optimize and obfuscate, like ProGuard itself.
+
+## Design
+
+The library defines many small classes as the building blocks for applications
+that contain the processing logic. This is sometimes taken to the extreme: even
+loops and conditional statements can often be implemented as separate classes.
+Even though these classes are verbose and repetitive, the resulting main code
+becomes much more compact, flexible, and robust.
+
+### Data classes
+
+Basic data classes define the structures to represent Java bytecode. They
+reflect the Java bytecode specifications literally, to ensure that no data are
+lost when reading, analyzing, and writing them. The data classes contain only
+a minimum number of methods. They do have one or more accept methods to let
+the visitor classes below operate on them.
+
+### Visitor classes
+
+The library applies the visitor pattern extensively. Visitor classes define
+the operations on the data: reading, writing, editing, transforming,
+analyzing, etc. The visitor classes have one or more 'visit' methods to
+operate on data classes of the same basic type.
+
+For example, a Java bytecode class contains a constant pool with constants of
+different types: integer constants, float constants, string constants, etc.
+The data classes IntegerConstant, FloatConstant, StringConstant, etc. all
+implement the basic type Constant. The visitor interface ConstantVisitor
+contains methods 'visitIntegerConstant', 'visitFloatConstant',
+'visitStringConstant', etc. Implementations of this visitor interface can
+perform all kinds of operations on the constants.
+
+The reasoning behind this pattern is that the data classes are very stable,
+because they are directly based on the bytecode specifications. The operations
+are more dynamic, since they depend on the final application. It is
+practically impossible to add all possible operations in the data classes, but
+it is easy to add another implementation of a visitor interface. Implementing
+an interface in practice helps a lot to think of all possible cases.
+
+The visitor pattern uses visitor interfaces to operate on the similar elements
+of a data structure. Each interface often has many implementations. A great
+disadvantage at this time is that visitor methods can invoke one another
+(directly or indirectly), but they can't communicate easily. Since the
+implementations can't add their own parameters or return values, they often
+have to rely on fields to pass values back and forth. This is more
+error-prone. Still, the advantages of the visitor pattern outweigh the
+disadvantages.
+
+### Dependency injection
+
+The library classes heavily use _constructor-based dependency injection_, to
+create immutable instances. Notably the visitor classess are often like
+commands that are combined in an immutable structure, via constructors. You
+can execute such commands by applying the visitors to the data classes.
+
+## API
+
+You can find the complete API in the [ProGuard Core
+javadoc](../api/index.html).
diff --git a/core/docs/md/license.md b/core/docs/md/license.md
new file mode 100644
index 00000000..e65e8242
--- /dev/null
+++ b/core/docs/md/license.md
@@ -0,0 +1,180 @@
+The ProGuard Core library is licensed under the Apache License Version 2.0.
+
+Copyright 2002-2020 Guardsquare NV
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/core/docs/md/patternmatching.md b/core/docs/md/patternmatching.md
new file mode 100644
index 00000000..d94b25ee
--- /dev/null
+++ b/core/docs/md/patternmatching.md
@@ -0,0 +1,70 @@
+## Basic pattern matching
+
+The library has powerful support to match patterns in bytecode instruction
+sequences. You first define the pattern as a sequence of instructions, with
+wildcards. For example:
+
+ final int X = InstructionSequenceMatcher.X;
+ final int C = InstructionSequenceMatcher.C;
+
+ InstructionSequenceBuilder ____ =
+ new InstructionSequenceBuilder();
+
+ Instruction[] pattern =
+ ____.iload(X)
+ .bipush(C)
+ .istore(X).__();
+
+ Constant[] constants = ____.constants();
+
+You can then find that pattern in given code:
+
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new AllAttributeVisitor(
+ new AllInstructionVisitor(
+ new MyMatchPrinter(
+ new InstructionSequenceMatcher(constants, pattern))))));
+
+Complete example: ApplyPeepholeOptimizations.java
+
+## Replacing patterns
+
+Instead of just matching instruction sequences, you can also replace matched
+sequences by other instruction sequences, for example to optimize code or
+instrument code. The core classes are PeepholeEditor and
+InstructionSequenceReplacer. Say that you want to replace an instruction
+sequence "putstatic/getstatic" by an equivalent "dup/putstatic":
+
+ final int X = InstructionSequenceReplacer.X;
+
+ InstructionSequenceBuilder ____ =
+ new InstructionSequenceBuilder();
+
+ Instruction[][] replacements =
+ {
+ ____.putstatic(X)
+ .getstatic(X).__(),
+
+ ____.dup()
+ .putstatic(X).__()
+ };
+
+ Constant[] constants = ____.constants();
+
+ BranchTargetFinder branchTargetFinder = new BranchTargetFinder();
+ CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
+
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new AllAttributeVisitor(
+ new PeepholeEditor(branchTargetFinder, codeAttributeEditor,
+ new InstructionSequenceReplacer(constants,
+ replacements,
+ branchTargetFinder,
+ codeAttributeEditor)))));
+
+You can define multiple patterns and their respective replacements in one go,
+with the wrapper InstructionSequencesReplacer.
+
+Complete example: ApplyPeepholeOptimizations.java
diff --git a/core/docs/md/reading.md b/core/docs/md/reading.md
new file mode 100644
index 00000000..6018dca8
--- /dev/null
+++ b/core/docs/md/reading.md
@@ -0,0 +1,84 @@
+## Streaming classes from a jar file
+
+You can read classes from class files and various types of (nested) jar files
+or jmod files, with some convenient utility classes and visitors. For example,
+you can read the classes from a jar file and print them out in a streaming
+fashion, without collecting their representations:
+
+ DirectoryPump directoryPump =
+ new DirectoryPump(
+ new File(inputJarFileName));
+
+ directoryPump.pumpDataEntries(
+ new JarReader(
+ new ClassFilter(
+ new ClassReader(false, false, false, false, null,
+ new ClassPrinter()))));
+
+Note the constructor-based dependency injection of visitor classes. We
+typically use a slightly unconventional indentation to make this construct
+easy to read.
+
+Complete example: PrintClasses.java
+
+## Writing out streamed classes
+
+You can read classes, optionally perform some small modifications, and write
+them out right away, again in a streaming fashion.
+
+ JarWriter jarWriter =
+ new JarWriter(
+ new ZipWriter(
+ new FixedFileWriter(
+ new File(outputJarFileName))));
+
+ DirectoryPump directoryPump =
+ new DirectoryPump(
+ new File(inputJarFileName));
+
+ directoryPump.pumpDataEntries(
+ new JarReader(
+ new ClassFilter(
+ new ClassReader(false, false, false, false, null,
+ new DataEntryClassWriter(jarWriter)))));
+
+ jarWriter.close();
+
+Complete example: ApplyPeepholeOptimizations.java
+
+## Collecting classes
+
+Alternatively, you may want to collect the classes in a so-called class pool
+first, so you can perform more extensive analyses on them:
+
+ ClassPool classPool = new ClassPool();
+
+ DirectoryPump directoryPump =
+ new DirectoryPump(
+ new File(jarFileName));
+
+ directoryPump.pumpDataEntries(
+ new JarReader(false,
+ new ClassFilter(
+ new ClassReader(false, false, false, false, null,
+ new ClassPoolFiller(classPool)))));
+
+Complete example: Preverify.java
+
+## Writing out a set of classes
+
+If you've collected a set of classes in a class pool, you can write them out
+with the same visitors as before.
+
+ JarWriter jarWriter =
+ new JarWriter(
+ new ZipWriter(
+ new FixedFileWriter(
+ new File(outputJarFileName))));
+
+ classPool.classesAccept(
+ new DataEntryClassWriter(jarWriter));
+
+ jarWriter.close();
+
+Complete example: Preverify.java
diff --git a/core/docs/md/releasenotes.md b/core/docs/md/releasenotes.md
new file mode 100644
index 00000000..f0f4bee5
--- /dev/null
+++ b/core/docs/md/releasenotes.md
@@ -0,0 +1,5 @@
+## Version 7.0 (Jan 2020)
+
+| Version| Issue | Module | Explanation
+|--------|----------|----------|----------------------------------
+| 7.0.0 | | CORE | Initial release, extracted from ProGuard.
diff --git a/core/docs/mkdocs.yml b/core/docs/mkdocs.yml
new file mode 100644
index 00000000..ccc46cfc
--- /dev/null
+++ b/core/docs/mkdocs.yml
@@ -0,0 +1,70 @@
+###################################################################
+# Project information
+###################################################################
+site_name: ProGuard Core
+site_description: The ProGuard Core library
+site_author: Guardsquare NV
+copyright: Copyright © 2002-2020 Guardsquare NV
+
+###################################################################
+# Options
+###################################################################
+theme:
+ name: null
+ custom_dir: ../../buildscripts/mkdocs/material
+ logo: img/core.png
+ favicon: img/guardsquare.png
+ language: en
+ palette: blue
+ font:
+ feature:
+
+docs_dir: md
+site_dir: html
+
+#extra_css:
+# - extra.css
+
+use_directory_urls: false
+#strict: true # broken links are errors
+
+###################################################################
+# Theme specific
+###################################################################
+extra:
+ #font:
+ # text: 'Droid Sans'
+ # code: 'Ubuntu Mono'
+ social:
+ - type: 'twitter'
+ link: 'https://twitter.com/guardsquare'
+ - type: 'linkedin'
+ link: 'https://www.linkedin.com/company/guardsquare-nv'
+ - type: 'facebook'
+ link: 'https://www.facebook.com/guardsquare'
+ #feature:
+ # tabs: true
+
+###################################################################
+# Extensions
+###################################################################
+markdown_extensions:
+- attr_list
+- admonition
+- footnotes
+- def_list
+
+###################################################################
+# Page tree
+###################################################################
+nav:
+- Introduction: index.md
+- Reading classes: reading.md
+- Creating classes: creating.md
+- Editing classes: editing.md
+- Pattern matching: patternmatching.md
+- Analyzing code: analyzing.md
+- License: license.md
+- Downloads: downloads.md
+- Building: building.md
+- Release notes: releasenotes.md
diff --git a/core/functions.sh b/core/functions.sh
new file mode 100755
index 00000000..593ee57c
--- /dev/null
+++ b/core/functions.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+#
+# Support functions for building ProGuard.
+
+SRC=src
+OUT=out
+LIB=lib
+
+TARGET=1.8
+
+PROGUARD_JAR=$LIB/proguard.jar
+
+set -o pipefail
+
+function download {
+ if [ ! -f "$2" ]; then
+ echo "Downloading $2..."
+ mkdir -p $(dirname "$2") && \
+ if type wget > /dev/null 2>&1; then
+ wget -O "$2" "$1"
+ else
+ curl -L -o "$2" "$1"
+ fi
+ fi
+}
+
+function compile {
+ echo "Compiling $(basename $PWD) ($1)..."
+ mkdir -p "$OUT" && \
+
+ # Compile Java source files.
+ find $SRC -name '_*.java' -o -path "$SRC/${1//.//}.java" \
+ | xargs --no-run-if-empty \
+ javac -nowarn -Xlint:none \
+ -source $TARGET -target $TARGET \
+ -sourcepath "$SRC" -d "$OUT" \
+ ${2:+-classpath "$2"} 2>&1 \
+ | sed -e 's|^| |' || return 1
+
+ # Compile Kotlin source files.
+ #find $SRC -path "$SRC/${1//.//}.kotlin" \
+ #| xargs --no-run-if-empty \
+ # kotlinc -nowarn -jvm-target $TARGET \
+ # -d "$OUT" \
+ # ${2:+-classpath "$2"} 2>&1 \
+ #| sed -e 's|^| |' || return 1
+
+ # Compile Groovy source files.
+ find $SRC -path "$SRC/${1//.//}.groovy" \
+ | xargs --no-run-if-empty \
+ groovyc \
+ -sourcepath "$SRC" -d "$OUT" \
+ ${2:+-classpath "$2"} 2>&1 \
+ | sed -e 's|^| |' || return 1
+
+ # Copy resource files.
+ (cd "$SRC" && \
+ find proguard \
+ \( -name \*.properties -o -name \*.png -o -name \*.gif -o -name \*.pro \) \
+ -exec cp --parents {} "../$OUT" \; )
+}
+
+function createjar {
+ echo "Creating $1..."
+ mkdir -p $(dirname "$1") && \
+ if [ -f "$SRC/META-INF/MANIFEST.MF" ]; then
+ jar -cfm "$1" "$SRC/META-INF/MANIFEST.MF" -C "$OUT" proguard
+ else
+ jar -cf "$1" -C "$OUT" proguard
+ fi
+}
+
+function updatejar {
+ echo "Updating $1..."
+ if [ -f "$SRC/META-INF/MANIFEST.MF" ]; then
+ jar -ufm "$1" "$SRC/META-INF/MANIFEST.MF" -C "$OUT" proguard
+ else
+ jar -uf "$1" -C "$OUT" proguard
+ fi
+}
diff --git a/core/gradle.properties b/core/gradle.properties
index 608bcce4..4d5f07ce 100644
--- a/core/gradle.properties
+++ b/core/gradle.properties
@@ -2,5 +2,5 @@
target = 1.8
-kotlinVersion=1.3.31
-kotlinxMetadataVersion=0.1.0
+kotlinVersion = 1.3.31
+kotlinxMetadataVersion = 0.1.0
diff --git a/core/pom.xml b/core/pom.xml
index 1f96ea8b..26687553 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -1,40 +1,166 @@
-
+
4.0.0
-
- net.sf.proguard
- proguard-parent
- 6.2.2
- ../buildscripts/pom.xml
-
- proguard-base
+
+ net.sf.proguard
+ proguard-core
+ 7.0.0
[${project.groupId}] ${project.artifactId}
+ ProGuard Core is a free library to read, analyze, modify, and write Java class files.
+ https://github.com/Guardsquare/proguard-core
+
+
+ 3
+
+
+
+
+ lafortune
+ Eric Lafortune
+ https://www.guardsquare.com/proguard
+ Guardsquare
+ https://www.guardsquare.com/
+
+ Project Administrator
+ Developer
+
+
+
+
+
+
+ Apache License Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+
+ Github Tracker
+ https://github.com/Guardsquare/proguard-core/issues
+
+
+
+ https://github.com/Guardsquare/proguard-core.git
+ scm:git:https://github.com/Guardsquare/proguard-core.git
+
+
+
+ UTF-8
+
src
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.0.2
+
+
+
+
+ org.apache.maven.plugins
maven-source-plugin
+ 3.0.1
+
+
+ attach-sources
+ package
+
+ jar
+
+
+
+
+ org.apache.maven.plugins
maven-compiler-plugin
+ 3.5.1
+
+ 1.8
+ 1.8
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9.1
+
+
+ https://download.oracle.com/javase/1.5.0/docs/api/
+
+ true
+
+
+
+ attach-javadoc
+ package
+
+ jar
+
+
+ -Xdoclint:none
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy-dependencies
+ prepare-package
+
+ copy-dependencies
+
+
+ ${project.build.directory}
+ false
+ false
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
maven-jar-plugin
- proguard.ProGuard
+ true
+
- maven-javadoc-plugin
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
@@ -44,25 +170,31 @@
org.jetbrains.kotlin
kotlin-stdlib
1.3.31
- provided
org.jetbrains.kotlin
kotlin-stdlib-common
1.3.31
- provided
org.jetbrains.kotlinx
kotlinx-metadata-jvm
0.1.0
- provided
+
jcenter
https://jcenter.bintray.com
+
+
+
+ sonatype-nexus-staging
+ Nexus Release Repository
+ https://oss.sonatype.org/service/local/staging/deploy/maven2
+
+
diff --git a/docs/md/manual/retrace/usage.md b/docs/md/manual/retrace/usage.md
index f9742886..2c864198 100644
--- a/docs/md/manual/retrace/usage.md
+++ b/docs/md/manual/retrace/usage.md
@@ -1,8 +1,7 @@
You can find the ReTrace jar in the `lib` directory of the ProGuard
distribution. To run ReTrace, just type:
-`java -jar retrace.jar `\[*options...*\] *mapping\_file*
-\[*stacktrace\_file*\]
+ java -jar retrace.jar
Alternatively, the `bin` directory contains some short Linux and Windows
scripts containing this command. These are the arguments:
diff --git a/docs/md/manual/usage.md b/docs/md/manual/usage.md
index c015b241..f822eeda 100644
--- a/docs/md/manual/usage.md
+++ b/docs/md/manual/usage.md
@@ -1,16 +1,16 @@
To run ProGuard, just type:
-`bin/proguard `*options* ...
+ bin/proguard
Typically, you'll put most options in a configuration file (say,
`myconfig.pro`), and just call:
-`bin/proguard @myconfig.pro`
+ bin/proguard @myconfig.pro
You can combine command line options and options from configuration
files. For instance:
-`bin/proguard @myconfig.pro -verbose`
+ bin/proguard @myconfig.pro -verbose
You can add comments in a configuration file, starting with a `#`
character and continuing until the end of the line.
diff --git a/gui/gui.iml b/gui/gui.iml
index a4838090..ea4eee61 100644
--- a/gui/gui.iml
+++ b/gui/gui.iml
@@ -6,6 +6,9 @@
+
+
+
diff --git a/retrace/settings.gradle b/retrace/settings.gradle
index 429d0260..d003d95c 100644
--- a/retrace/settings.gradle
+++ b/retrace/settings.gradle
@@ -1,2 +1,2 @@
-includeFlat 'base'
+includeFlat 'core'
includeFlat 'base'