package org.simantics.scl.compiler.environment.filter; import gnu.trove.set.hash.THashSet; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.module.ImportDeclaration.ImportSpec; public class NamespaceFilters { public static NamespaceFilter createFromSpec(ImportSpec spec) { if(spec.hiding) { if(spec.values.length == 0) return AcceptAllNamespaceFilter.INSTANCE; THashSet names = new THashSet(spec.values.length); for(EVar value : spec.values) names.add(value.name); return new NegativeNamespaceFilter(names); } else { THashSet names = new THashSet(spec.values.length); for(EVar value : spec.values) names.add(value.name); return new PositiveNamespaceFilter(names); } } public static NamespaceFilter union(NamespaceFilter a, NamespaceFilter b) { if(a == AcceptAllNamespaceFilter.INSTANCE || b == AcceptAllNamespaceFilter.INSTANCE) return AcceptAllNamespaceFilter.INSTANCE; if(a instanceof PositiveNamespaceFilter) { if(b instanceof PositiveNamespaceFilter) return unionImpl((PositiveNamespaceFilter)a, (PositiveNamespaceFilter)b); else if(b instanceof NegativeNamespaceFilter) return unionImpl((NegativeNamespaceFilter)b, (PositiveNamespaceFilter)a); } else if(a instanceof NegativeNamespaceFilter) { if(b instanceof PositiveNamespaceFilter) return unionImpl((NegativeNamespaceFilter)a, (PositiveNamespaceFilter)b); else if(b instanceof NegativeNamespaceFilter) return unionImpl((NegativeNamespaceFilter)a, (NegativeNamespaceFilter)b); } return new NamespaceFilterUnion(a, b); } private static NamespaceFilter unionImpl(PositiveNamespaceFilter a, PositiveNamespaceFilter b) { THashSet includedValues = new THashSet(a.includedValues.size() + b.includedValues.size()); includedValues.addAll(a.includedValues); includedValues.addAll(b.includedValues); if(includedValues.size() == a.includedValues.size()) return a; if(includedValues.size() == b.includedValues.size()) return b; return new PositiveNamespaceFilter(includedValues); } private static NamespaceFilter unionImpl(NegativeNamespaceFilter a, PositiveNamespaceFilter b) { THashSet excludedValues = new THashSet(a.excludedValues); excludedValues.removeAll(b.includedValues); if(excludedValues.size() == a.excludedValues.size()) return a; if(excludedValues.isEmpty()) return AcceptAllNamespaceFilter.INSTANCE; return new NegativeNamespaceFilter(excludedValues); } private static NamespaceFilter unionImpl(NegativeNamespaceFilter a, NegativeNamespaceFilter b) { THashSet excludedValues = new THashSet(a.excludedValues); excludedValues.retainAll(b.excludedValues); if(excludedValues.size() == a.excludedValues.size()) return a; if(excludedValues.size() == b.excludedValues.size()) return b; if(excludedValues.isEmpty()) return AcceptAllNamespaceFilter.INSTANCE; return new NegativeNamespaceFilter(excludedValues); } public static NamespaceFilter intersection(NamespaceFilter a, NamespaceFilter b) { if(a == AcceptAllNamespaceFilter.INSTANCE) return b; if(b == AcceptAllNamespaceFilter.INSTANCE) return a; if(a instanceof PositiveNamespaceFilter) { if(b instanceof PositiveNamespaceFilter) return intersectionImpl((PositiveNamespaceFilter)a, (PositiveNamespaceFilter)b); else if(b instanceof NegativeNamespaceFilter) return intersectionImpl((PositiveNamespaceFilter)a, (NegativeNamespaceFilter)b); } else if(a instanceof NegativeNamespaceFilter) { if(b instanceof PositiveNamespaceFilter) return intersectionImpl((PositiveNamespaceFilter)b, (NegativeNamespaceFilter)a); else if(b instanceof NegativeNamespaceFilter) return intersectionImpl((NegativeNamespaceFilter)a, (NegativeNamespaceFilter)b); } return new NamespaceFilterIntersection(a, b); } private static NamespaceFilter intersectionImpl(NegativeNamespaceFilter a, NegativeNamespaceFilter b) { THashSet excludedValues = new THashSet(a.excludedValues.size() + b.excludedValues.size()); excludedValues.addAll(a.excludedValues); excludedValues.addAll(b.excludedValues); if(excludedValues.size() == a.excludedValues.size()) return a; if(excludedValues.size() == b.excludedValues.size()) return b; return new NegativeNamespaceFilter(excludedValues); } private static NamespaceFilter intersectionImpl(PositiveNamespaceFilter a, NegativeNamespaceFilter b) { THashSet includedValues = new THashSet(a.includedValues); includedValues.removeAll(b.excludedValues); if(includedValues.size() == a.includedValues.size()) return a; return new PositiveNamespaceFilter(includedValues); } private static NamespaceFilter intersectionImpl(PositiveNamespaceFilter a, PositiveNamespaceFilter b) { THashSet includedValues = new THashSet(a.includedValues); includedValues.retainAll(b.includedValues); if(includedValues.size() == a.includedValues.size()) return a; if(includedValues.size() == b.includedValues.size()) return b; return new PositiveNamespaceFilter(includedValues); } }