package com.excelsior.xds.parser.internal.modula.symbol; import java.util.Iterator; import org.apache.commons.collections.iterators.EmptyIterator; import com.excelsior.xds.parser.modula.symbol.IModulaSymbol; import com.excelsior.xds.parser.modula.symbol.IModulaSymbolScope; import com.excelsior.xds.parser.modula.symbol.SymbolAttribute; import com.excelsior.xds.parser.modula.symbol.reference.IModulaSymbolReference; import com.excelsior.xds.parser.modula.symbol.reference.ReferenceUtils; import com.excelsior.xds.parser.modula.symbol.type.IRecordTypeSymbol; /** * A scope of Modula-2 WITH statement. */ public class WithStatementScope implements IModulaSymbolScope { private final IModulaSymbolScope parentScope; private IModulaSymbolReference<IRecordTypeSymbol> withExpressionTypeRef; public WithStatementScope(IModulaSymbolReference<IRecordTypeSymbol> withExpressionTypeRef, IModulaSymbolScope parentScope) { this.withExpressionTypeRef = withExpressionTypeRef; this.parentScope = parentScope; } /** * {@inheritDoc} */ @Override public IModulaSymbolScope getParentScope() { return parentScope; } /** * {@inheritDoc} */ @Override public IModulaSymbol resolveName(String symbolName) { IModulaSymbol symbol = findSymbolInScope(symbolName); if (symbol == null) { IModulaSymbolScope parentScope = getParentScope(); if (parentScope != null) { symbol = parentScope.resolveName(symbolName); } } return symbol; } /** * {@inheritDoc} */ @Override public IModulaSymbol findSymbolInScope(String symbolName) { IModulaSymbol symbol = null; IRecordTypeSymbol withExpressionType = ReferenceUtils.resolve(withExpressionTypeRef); if (withExpressionType != null) { symbol = withExpressionType.findSymbolInScope(symbolName); } if (symbol == null) { IModulaSymbolScope parentScope = getParentScope(); if (parentScope != null) { symbol = parentScope.findSymbolInScope(symbolName); } } return symbol; } /** * {@inheritDoc} */ @Override public IModulaSymbol findSymbolInScope(String symbolName, boolean isPublic) { IModulaSymbol symbol = findSymbolInScope(symbolName); if (symbol != null) { if (isPublic != symbol.isAttributeSet(SymbolAttribute.PUBLIC)) { symbol = null; } } return symbol; } /** * {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public Iterator<IModulaSymbol> iterator() { IRecordTypeSymbol withExpressionType = ReferenceUtils.resolve(withExpressionTypeRef); if (withExpressionType == null) { return EmptyIterator.INSTANCE; } return withExpressionType.iterator(); } }