Skip to content

Commit

Permalink
annotation injection, step-by-step (wip)
Browse files Browse the repository at this point in the history
+ organize imports (accidentally)
  • Loading branch information
elucash committed Mar 5, 2018
1 parent f1c2565 commit 4a87157
Show file tree
Hide file tree
Showing 21 changed files with 289 additions and 136 deletions.
22 changes: 18 additions & 4 deletions annotate/src/org/immutables/annotate/InjectAnnotation.java
Expand Up @@ -21,14 +21,16 @@

/**
* Specify annotation type, this is an alternative to specifying {@link #code()}. All the
* attributes from the annotated annotation (the one which is annotated by {@link InjectAnnotation} and
* placed on abstract value type or abstract attribute.
* attributes from the annotated annotation (the one which is annotated by
* {@link InjectAnnotation} and placed on abstract value type or abstract attribute.
* Default value is {@code InjectAnnotation.class} which is just a placeholder for unspecified
* value.
* @see #code()
*/
Class<?> type() default Void.class;
Class<? extends Annotation> type() default InjectAnnotation.class;

/**
* Enables special behavior when annotation is placed to {@link #target()} places only if
* Enables special behavior when annotation is injected to {@link #target()} only if
* {@link #type()} is set and corresponding model element have the same annotation. {@link #code}
* expansion will still work and can override annotation type (if starts with full annotation
* definition).
Expand All @@ -45,6 +47,18 @@
*/
Where[] target();

/**
* Unique key is used when there's a need to prevent putting multiple conflicting annotations on
* the element if it's covered by injection annotations. Putting it straight: when traversing all
* injection annotations (or as meta-annotations) which covers the element in question, starting
* from most specific to least specific, if there already was annotation injected by the some key,
* the following annotations by the same key will be discarded.
* if not specified explicitly (empty string in the annotation attribute) the key will be
* auto-inferred as {@code type()} if specifed or
* string
*/
String deduplicationKey() default "";

/** Logical elements of generated code to which annotations can be applied to. */
enum Where {
FIELD,
Expand Down
Expand Up @@ -93,7 +93,9 @@ private static Processor createClassLoaderDelegate() {
Thread.currentThread().getContextClassLoader());
}
return (Processor) cachedProxyClassLoader.loadClass(DELEGATE_CLASS).newInstance();
} catch (Throwable ex) {
} catch (RuntimeException | Error ex) {
throw ex;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
Expand Down
Expand Up @@ -22,7 +22,10 @@
import java.util.Set;
import org.immutables.generator.Naming;
import org.immutables.value.Value;
import org.immutables.value.Value.*;
import org.immutables.value.Value.Default;
import org.immutables.value.Value.Derived;
import org.immutables.value.Value.Enclosing;
import org.immutables.value.Value.Immutable;
import org.immutables.value.processor.encode.Code.Term;

@Immutable
Expand Down
Expand Up @@ -15,9 +15,15 @@
*/
package org.immutables.value.processor.encode;

import com.google.common.base.*;
import com.google.common.collect.*;
import java.util.*;
import com.google.common.base.CaseFormat;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.immutables.generator.Templates;
import org.immutables.generator.Templates.Invokable;
Expand All @@ -26,7 +32,10 @@
import org.immutables.value.processor.encode.Code.Term;
import org.immutables.value.processor.encode.EncodedElement.Param;
import org.immutables.value.processor.encode.EncodedElement.TypeParam;
import org.immutables.value.processor.encode.Type.*;
import org.immutables.value.processor.encode.Type.Defined;
import org.immutables.value.processor.encode.Type.Parameters;
import org.immutables.value.processor.encode.Type.Variable;
import org.immutables.value.processor.encode.Type.VariableResolver;
import org.immutables.value.processor.meta.Styles;
import org.immutables.value.processor.meta.Styles.UsingName.AttributeNames;
import org.immutables.value.processor.meta.ValueType;
Expand Down
Expand Up @@ -15,7 +15,6 @@
*/
package org.immutables.value.processor.encode;

import org.immutables.value.processor.meta.ValueType;
import com.google.common.base.Optional;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
Expand All @@ -31,6 +30,7 @@
import org.immutables.value.processor.encode.Type.Wildcard;
import org.immutables.value.processor.meta.Reporter;
import org.immutables.value.processor.meta.Styles;
import org.immutables.value.processor.meta.ValueType;

public final class Instantiator {
private final Type.Factory typeFactory;
Expand Down
@@ -1,6 +1,9 @@
package org.immutables.value.processor.meta;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Map;
import org.immutables.mirror.Mirror;
import org.immutables.value.processor.meta.AnnotationInjections.InjectAnnotation.Where;

Expand All @@ -11,12 +14,14 @@ private AnnotationInjections() {}
public @interface InjectAnnotation {
String code() default "";

Class<? extends Annotation> type() default Override.class;
Class<? extends Annotation> type() default InjectAnnotation.class;

boolean ifPresent() default false;

Where[] target();

String deduplicationKey() default "";

enum Where {
FIELD,
ACCESSOR,
Expand All @@ -29,22 +34,62 @@ enum Where {
}
}

private static boolean isDefault(String annotationType) {
return annotationType.equals("org.immutables.annotate.InjectAnnotation") // original default
|| annotationType.equals(Override.class.getName()); // default from the mirror
private static String emptyIfDefault(String annotationType) {
if (annotationType.equals("org.immutables.annotate.InjectAnnotation") // original default
|| annotationType.equals(InjectAnnotation.class.getName())) { // default from the mirror
return "";
}
return annotationType;
}

public final class InjectionInfo {
public static InjectionInfo infoFrom(InjectAnnotationMirror mirror) {
return new InjectionInfo(
mirror.code(),
emptyIfDefault(mirror.typeName()),
mirror.deduplicationKey(),
mirror.ifPresent(),
mirror.target());
}

public static final class InjectionInfo {
final String code;
/** empty if injected annotations. */
final String annotationType;
final boolean ifPresent;
final Where[] target;
final String deduplicationKey;
final EnumSet<Where> targets;

private InjectionInfo(String code, String annotationType, boolean ifPresent, Where[] target) {
private InjectionInfo(
String code,
String annotationType,
String deduplicationKey,
boolean ifPresent,
Where[] targets) {
this.code = code;
this.annotationType = annotationType;
this.ifPresent = ifPresent;
this.target = target;
this.targets = targets.length == 0
? EnumSet.allOf(Where.class)
: EnumSet.copyOf(Arrays.asList(targets));

this.deduplicationKey = deduplicationKeyFor(deduplicationKey, annotationType, code);
}

private String deduplicationKeyFor(String deduplicationKey, String annotationType, String code) {
if (!deduplicationKey.isEmpty()) {
return deduplicationKey;
}
if (!annotationType.isEmpty()) {
return annotationType;
}
return code;
}

void collectApplicable(Where target, Map<String, String> annotations) {
if (annotations.containsKey(deduplicationKey)
|| !targets.contains(target)) {
return;
}
}
}
}
Expand Up @@ -15,8 +15,8 @@
*/
package org.immutables.value.processor.meta;

import org.immutables.generator.ExtensionLoader;
import com.google.common.collect.ImmutableSet;
import org.immutables.generator.ExtensionLoader;

public final class CustomImmutableAnnotations {
private CustomImmutableAnnotations() {}
Expand Down
Expand Up @@ -15,8 +15,8 @@
*/
package org.immutables.value.processor.meta;

import org.immutables.generator.ExtensionLoader;
import com.google.common.collect.ImmutableSet;
import org.immutables.generator.ExtensionLoader;

public final class CustomImmutableCollections {
private CustomImmutableCollections() {}
Expand Down
Expand Up @@ -15,13 +15,13 @@
*/
package org.immutables.value.processor.meta;

import javax.lang.model.element.ElementKind;
import com.google.common.base.Functions;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.List;
import javax.annotation.Nullable;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Parameterizable;
import javax.lang.model.element.VariableElement;
Expand Down
Expand Up @@ -15,11 +15,11 @@
*/
package org.immutables.value.processor.meta;

import javax.annotation.Nullable;
import com.google.common.collect.Iterators;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
import javax.lang.model.element.Element;
import javax.lang.model.element.Parameterizable;
import javax.lang.model.element.TypeParameterElement;
Expand Down
Expand Up @@ -15,7 +15,6 @@
*/
package org.immutables.value.processor.meta;

import javax.annotation.Nullable;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand All @@ -26,7 +25,8 @@
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Set;
import static com.google.common.base.Preconditions.*;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkArgument;

/**
* Structure to calculate bit packing
Expand Down

0 comments on commit 4a87157

Please sign in to comment.