Skip to content

Commit

Permalink
Add more missing documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Hapstyx committed Nov 17, 2024
1 parent ce09349 commit 6e0a0fe
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ public SolutionMergingClassTransformer(String projectPrefix, String... available
this(new Builder(projectPrefix, availableSolutionClasses));
}

/**
* Constructs a new {@link SolutionMergingClassTransformer} instance with config settings from
* the given builder.
*
* @param builder the builder object
*/
@SuppressWarnings("unchecked")
private SolutionMergingClassTransformer(Builder builder) {
Map<String, SolutionClassNode> solutionClasses = new HashMap<>();
Expand Down Expand Up @@ -104,6 +110,9 @@ public void transform(ClassReader reader, ClassWriter writer) {
reader.accept(new SubmissionClassVisitor(writer, transformationContext, submissionClassName), 0);
}

/**
* (Internal) Configuration keys
*/
public enum Config {
PROJECT_PREFIX(null),
SOLUTION_CLASSES(null),
Expand All @@ -116,10 +125,19 @@ public enum Config {
}
}

/**
* Builder for {@link SolutionMergingClassTransformer}.
*/
public static class Builder {

private final Map<Config, Object> configuration = new EnumMap<>(Config.class);

/**
* Constructs a new {@link Builder}.
*
* @param projectPrefix the root package containing all submission classes, usually the sheet number
* @param solutionClasses the list of solution class names (fully qualified) to use
*/
public Builder(String projectPrefix, String... solutionClasses) {
for (Config config : Config.values()) {
configuration.put(config, config.defaultValue);
Expand All @@ -128,11 +146,22 @@ public Builder(String projectPrefix, String... solutionClasses) {
configuration.put(Config.SOLUTION_CLASSES, List.of(solutionClasses));
}

/**
* Sets the threshold for matching submission classes to solution classes via similarity matching.
*
* @param similarity the new similarity threshold
* @return the builder object
*/
public Builder setSimilarity(double similarity) {
configuration.put(Config.SIMILARITY, similarity);
return this;
}

/**
* Constructs the transformer.
*
* @return the configured {@link SolutionMergingClassTransformer} object
*/
public SolutionMergingClassTransformer build() {
return new SolutionMergingClassTransformer(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,37 @@
* </ul>
* All of these options can be enabled / disabled via {@link SubmissionExecutionHandler}.
*
* <br><br>
*
* Generally, the body of a transformed method would look like this in Java source code:
* <pre>
* SubmissionExecutionHandler.Internal submissionExecutionHandler = SubmissionExecutionHandler.getInstance().new Internal();
* MethodHeader methodHeader = new MethodHeader(...); // parameters are hardcoded during transformation
*
* if (submissionExecutionHandler.logInvocation(methodHeader)) {
* submissionExecutionHandler.addInvocation(new Invocation(...) // new Invocation() if constructor or static method
* .addParameter(...) // for each parameter
* ...);
* }
* if (submissionExecutionHandler.useSubstitution(methodHeader)) { // if not constructor
* submissionExecutionHandler.getSubstitution(methodHeader)
* .execute(new Invocation(...) ...); // same as above
* }
* if (submissionExecutionHandler.useSubmissionImpl(methodHeader)) {
* ... // submission code
* } else {
* ... // solution code
* }
* </pre>
* If no solution class is associated with the submission class, the submission code is executed unconditionally.
* <br>
* Additionally, the following methods are injected into the submission class:
* <pre>
* public static ClassHeader getOriginalClassHeader() {...}
* public static Set&lt;FieldHeader&gt; getOriginalFieldHeaders() {...}
* public static Set&lt;MethodHeader&gt; getOriginalMethodHeaders() {...}
* </pre>
*
* @see SubmissionExecutionHandler
* @author Daniel Mangold
*/
Expand Down Expand Up @@ -364,6 +395,7 @@ private void buildInvocation(Type[] argumentTypes) {
/**
* Adds all remaining fields and methods from the solution class that have not already
* been visited (e.g., lambdas).
* Injects methods for retrieving the original class, field and method headers during runtime.
*/
@Override
public void visitEnd() {
Expand All @@ -389,6 +421,10 @@ public void visitEnd() {
super.visitEnd();
}

/**
* Injects a static method {@code getOriginalClassHeader()} into the submission class.
* This injected method returns the original class header of the class pre-transformation.
*/
private void classMetadata() {
ClassHeader classHeader = submissionClassInfo.getOriginalClassHeader();
Label startLabel = new Label();
Expand All @@ -412,6 +448,10 @@ private void classMetadata() {
mv.visitMaxs(maxStack, 1);
}

/**
* Injects a static method {@code getOriginalFieldHeaders()} into the submission class.
* This injected method returns the set of original field headers of the class pre-transformation.
*/
private void fieldMetadata() {
Set<FieldHeader> fieldHeaders = submissionClassInfo.getOriginalFieldHeaders();
Label startLabel = new Label();
Expand Down Expand Up @@ -455,6 +495,10 @@ private void fieldMetadata() {
mv.visitMaxs(maxStack, 1);
}

/**
* Injects a static method {@code getOriginalMethodHeaders()} into the submission class.
* This injected method returns the set of original method headers of the class pre-transformation.
*/
private void methodMetadata() {
Set<MethodHeader> methodHeaders = submissionClassInfo.getOriginalMethodHeaders();
Label startLabel = new Label();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,20 @@ public record TransformationContext(
Map<String, SubmissionClassInfo> submissionClasses
) {

/**
* Returns the project prefix.
*
* @return the project prefix
*/
public String getProjectPrefix() {
return (String) configuration.get(SolutionMergingClassTransformer.Config.PROJECT_PREFIX);
}

/**
* Returns the minimum similarity threshold.
*
* @return the minimum similarity threshold
*/
public double getSimilarity() {
return (Double) configuration.get(SolutionMergingClassTransformer.Config.SIMILARITY);
}
Expand Down

0 comments on commit 6e0a0fe

Please sign in to comment.