java-commons/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/type/DTypeAnd.java

46 lines
1.9 KiB
Java

package io.gitlab.jfronny.muscript.data.dynamic.type;
import io.gitlab.jfronny.commons.data.ImmCollection;
import java.util.*;
public record DTypeAnd(Set<DType> elements) implements DType {
public DTypeAnd(Set<DType> elements) {
if (elements.isEmpty()) throw new IllegalArgumentException("Cannot create union type without elements");
Set<DType> simple = new LinkedHashSet<>();
Set<DType> list = new LinkedHashSet<>();
Set<DType> object = new LinkedHashSet<>();
boolean foundNullList = false, foundNullObject = false;
Queue<DType> toProcess = new LinkedList<>(elements);
while (!toProcess.isEmpty()) {
DType type = toProcess.remove();
//TODO replace with pattern match
if (type instanceof DTypePrimitive || type instanceof DTypeSum || type instanceof DTypeCallable || type instanceof DTypeGeneric) simple.add(type);
else if (type instanceof DTypeList u) {
if (u.entryType() == null) {
if (!foundNullList) simple.add(new DTypeList(null));
foundNullList = true;
} else list.add(u.entryType());
} else if (type instanceof DTypeObject u) {
if (u.entryType() == null) {
if (!foundNullObject) simple.add(new DTypeObject(null));
foundNullObject = true;
} else object.add(u.entryType());
} else if (type instanceof DTypeAnd u) toProcess.addAll(u.elements);
else throw new IllegalArgumentException("Unexpected DType implementation: " + type.getClass());
}
if (!list.isEmpty()) simple.add(new DTypeList(new DTypeAnd(list)));
if (!object.isEmpty()) simple.add(new DTypeObject(new DTypeAnd(object)));
this.elements = ImmCollection.copyOf(simple);
}
@Override
public String toString() {
return DType.toString(this);
}
}