X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fenvironment%2Ffilter%2FNamespaceFilters.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fenvironment%2Ffilter%2FNamespaceFilters.java;h=57159b861d7d42254266dda514db36410137157f;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java new file mode 100644 index 000000000..57159b861 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java @@ -0,0 +1,128 @@ +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); + } +}