001package org.clafer.ast.analysis; 002 003import java.util.HashMap; 004import java.util.Map; 005import java.util.Set; 006import org.clafer.ast.AstAbstractClafer; 007import org.clafer.ast.AstClafer; 008import org.clafer.ast.AstConcreteClafer; 009import org.clafer.ast.Card; 010import org.clafer.scope.Scope; 011 012/** 013 * 014 * @author jimmy 015 */ 016public class ScopeAnalyzer implements Analyzer { 017 018 /* 019 * Shrinks the scope if it's greater than the upper global cardinality. 020 * Also set abstract scopes. 021 */ 022 @Override 023 public Analysis analyze(Analysis analysis) { 024 Scope scope = analysis.getScope(); 025 Map<AstClafer, Integer> optimizedScope = new HashMap<>(); 026 optimizedScope.put(analysis.getModel(), 1); 027 028 for (Set<AstClafer> component : analysis.getClafersInParentAndSubOrder()) { 029 for (AstClafer clafer : component) { 030 if (clafer instanceof AstConcreteClafer) { 031 Card globalCard = analysis.getGlobalCard(clafer); 032 optimizedScope.put(clafer, Math.min(scope.getScope(clafer), globalCard.getHigh())); 033 } else { 034 int subScopes = 0; 035 for (AstClafer sub : ((AstAbstractClafer) clafer).getSubs()) { 036 subScopes += optimizedScope.containsKey(sub) ? optimizedScope.get(sub) : scope.getDefaultScope(); 037 } 038 optimizedScope.put(clafer, subScopes); 039 } 040 } 041 } 042 return analysis.setScope(new Scope(optimizedScope, scope.getDefaultScope(), scope.getIntLow(), scope.getIntHigh())); 043 } 044}