package com.redhat.ceylon.eclipse.core.typechecker; import java.util.List; import org.antlr.runtime.CommonToken; import com.redhat.ceylon.compiler.typechecker.TypeChecker; import com.redhat.ceylon.model.typechecker.util.ModuleManager; import com.redhat.ceylon.compiler.typechecker.analyzer.ModuleSourceMapper; import com.redhat.ceylon.compiler.typechecker.context.PhasedUnit; import com.redhat.ceylon.compiler.typechecker.context.PhasedUnits; import com.redhat.ceylon.compiler.typechecker.io.VirtualFile; import com.redhat.ceylon.model.typechecker.model.Package; import com.redhat.ceylon.compiler.typechecker.tree.Tree.CompilationUnit; public abstract class LazyPhasedUnit extends IdePhasedUnit { private TypeChecker typeChecker; private boolean validatingTree = false; private boolean scanningDeclarations = false; private boolean scanningTypeDeclarations = false; private boolean validatingRefinement = false; private boolean analysingTypes = false; private boolean analyzingFlow = false; public LazyPhasedUnit(VirtualFile unitFile, VirtualFile srcDir, CompilationUnit cu, Package p, ModuleManager moduleManager, ModuleSourceMapper moduleSourceMapper, TypeChecker typeChecker, List<CommonToken> tokenStream) { super(unitFile, srcDir, cu, p, moduleManager, moduleSourceMapper, typeChecker, tokenStream); this.typeChecker = typeChecker; } public LazyPhasedUnit(PhasedUnit other) { super(other); if (other instanceof LazyPhasedUnit) { typeChecker = ((LazyPhasedUnit) other).typeChecker; } } @Override public void validateTree() { if (! isTreeValidated() && ! validatingTree) { validatingTree = true; super.validateTree(); validatingTree = false; } } @Override public synchronized void scanDeclarations() { if (! isDeclarationsScanned() && !scanningDeclarations) { scanningDeclarations = true; for (PhasedUnit phasedUnit : typeChecker.getPhasedUnits().getPhasedUnits()) { phasedUnit.validateTree(); } super.scanDeclarations(); scanningDeclarations = false; } } @Override public synchronized void scanTypeDeclarations() { if (! isTypeDeclarationsScanned() && ! scanningTypeDeclarations) { scanningTypeDeclarations = true; for (PhasedUnits phasedUnits : typeChecker.getPhasedUnitsOfDependencies()) { for (PhasedUnit phasedUnit : phasedUnits.getPhasedUnits()) { phasedUnit.scanDeclarations(); } } for (PhasedUnit phasedUnit : typeChecker.getPhasedUnits().getPhasedUnits()) { phasedUnit.scanDeclarations(); } super.scanTypeDeclarations(); scanningTypeDeclarations = false; } } @Override public synchronized void validateRefinement() { if (! isRefinementValidated() && ! validatingRefinement) { validatingRefinement = true; for (PhasedUnits phasedUnits : typeChecker.getPhasedUnitsOfDependencies()) { for (PhasedUnit phasedUnit : phasedUnits.getPhasedUnits()) { phasedUnit.scanTypeDeclarations(); } } for (PhasedUnit phasedUnit : typeChecker.getPhasedUnits().getPhasedUnits()) { phasedUnit.scanTypeDeclarations(); } super.validateRefinement(); validatingRefinement = false; } } @Override public synchronized void analyseTypes() { if (! isFullyTyped() && ! analysingTypes) { analysingTypes = true; for (PhasedUnits phasedUnits : typeChecker.getPhasedUnitsOfDependencies()) { for (PhasedUnit phasedUnit : phasedUnits.getPhasedUnits()) { phasedUnit.validateRefinement(); } } for (PhasedUnit phasedUnit : typeChecker.getPhasedUnits().getPhasedUnits()) { phasedUnit.validateRefinement(); } super.analyseTypes(); analysingTypes = false; } } @Override public synchronized void analyseFlow() { if (! isFlowAnalyzed() && ! analyzingFlow) { analyzingFlow = true; for (PhasedUnits phasedUnits : typeChecker.getPhasedUnitsOfDependencies()) { for (PhasedUnit phasedUnit : phasedUnits.getPhasedUnits()) { phasedUnit.analyseTypes(); } } for (PhasedUnit phasedUnit : typeChecker.getPhasedUnits().getPhasedUnits()) { phasedUnit.analyseTypes(); } super.analyseFlow(); analyzingFlow = false; } } }