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