JavaType.java

/*
 * SPDX-FileCopyrightText: 2025 kaumei.io
 * SPDX-License-Identifier: Apache-2.0
 */
package io.kaumei.jdbc.anno.model;

import io.kaumei.jdbc.anno.ctx.Context;
import org.jspecify.annotations.Nullable;

import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;

public class JavaType {

    private final Context ctx;
    private final TypeElement typeElement;
    private final TypeMirror typeMirror;
    private final boolean hasGenerics;

    public JavaType(Context ctx, TypeElement typeElement) {
        this.ctx = ctx;
        this.typeElement = typeElement;
        this.hasGenerics = !typeElement.getTypeParameters().isEmpty();
        this.typeMirror = hasGenerics ? this.ctx.erasure(typeElement.asType()) : typeElement.asType();
        if (this.typeMirror.getKind() == TypeKind.ERROR) {
            throw new IllegalArgumentException("Type has ERROR kind: " + this.typeMirror);
        }
    }

    @Override
    public String toString() {
        return "JavaType{typeElement=" + typeElement +
                ", typeMirror=" + typeMirror +
                ", hasGenerics=" + hasGenerics +
                '}';
    }

    public TypeMirror typeMirror() {
        return this.typeMirror;
    }

    public boolean isSameType(@Nullable TypeMirror other) {
        if (other == null) {
            return false;
        }
        return this.ctx.isSameType(typeMirror, this.hasGenerics ? this.ctx.erasure(other) : other);
    }

    public boolean isSupertypeOf(TypeMirror other) {
        return this.ctx.isSubtype(other, this.typeMirror);
    }

}