Skip to content

Commit

Permalink
codegen cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-manes committed Oct 18, 2021
1 parent 23645d5 commit c5e46c3
Show file tree
Hide file tree
Showing 32 changed files with 138 additions and 98 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ subprojects {
testImplementation testLibraries.truth
testImplementation testLibraries.mockito
testImplementation testLibraries.hamcrest
testImplementation testLibraries.slf4jTest
testImplementation testLibraries.awaitility
testImplementation testLibraries.osgiCompile

Expand Down
13 changes: 8 additions & 5 deletions caffeine/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ dependencies {
testImplementation testLibraries.jctools
testImplementation testLibraries.lincheck
testImplementation libraries.commonsLang3
testImplementation testLibraries.slf4jTest
testImplementation testLibraries.guavaTestLib

javaAgent libraries.jamm
Expand All @@ -68,13 +69,12 @@ dependencies {
}

tasks.named('compileCodeGenJava').configure {
gradle.taskGraph.whenReady {
enabled = gradle.taskGraph.hasTask(':caffeine:publishToSonatype')
}
onlyIf { System.env.'CI' }
dependsOn compileJava

doFirst {
options.compilerArgs += [ '--module-path', classpath.asPath ]
}
dependsOn compileJava
options.debug = false
options.incremental = false
destinationDirectory = compileJava.destinationDirectory
Expand All @@ -83,7 +83,6 @@ tasks.named('compileCodeGenJava').configure {

tasks.named('jar').configure {
dependsOn(compileCodeGenJava)

manifest {
attributes 'Bundle-SymbolicName': 'com.github.ben-manes.caffeine'
attributes 'Import-Package': ''
Expand Down Expand Up @@ -123,9 +122,13 @@ def generateNodes = tasks.register('generateNodes', JavaExec) {
}

tasks.named('compileJava').configure {
finalizedBy(compileCodeGenJava)
dependsOn(generateLocalCaches)
dependsOn(generateNodes)
}
tasks.named('compileTestJava').configure {
dependsOn(compileCodeGenJava)
}
tasks.named('sourcesJar').configure {
dependsOn(generateLocalCaches)
dependsOn(generateNodes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import com.google.common.base.CaseFormat;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;

/**
* The features that may be code generated.
Expand All @@ -46,8 +46,12 @@ public enum Feature {
LISTENING,
STATS;

private static final Set<Feature> fastPathIncompatible = Sets.immutableEnumSet(
Feature.EXPIRE_ACCESS, Feature.WEAK_KEYS, Feature.INFIRM_VALUES,
Feature.WEAK_VALUES, Feature.SOFT_VALUES);

public static String makeEnumName(Iterable<Feature> features) {
return StreamSupport.stream(features.spliterator(), false)
return Streams.stream(features)
.map(Feature::name)
.collect(Collectors.joining("_"));
}
Expand Down Expand Up @@ -110,8 +114,6 @@ public static boolean usesMaximum(Set<Feature> features) {
}

public static boolean usesFastPath(Set<Feature> features) {
Set<Feature> incompatible = Sets.immutableEnumSet(Feature.EXPIRE_ACCESS,
Feature.WEAK_KEYS, Feature.INFIRM_VALUES, Feature.WEAK_VALUES, Feature.SOFT_VALUES);
return features.stream().noneMatch(incompatible::contains) && usesMaximum(features);
return features.stream().noneMatch(fastPathIncompatible::contains) && usesMaximum(features);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
import com.github.benmanes.caffeine.cache.local.LocalCacheContext;
import com.github.benmanes.caffeine.cache.local.LocalCacheRule;
import com.google.common.base.CaseFormat;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
Expand Down Expand Up @@ -99,7 +98,7 @@ public final class LocalCacheFactoryGenerator {
final Feature[] featureByIndex = { null, null, Feature.LISTENING, Feature.STATS,
Feature.MAXIMUM_SIZE, Feature.MAXIMUM_WEIGHT, Feature.EXPIRE_ACCESS,
Feature.EXPIRE_WRITE, Feature.REFRESH_WRITE};
final List<LocalCacheRule> rules = ImmutableList.of(new AddSubtype(), new AddConstructor(),
final List<LocalCacheRule> rules = List.of(new AddSubtype(), new AddConstructor(),
new AddKeyValueStrength(), new AddRemovalListener(), new AddStats(),
new AddExpirationTicker(), new AddMaximum(), new AddFastPath(), new AddDeques(),
new AddExpireAfterAccess(), new AddExpireAfterWrite(), new AddRefreshAfterWrite(),
Expand Down Expand Up @@ -166,7 +165,7 @@ private void reformat() throws IOException {
List<Path> files = stream
.filter(path -> path.toString().endsWith(".java"))
.collect(toList());
Formatter formatter = new Formatter();
var formatter = new Formatter();
for (Path file : files) {
String source = Files.readString(file);
String formatted = formatter.formatSourceAndFixImports(source);
Expand All @@ -178,7 +177,7 @@ private void reformat() throws IOException {
}

private void addConstants() {
List<String> constants = ImmutableList.of("maximum", "windowMaximum", "mainProtectedMaximum",
var constants = List.of("maximum", "windowMaximum", "mainProtectedMaximum",
"weightedSize", "windowWeightedSize", "mainProtectedWeightedSize");
for (String constant : constants) {
String name = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, constant);
Expand All @@ -188,7 +187,7 @@ private void addConstants() {
.build());
}

constants = ImmutableList.of("key", "value", "accessTime", "writeTime");
constants = List.of("key", "value", "accessTime", "writeTime");
for (String constant : constants) {
String name = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, constant);
factory.addField(FieldSpec.builder(String.class, name)
Expand All @@ -212,7 +211,7 @@ private void generateLocalCaches() {
}

private NavigableMap<String, Set<Feature>> getClassNameToFeatures() {
NavigableMap<String, Set<Feature>> classNameToFeatures = new TreeMap<>();
var classNameToFeatures = new TreeMap<String, Set<Feature>>();
for (List<Object> combination : combinations()) {
Set<Feature> features = getFeatures(combination);
String className = encode(Feature.makeClassName(features));
Expand All @@ -222,7 +221,7 @@ private NavigableMap<String, Set<Feature>> getClassNameToFeatures() {
}

private Set<Feature> getFeatures(List<Object> combination) {
Set<Feature> features = new LinkedHashSet<>();
var features = new LinkedHashSet<Feature>();
features.add(((Boolean) combination.get(0)) ? Feature.STRONG_KEYS : Feature.WEAK_KEYS);
features.add(((Boolean) combination.get(1)) ? Feature.STRONG_VALUES : Feature.INFIRM_VALUES);
for (int i = 2; i < combination.size(); i++) {
Expand All @@ -237,8 +236,7 @@ private Set<Feature> getFeatures(List<Object> combination) {
}

private Set<List<Object>> combinations() {
Set<Boolean> options = ImmutableSet.of(true, false);
List<Set<Boolean>> sets = Collections.nCopies(featureByIndex.length, options);
List<Set<Boolean>> sets = Collections.nCopies(featureByIndex.length, Set.of(true, false));
return Sets.cartesianProduct(sets);
}

Expand All @@ -257,8 +255,8 @@ private TypeSpec makeLocalCacheSpec(String className, boolean isFinal, Set<Featu
encode(Feature.makeClassName(parentFeatures))), kTypeVar, vTypeVar);
}

LocalCacheContext context = new LocalCacheContext(
superClass, className, isFinal, parentFeatures, generateFeatures);
var context = new LocalCacheContext(superClass,
className, isFinal, parentFeatures, generateFeatures);
for (LocalCacheRule rule : rules) {
rule.accept(context);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public final class NodeFactoryGenerator {
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.build();

final List<NodeRule> rules = ImmutableList.of(new AddSubtype(), new AddConstructors(),
final List<NodeRule> rules = List.of(new AddSubtype(), new AddConstructors(),
new AddKey(), new AddValue(), new AddMaximum(), new AddExpiration(), new AddDeques(),
new AddFactoryMethods(), new AddHealth(), new Finalize());
final Feature[] featureByIndex = { null, null, Feature.EXPIRE_ACCESS, Feature.EXPIRE_WRITE,
Expand Down Expand Up @@ -166,7 +166,7 @@ private void reformat() throws IOException {
List<Path> files = stream
.filter(path -> path.toString().endsWith(".java"))
.collect(toList());
Formatter formatter = new Formatter();
var formatter = new Formatter();
for (Path file : files) {
String source = Files.readString(file);
String formatted = formatter.formatSourceAndFixImports(source);
Expand All @@ -184,7 +184,7 @@ private void addClassJavaDoc() {
}

private void addConstants() {
List<String> constants = ImmutableList.of("key", "value", "accessTime", "writeTime");
var constants = List.of("key", "value", "accessTime", "writeTime");
for (String constant : constants) {
String name = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, constant);
nodeFactory.addField(FieldSpec.builder(String.class, name)
Expand Down Expand Up @@ -246,8 +246,8 @@ private MethodSpec newLookupKeyMethod() {

private MethodSpec newReferenceKeyMethod() {
return MethodSpec.methodBuilder("newReferenceKey")
.addJavadoc("Returns a key suitable for inserting into the cache. If the cache holds"
+ " keys strongly then\nthe key is returned. If the cache holds keys weakly "
.addJavadoc("Returns a key suitable for inserting into the cache. If the cache holds "
+ "keys strongly then\nthe key is returned. If the cache holds keys weakly "
+ "then a {@link $T}\nholding the key argument is returned.\n", referenceKeyType)
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addParameter(kTypeVar, "key")
Expand Down Expand Up @@ -293,8 +293,7 @@ private void generatedNodes() {
}

private NavigableMap<String, Set<Feature>> getClassNameToFeatures() {
NavigableMap<String, Set<Feature>> classNameToFeatures = new TreeMap<>();

var classNameToFeatures = new TreeMap<String, Set<Feature>>();
for (List<Object> combination : combinations()) {
Set<Feature> features = getFeatures(combination);
String className = Feature.makeClassName(features);
Expand All @@ -304,7 +303,7 @@ private NavigableMap<String, Set<Feature>> getClassNameToFeatures() {
}

private Set<Feature> getFeatures(List<Object> combination) {
Set<Feature> features = new LinkedHashSet<>();
var features = new LinkedHashSet<Feature>();
features.add((Feature) combination.get(0));
features.add((Feature) combination.get(1));
for (int i = 2; i < combination.size(); i++) {
Expand Down Expand Up @@ -333,28 +332,24 @@ private TypeSpec makeNodeSpec(String className, boolean isFinal, Set<Feature> fe
encode(Feature.makeClassName(parentFeatures))), kTypeVar, vTypeVar);
}

NodeContext context = new NodeContext(superClass, className,
isFinal, parentFeatures, generateFeatures);
var context = new NodeContext(superClass, className, isFinal, parentFeatures, generateFeatures);
for (NodeRule rule : rules) {
rule.accept(context);
}
return context.nodeSubtype.build();
}

private Set<List<Object>> combinations() {
Set<Feature> keyStrengths = ImmutableSet.of(Feature.STRONG_KEYS, Feature.WEAK_KEYS);
Set<Feature> valueStrengths = ImmutableSet.of(
Feature.STRONG_VALUES, Feature.WEAK_VALUES, Feature.SOFT_VALUES);
Set<Boolean> expireAfterAccess = ImmutableSet.of(false, true);
Set<Boolean> expireAfterWrite = ImmutableSet.of(false, true);
Set<Boolean> refreshAfterWrite = ImmutableSet.of(false, true);
Set<Boolean> maximumSize = ImmutableSet.of(false, true);
Set<Boolean> weighed = ImmutableSet.of(false, true);

@SuppressWarnings("unchecked")
Set<List<Object>> combinations = Sets.cartesianProduct(keyStrengths, valueStrengths,
var keyStrengths = Set.of(Feature.STRONG_KEYS, Feature.WEAK_KEYS);
var valueStrengths = Set.of(Feature.STRONG_VALUES, Feature.WEAK_VALUES, Feature.SOFT_VALUES);
var expireAfterAccess = Set.of(false, true);
var expireAfterWrite = Set.of(false, true);
var refreshAfterWrite = Set.of(false, true);
var maximumSize = Set.of(false, true);
var weighed = Set.of(false, true);

return Sets.cartesianProduct(keyStrengths, valueStrengths,
expireAfterAccess, expireAfterWrite, refreshAfterWrite, maximumSize, weighed);
return combinations;
}

/** Returns an encoded form of the class name for compact use. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ protected boolean applies() {

@Override
protected void execute() {
String cacheLoader = context.superClass.equals(BOUNDED_LOCAL_CACHE)
? "(CacheLoader<K, V>) cacheLoader"
: "cacheLoader";
String cacheLoader;
if (context.superClass.equals(BOUNDED_LOCAL_CACHE)) {
cacheLoader = "(CacheLoader<K, V>) cacheLoader";
context.suppressedWarnings.add("unchecked");
} else {
cacheLoader = "cacheLoader";
}
context.constructor
.addParameter(BUILDER_PARAM)
.addParameter(CACHE_LOADER_PARAM)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ private void addAccessOrderWindowDeque() {
"this.$L = builder.evicts() || builder.expiresAfterAccess()\n? new $T()\n: null",
"accessOrderWindowDeque", ACCESS_ORDER_DEQUE);
addFieldAndMethod(ACCESS_ORDER_DEQUE, "accessOrderWindowDeque");
context.suppressedWarnings.add("NullAway");
}

private void addAccessOrderMainDeque() {
Expand All @@ -61,6 +62,7 @@ private void addAccessOrderMainDeque() {
}
addDeque(ACCESS_ORDER_DEQUE, "accessOrderProbationDeque");
addDeque(ACCESS_ORDER_DEQUE, "accessOrderProtectedDeque");
context.suppressedWarnings.add("NullAway");
}

private void addWriteOrderDeque() {
Expand All @@ -69,6 +71,7 @@ private void addWriteOrderDeque() {
return;
}
addDeque(WRITE_ORDER_DEQUE, "writeOrderDeque");
context.suppressedWarnings.add("NullAway");
}

private void addDeque(TypeName type, String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ protected boolean applies() {

@Override
protected void execute() {
context.suppressedWarnings.add("NullAway");
variableExpiration();
fixedExpiration();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ protected boolean applies() {

@Override
protected void execute() {
context.suppressedWarnings.add("NullAway");
context.cache.addField(
FieldSpec.builder(REMOVAL_LISTENER, "removalListener", Modifier.FINAL).build());
context.constructor.addStatement("this.removalListener = builder.getRemovalListener(async)");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import com.github.benmanes.caffeine.cache.Feature;
import com.google.common.base.CaseFormat;
import com.squareup.javapoet.AnnotationSpec;

/**
* Adds the cache inheritance hierarchy.
Expand All @@ -38,10 +37,8 @@ protected boolean applies() {

@Override
protected void execute() {
context.suppressedWarnings.add("MissingOverride");
context.cache.superclass(context.superClass)
.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class)
.addMember("value", "{$S, $S, $S}", "unchecked", "MissingOverride", "NullAway")
.build())
.addJavadoc(getJavaDoc())
.addTypeVariable(kTypeVar)
.addTypeVariable(vTypeVar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
*/
package com.github.benmanes.caffeine.cache.local;

import org.apache.commons.lang3.StringUtils;

import com.squareup.javapoet.AnnotationSpec;

/**
* @author [email protected] (Ben Manes)
*/
Expand All @@ -27,6 +31,12 @@ protected boolean applies() {

@Override
protected void execute() {
if (!context.suppressedWarnings.isEmpty()) {
var format = "{" + StringUtils.repeat("$S", ", ", context.suppressedWarnings.size()) + "}";
context.cache.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class)
.addMember("value", format, context.suppressedWarnings.toArray())
.build());
}
context.cache.addMethod(context.constructor.build());
}
}
Loading

0 comments on commit c5e46c3

Please sign in to comment.