Skip to content

Commit

Permalink
Add JavaType.Annotation to support annotations in the type model (#27)
Browse files Browse the repository at this point in the history
* WIP: Add `JavaType.Annotation`

See:
 - openrewrite/rewrite#4746

* Complete

* Polish
  • Loading branch information
knutwannheden authored Jan 23, 2025
1 parent 2661a04 commit 36e5209
Show file tree
Hide file tree
Showing 2 changed files with 369 additions and 3 deletions.
186 changes: 183 additions & 3 deletions Rewrite/src/Rewrite.Java/Tree/JavaType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface JavaType
internal static readonly Method[] EMPTY_METHOD_ARRAY = [];
internal static readonly Variable[] EMPTY_VARIABLE_ARRAY = [];
internal static readonly string[] EMPTY_STRING_ARRAY = [];
internal static readonly Annotation.ElementValue[] EMPTY_ANNOTATION_VALUE_ARRAY = [];

internal int? ManagedReference => null;

Expand Down Expand Up @@ -152,9 +153,8 @@ private IEnumerator<Variable> GetVisibleMembers(string packageName)
}

private class FullyQualifiedEnumerator<E>(
#pragma warning disable // TODO: needs to be fully implemented
#pragma warning disable // TODO: needs to be fully implemented
FullyQualified fq,

string packageName,
Func<E, long> flagsFn,
Func<FullyQualified, IList<E>> baseFn,
Expand Down Expand Up @@ -325,7 +325,6 @@ internal void UnsafeSet(IList<JavaType>? typeParameters, FullyQualified? superty
IList<FullyQualified>? annotations, IList<FullyQualified>? interfaces,
IList<Variable>? members, IList<Method>? methods)
{

TypeParameters = typeParameters ?? EMPTY_JAVA_TYPE_ARRAY;
Supertype = supertype;
OwningClass = owningClass;
Expand Down Expand Up @@ -420,6 +419,187 @@ public override ISet<Flag> GetFlags()
public override FullyQualified? OwningClass { get; internal set; }
}

public sealed class Annotation : FullyQualified
{
internal Annotation()
{
}

public Annotation(FullyQualified type,
IList<ElementValue>? values)
{
Type = type;
Values = values ?? EMPTY_ANNOTATION_VALUE_ARRAY;
}

public IList<ElementValue> Values { get; internal set; } = EMPTY_ANNOTATION_VALUE_ARRAY;

public Annotation WithValues(IList<ElementValue>? values)
{
var newValues = values ?? EMPTY_ANNOTATION_VALUE_ARRAY;
if (newValues == Values)
{
return this;
}

return new Annotation(Type, newValues);
}

public FullyQualified Type { get; internal set; } = null!;

public Annotation WithType(FullyQualified type)
{
if (type == Type)
{
return this;
}

return new Annotation(type, Values);
}

public override string FullyQualifiedName
{
get => Type.FullyQualifiedName;
internal set => Type.FullyQualifiedName = value;
}

public override FullyQualified WithFullyQualifiedName(string fullyQualifiedName)
{
return WithType(Type.WithFullyQualifiedName(fullyQualifiedName));
}

public override IList<FullyQualified> Annotations
{
get => Type.Annotations;
internal set => Type.Annotations = value;
}

public override bool HasFlags(Flag[] test)
{
return Type.HasFlags(test);
}

public override ISet<Flag> GetFlags()
{
return Type.GetFlags();
}

public override IList<FullyQualified> Interfaces
{
get => Type.Interfaces;
internal set => Type.Interfaces = value;
}

public override TypeKind Kind
{
get => Type.Kind;
internal set => Type.Kind = value;
}

public override IList<Variable> Members
{
get => Type.Members;
internal set => Type.Members = value;
}

public override IList<Method> Methods
{
get => Type.Methods;
internal set => Type.Methods = value;
}

public override IList<JavaType> TypeParameters
{
get => Type.TypeParameters;
internal set => Type.TypeParameters = value;
}

public override FullyQualified? Supertype
{
get => Type.Supertype;
internal set => Type.Supertype = value;
}

public override FullyQualified? OwningClass
{
get => Type.OwningClass;
internal set => Type.OwningClass = value;
}

public interface ElementValue
{
JavaType Element { get; }
object GetValue();
}

public sealed class SingleElementValue : ElementValue
{
internal SingleElementValue()
{
}

public SingleElementValue(JavaType element, object value)
{
Element = element;
if (value is JavaType javaType)
{
ReferenceValue = javaType;
}
else
{
ConstantValue = value;
}
}

public JavaType Element { get; internal set; } = null!;

internal object? ConstantValue { get; set; } = null!;
internal JavaType? ReferenceValue { get; set; } = null!;

public object GetValue()
{
return ConstantValue ?? ReferenceValue!;
}
}

public sealed class ArrayElementValue : ElementValue
{
internal ArrayElementValue()
{
}

public ArrayElementValue(JavaType element, IList<object> values)
{
Element = element;
if (values.Count == 0)
{
ConstantValues = null;
ReferenceValues = null;
}
else if (values is IList<JavaType> javaTypes)
{
ReferenceValues = javaTypes;
}
else
{
ConstantValues = values;
}
}

public JavaType Element { get; internal set; } = null!;

internal IList<object>? ConstantValues { get; set; }
internal IList<JavaType>? ReferenceValues { get; set; }

public object GetValue()
{
return ConstantValues != null ? ConstantValues :
ReferenceValues != null ? ReferenceValues :
EMPTY_ANNOTATION_VALUE_ARRAY;
}
}
}

public sealed class GenericTypeVariable : JavaType
{
internal GenericTypeVariable()
Expand Down
Loading

0 comments on commit 36e5209

Please sign in to comment.