package cd.transform.optimizers;

import cd.ir.Ast.ClassDecl;
import cd.ir.Symbol.ArrayTypeSymbol;
import cd.ir.Symbol.TypeSymbol;
import cd.transform.analysis.ClassUsage;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class UnusedClassRemoval extends GlobalOptimizerVisitor<Void> {
	public boolean go(List<ClassDecl> classDecls, List<TypeSymbol> typeList) {
		Set<ClassDecl> used = new ClassUsage().go(classDecls);
		Set<ClassDecl> toRemove = new HashSet<>(classDecls);
		toRemove.removeAll(used);

		// Remove classes from list of declarations
		classDecls.clear();
		classDecls.addAll(used);

		// Remove corresponding types and array types
		for (ClassDecl classDecl : toRemove) {
			typeList.remove(classDecl.sym);
			TypeSymbol arrayType = null;
			for (TypeSymbol type : typeList) {
				if (type instanceof ArrayTypeSymbol && ((ArrayTypeSymbol) type).elementType == classDecl.sym) {
					arrayType = type;
					break;
				}
			}
			assert arrayType != null;
			typeList.remove(arrayType);
		}

		return !toRemove.isEmpty();
	}
}
