Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dependency:
<groupId>org.microbean</groupId>
<artifactId>microbean-assign</artifactId>
<!-- Always check https://search.maven.org/artifact/org.microbean/microbean-bean for up-to-date available versions. -->
<version>0.0.3</version>
<version>0.0.4</version>
</dependency>
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
*
* Copyright © 2025 microBean™.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.microbean.assign;

import java.util.Comparator;

import javax.lang.model.type.TypeKind;

/**
* A {@link Comparator} establishing a <a href="https://en.wikipedia.org/wiki/Partially_ordered_set"><dfn>partial
* order</dfn></a> over {@link TypeKind}s such that {@linkplain TypeKind#TYPEVAR type variables} precede {@linkplain
* TypeKind#isPrimitive primitive types}, {@linkplain TypeKind#isPrimitive primitive types} precede {@linkplain
* TypeKind#ARRAY array types}, and {@linkplain TypeKind#ARRAY array types} precede {@linkplain TypeKind#DECLARED
* declared types}.
*
* @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a>
*
* @see #compare(TypeKind, TypeKind)
*/
public final class PrimitiveAndReferenceTypeKindComparator implements Comparator<TypeKind> {


/*
* Static fields.
*/


/**
* The sole instance of this class.
*/
public static final PrimitiveAndReferenceTypeKindComparator INSTANCE = new PrimitiveAndReferenceTypeKindComparator();


/*
* Constructors.
*/


private PrimitiveAndReferenceTypeKindComparator() {
super();
}


/*
* Instance methods.
*/


/**
* Compares the two {@link TypeKind}s and returns the result.
*
* <p>If {@code k0} is {@code null} and {@code k1} is not, returns a positive value.</p>
*
* <p>If {@code k1} is {@code null} and {@code k0} is not, returns a negative value.</p>
*
* <p>If {@code k0} is {@link TypeKind#ARRAY}, and {@code k1} {@linkplain TypeKind#isPrimitive() is primitive},
* returns a positive value.</p>
*
* <p>If {@code k0} is {@link TypeKind#ARRAY}, and {@code k1} is {@link TypeKind#DECLARED}, returns a negative
* value.</p>
*
* <p>If {@code k0} {@linkplain TypeKind#isPrimitive() is primitive}, and {@code k1} is {@link TypeKind#ARRAY} or
* {@link TypeKind#DECLARED}, returns a negative value.</p>
*
* <p>If {@code k0} {@linkplain TypeKind#isPrimitive() is primitive}, and {@code k1} is {@link TypeKind#TYPEVAR},
* returns a positive value.</p>
*
* <p>If {@code k0} is {@link TypeKind#DECLARED}, and {@code k1} is {@link TypeKind#ARRAY}, or {@linkplain
* TypeKind#isPrimitive() is primitive}, or is {@link TypeKind#TYPEVAR}, returns a positive value.</p>
*
* <p>If {@code k0} is {@link TypeKind#TYPEVAR}, and {@code k1} is {@link TypeKind#ARRAY}, or {@linkplain
* TypeKind#isPrimitive() is primitive}, or is {@link TypeKind#DECLARED}, returns a negative value.</p>
*
* <p>Returns {@code 0} in all other cases.
*
* @param k0 a {@link TypeKind}; may be {@code null}
*
* @param k1 a {@link TypeKind}; may be {@code null}
*
* @return a comparison result
*
* @see TypeKind#isPrimitive()
*
* @see TypeKind#ARRAY
*
* @see TypeKind#DECLARED
*
* @see TypeKind#TYPEVAR
*/
@Override // Comparator<TypeKind>
public final int compare(final TypeKind k0, final TypeKind k1) {
return k0 == k1 ? 0 : k0 == null ? 1 : k1 == null ? -1 : switch (k0) {

case ARRAY -> switch (k1) {
// Arrays come after primitives and type variables.
case BOOLEAN, BYTE, CHAR, DOUBLE, FLOAT, INT, LONG, SHORT, TYPEVAR -> 1;
// Arrays come before declared types.
case DECLARED -> -1; // arrays come before declared
default -> 0;
};

case BOOLEAN, BYTE, CHAR, DOUBLE, FLOAT, INT, LONG, SHORT -> switch (k1) {
// Primitives come before arrays and declared types.
case ARRAY, DECLARED -> -1;
// Primitives come after type variables.
case TYPEVAR -> 1;
default -> 0;
};

case DECLARED -> switch (k1) {
// Declared types come after arrays, primitives and type variables.
case ARRAY, BOOLEAN, BYTE, CHAR, DOUBLE, FLOAT, INT, LONG, SHORT, TYPEVAR -> 1;
default -> 0;
};

case TYPEVAR -> switch (k1) {
// Type variables come before arrays, primitives and declared types.
case ARRAY, BOOLEAN, BYTE, CHAR, DECLARED, DOUBLE, FLOAT, INT, LONG, SHORT -> -1;
default -> 0;
};

default -> 0;
};
}

}

This file was deleted.

This file was deleted.

14 changes: 11 additions & 3 deletions src/main/java/org/microbean/assign/Types.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public class Types implements Constable {
public Types(final Domain domain) {
super();
this.domain = Objects.requireNonNull(domain, "domain");
this.c = comparing(TypeMirror::getKind, TypeVariablesFirstTypeKindComparator.INSTANCE)
this.c = comparing(TypeMirror::getKind, PrimitiveAndReferenceTypeKindComparator.INSTANCE)
.thenComparing(new SpecializationComparator(domain))
.thenComparing(Types::erasedName);
}
Expand Down Expand Up @@ -279,8 +279,16 @@ public final SupertypeList supertypes(final TypeMirror t, final Predicate<? supe
interfaceTypes.trimToSize();
final int interfaceIndex = interfaceTypes.isEmpty() ? -1 : nonInterfaceTypes.size();
return
new SupertypeList(concat(nonInterfaceTypes.stream(), // non-interface supertypes are already sorted from most-specific to least
interfaceTypes.stream().sorted(this.c)) // have to sort interfaces because you can extend them in any order
new SupertypeList(concat(
// Non-interface supertypes are already sorted from most-specific to least and will not
// contain primitive types. By extension, array types will precede declared types
// (java.lang.Object). If t is a type variable, then either its supertype will be another
// type variable or a declared type, so type variables precede everything.
nonInterfaceTypes.stream(),
// Interfaces need to be explicitly sorted because they can show up in multiple
// implements clauses and you want the set to be determinate.
interfaceTypes.stream().sorted(this.c)
)
.toList(),
interfaceIndex);
}
Expand Down