001/* 002 * Hypo, an extensible and pluggable Java bytecode analytical model. 003 * 004 * Copyright (C) 2021 Kyle Wood (DemonWav) 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the Lesser GNU General Public License as published by 008 * the Free Software Foundation, version 3 of the License only. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <https://www.gnu.org/licenses/>. 017 */ 018 019package com.demonwav.hypo.core; 020 021import com.demonwav.hypo.model.ClassDataDecorator; 022import com.demonwav.hypo.model.ClassDataProvider; 023import com.google.errorprone.annotations.CanIgnoreReturnValue; 024import com.google.errorprone.annotations.Immutable; 025import java.util.function.Function; 026import org.jetbrains.annotations.Contract; 027import org.jetbrains.annotations.NotNull; 028 029/** 030 * Core global configuration for Hypo executions. 031 * 032 * <p>Create new instances of this class using {@link #builder()}. 033 */ 034@Immutable 035public final class HypoConfig { 036 037 private final int parallelism; 038 @SuppressWarnings("Immutable") 039 private final @NotNull Function<ClassDataProvider, ClassDataDecorator> decorator; 040 041 /** 042 * Create a new instance of {@link HypoConfig}. Use {@link #builder()} instead. 043 * 044 * @param parallelism The parallelism level to use for Hypo executions. 045 * @param decorator The decorator to use for {@link ClassDataProvider#setDecorator(ClassDataDecorator)}. 046 */ 047 HypoConfig( 048 final int parallelism, 049 final @NotNull Function<ClassDataProvider, ClassDataDecorator> decorator 050 ) { 051 this.parallelism = parallelism; 052 this.decorator = decorator; 053 } 054 055 /** 056 * Returns the parallelism level to use for Hypo executions. 057 * @return The parallelism level to use for Hypo executions. 058 */ 059 public int getParallelism() { 060 return this.parallelism; 061 } 062 063 /** 064 * Returns the {@link ClassDataDecorator decorator} constructor to use for 065 * {@link ClassDataProvider#setDecorator(ClassDataDecorator)}. 066 * 067 * @return The {@link ClassDataDecorator decorator} constructor to use. 068 */ 069 public @NotNull Function<ClassDataProvider, ClassDataDecorator> getDecorator() { 070 return this.decorator; 071 } 072 073 /** 074 * Create a new {@link Builder builder} for creating new instances of {@link HypoConfig}. 075 * 076 * @return A new {@link Builder} instance. 077 */ 078 @Contract(value = "-> new ", pure = true) 079 public static @NotNull Builder builder() { 080 return new Builder(); 081 } 082 083 /** 084 * Builder class for creating new instances of {@link HypoConfig}. Create new instances of this builder with 085 * {@link HypoConfig#builder()}. 086 * 087 * <p>This class is structured as the write-only version of {@link HypoConfig}, which is read-only. 088 */ 089 public static final class Builder { 090 091 private int parallelism = -1; 092 private @NotNull Function<ClassDataProvider, ClassDataDecorator> decorator = DefaultClassDataDecorator::new; 093 094 /** 095 * Constructor for {@link Builder}. Use {@link HypoConfig#builder()} instead. 096 */ 097 Builder() {} 098 099 /** 100 * Set the level of parallelism to use for Hypo executions. 101 * 102 * <p>Defaults to {@code -1}, which means to use {@link Runtime#availableProcessors()}. 103 * 104 * @param parallelism The level of parallelism to use for Hypo executions. 105 * @return {@code this} for chaining. 106 */ 107 @CanIgnoreReturnValue 108 @Contract(value = "_ -> this", mutates = "this") 109 public @NotNull Builder withParallelism(final int parallelism) { 110 this.parallelism = parallelism; 111 return this; 112 } 113 114 /** 115 * Set the {@link ClassDataDecorator decorator} constructor to use for 116 * {@link ClassDataProvider#setDecorator(ClassDataDecorator)}. 117 * 118 * <p>Defaults to {@link DefaultClassDataDecorator#DefaultClassDataDecorator(ClassDataProvider) 119 * DefaultClassDataDecorator::new}. 120 * 121 * @param decorator The {@link ClassDataDecorator decorator} constructor to use. 122 * @return {@code this} for chaining. 123 */ 124 @CanIgnoreReturnValue 125 @Contract(value = "_ -> this", mutates = "this") 126 public @NotNull Builder withDecorator( 127 final @NotNull Function<ClassDataProvider, ClassDataDecorator> decorator 128 ) { 129 this.decorator = decorator; 130 return this; 131 } 132 133 /** 134 * Use the current values of this builder to create a new instance of {@link HypoConfig} and return it. 135 * 136 * @return The new instance of {@link HypoConfig} using the value set in this builder. 137 */ 138 @CanIgnoreReturnValue 139 @Contract(value = "-> new", pure = true) 140 public @NotNull HypoConfig build() { 141 return new HypoConfig(this.parallelism, this.decorator); 142 } 143 } 144}