10000 Introduction of @Mixin annotation to generate code by verhasi · Pull Request #34977 · spring-projects/spring-framework · GitHub
[go: up one dir, main page]

Skip to content

Introduction of @Mixin annotation to generate code #34977

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugins {
id("java")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.springframework.annotation.processor;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import java.util.Set;

/**
* This annotation processor claims all the annotations that are not processed at compile time at all.
* Otherwise, the compiler would emit a warning that
* {@code No processor claimed any of these annotations}. Adding this to the compiler arg option {@code -Werror},
* would fail the build.
*/
@SupportedAnnotationTypes({
"org.springframework.core.annotation.AliasFor",
"javax.annotation.Nonnull",
"org.jspecify.annotations.NullMarked",
"com.oracle.svm.core.annotate.Alias",
"org.springframework.lang.Contract",
"jdk.jfr/jdk.jfr.Registered",
"org.springframework.aot.hint.annotation.Reflective",
"jdk.jfr/jdk.jfr.Category",
"javax.annotation.CheckForNull",
"com.oracle.svm.core.annotate.Substitute",
"jdk.jfr/jdk.jfr.Enabled",
"jdk.jfr/jdk.jfr.Label",
"org.springframework.aot.hint.annotation.RegisterReflection",
"com.oracle.svm.core.annotate.TargetClass",
"jdk.jfr/jdk.jfr.StackTrace",
"jdk.jfr/jdk.jfr.Description",
"javax.annotation.meta.TypeQualifierNickname",
"javax.annotation.meta.TypeQualifierDefault",
"javax.annotation.Generated"
})
@SupportedSourceVersion(SourceVersion.RELEASE_21)
public class NonProcessedAnnotationClaimer extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.springframework.annotation.processor.NonProcessedAnnotationClaimer
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ include "framework-api"
include "framework-bom"
include "framework-docs"
include "framework-platform"
include 'framework-annotation-processor'
include "integration-tests"

rootProject.name = "spring"
Expand All @@ -51,3 +52,4 @@ settings.gradle.projectsLoaded {
}
}
}

7 changes: 7 additions & 0 deletions spring-core/spring-core.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ configurations {
objenesis
graalvm
}
tasks.compileJava {
options.errorprone.excludedPaths = ".*/build/generated/.*"
}

tasks.register('javapoetRepackJar', ShadowJar) {
archiveBaseName = 'spring-javapoet-repack'
Expand Down Expand Up @@ -67,6 +70,7 @@ tasks.register('objenesisSourceJar', Jar) {
}

dependencies {
annotationProcessor project(":framework-annotation-processor")
javapoet("com.squareup:javapoet:${javapoetVersion}@jar")
objenesis("org.objenesis:objenesis:${objenesisVersion}@jar")
api(files(javapoetRepackJar))
Expand All @@ -76,6 +80,9 @@ dependencies {
compileOnly("com.google.code.findbugs:jsr305")
compileOnly("io.projectreactor.tools:blockhound")
compileOnly("org.graalvm.sdk:graal-sdk")
compileOnly("guru.mocker.annotation:mixin-annotation:1.1.0")
annotationProcessor("guru.mocker.annotation:mixin-annotation-processor:1.1.0")
implementation 'javax.annotation:javax.annotation-api:1.3.2'
optional("io.micrometer:context-propagation")
optional("io.netty:netty-buffer")
optional("io.projectreactor:reactor-core")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

import guru.mocker.annotation.mixin.Mixin;
import org.jspecify.annotations.Nullable;

/**
Expand All @@ -38,38 +36,36 @@
* @see LinkedMultiValueMap
*/
@SuppressWarnings("serial")
public class MultiValueMapAdapter<K, V> implements MultiValueMap<K, V>, Serializable {

private final Map<K, List<V>> targetMap;

@Mixin
public class MultiValueMapAdapter<K, V> extends MapForwarder<K,V> implements MultiValueMap<K, V>, Serializable {

/**
* Wrap the given target {@link Map} as a {@link MultiValueMap} adapter.
* @param targetMap the plain target {@code Map}
* @param mapForwarder the plain target {@code Map}
*/
public MultiValueMapAdapter(Map<K, List<V>> targetMap) {
Assert.notNull(targetMap, "'targetMap' must not be null");
this.targetMap = targetMap;
public MultiValueMapAdapter(Map<K, List<V>> mapForwarder) {
super(mapForwarder);
Assert.notNull(mapForwarder, "'targetMap' must not be null");
}


// MultiValueMap implementation

@Override
public @Nullable V getFirst(K key) {
List<V> values = this.targetMap.get(key);
List<V> values = this.mapForwarder.get(key);
return (!CollectionUtils.isEmpty(values) ? values.get(0) : null);
}

@Override
public void add(K key, @Nullable V value) {
List<V> values = this.targetMap.computeIfAbsent(key, k -> new ArrayList<>(1));
List<V> values = this.mapForwarder.computeIfAbsent(key, k -> new ArrayList<>(1));
values.add(value);
}

@Override
public void addAll(K key, List<? extends V> values) {
List<V> currentValues = this.targetMap.computeIfAbsent(key, k -> new ArrayList<>(values.size()));
List<V> currentValues = this.mapForwarder.computeIfAbsent(key, k -> new ArrayList<>(values.size()));
currentValues.addAll(values);
}

Expand All @@ -82,7 +78,7 @@ public void addAll(MultiValueMap<K, V> values) {
public void set(K key, @Nullable V value) {
List<V> values = new ArrayList<>(1);
values.add(value);
this.targetMap.put(key, values);
this.mapForwarder.put(key, values);
}

@Override
Expand All @@ -92,8 +88,8 @@ public void setAll(Map<K, V> values) {

@Override
public Map<K, V> toSingleValueMap() {
Map<K, V> singleValueMap = CollectionUtils.newLinkedHashMap(this.targetMap.size());
this.targetMap.forEach((key, values) -> {
Map<K, V> singleValueMap = CollectionUtils.newLinkedHashMap(this.mapForwarder.size());
this.mapForwarder.forEach((key, values) -> {
if (!CollectionUtils.isEmpty(values)) {
singleValueMap.put(key, values.get(0));
}
Expand All @@ -104,89 +100,13 @@ public Map<K, V> toSingleValueMap() {

// Map implementation

@Override
public int size() {
return this.targetMap.size();
}

@Override
public boolean isEmpty() {
return this.targetMap.isEmpty();
}

@Override
public boolean containsKey(Object key) {
return this.targetMap.containsKey(key);
}

@Override
public boolean containsValue(Object value) {
return this.targetMap.containsValue(value);
}

@Override
public @Nullable List<V> get(Object key) {
return this.targetMap.get(key);
}

@Override
public @Nullable List<V> put(K key, List< BF04 ;V> value) {
return this.targetMap.put(key, value);
}

@Override
public @Nullable List<V> putIfAbsent(K key, List<V> value) {
return this.targetMap.putIfAbsent(key, value);
}

@Override
public @Nullable List<V> remove(Object key) {
return this.targetMap.remove(key);
}

@Override
public void putAll(Map<? extends K, ? extends List<V>> map) {
this.targetMap.putAll(map);
}

@Override
public void clear() {
this.targetMap.clear();
}

@Override
public Set<K> keySet() {
return this.targetMap.keySet();
}

@Override
public Collection<List<V>> values() {
return this.targetMap.values();
}

@Override
public Set<Entry<K, List<V>>> entrySet() {
return this.targetMap.entrySet();
}

@Override
public void forEach(BiConsumer<? super K, ? super List<V>> action) {
this.targetMap.forEach(action);
}

@Override
public boolean equals(@Nullable Object other) {
return (this == other || this.targetMap.equals(other));
return (this == other || this.mapForwarder.equals(other));
}

@Override
public int hashCode() {
return this.targetMap.hashCode();
}

@Override
public String toString() {
return this.targetMap.toString();
return this.mapForwarder.hashCode();
}

}
0