001package gudusoft.gsqlparser.resolver2.scope; 002 003import gudusoft.gsqlparser.nodes.TParseTreeNode; 004import gudusoft.gsqlparser.resolver2.ScopeType; 005import gudusoft.gsqlparser.resolver2.matcher.INameMatcher; 006import gudusoft.gsqlparser.resolver2.model.QualifiedName; 007import gudusoft.gsqlparser.resolver2.model.ScopeChild; 008import gudusoft.gsqlparser.resolver2.namespace.INamespace; 009 010import java.util.Collections; 011import java.util.List; 012 013/** 014 * Abstract base class for all scopes. 015 * Implements delegation pattern - most methods delegate to parent. 016 * 017 * Subclasses only need to override methods where they have special behavior. 018 */ 019public abstract class AbstractScope implements IScope { 020 021 /** Parent scope (never null - root has EmptyScope parent) */ 022 protected final IScope parent; 023 024 /** Associated AST node */ 025 protected final TParseTreeNode node; 026 027 /** Scope type */ 028 protected final ScopeType scopeType; 029 030 protected AbstractScope(IScope parent, TParseTreeNode node, ScopeType scopeType) { 031 if (parent == null) { 032 throw new IllegalArgumentException("Parent scope cannot be null. Use EmptyScope for root."); 033 } 034 this.parent = parent; 035 this.node = node; 036 this.scopeType = scopeType; 037 } 038 039 @Override 040 public IScope getParent() { 041 return parent; 042 } 043 044 @Override 045 public TParseTreeNode getNode() { 046 return node; 047 } 048 049 @Override 050 public ScopeType getScopeType() { 051 return scopeType; 052 } 053 054 /** 055 * Default implementation: delegate to parent 056 */ 057 @Override 058 public void resolve(List<String> names, 059 INameMatcher matcher, 060 boolean deep, 061 IResolved resolved) { 062 parent.resolve(names, matcher, deep, resolved); 063 } 064 065 /** 066 * Default implementation: delegate to parent 067 */ 068 @Override 069 public INamespace resolveTable(String tableName) { 070 return parent.resolveTable(tableName); 071 } 072 073 /** 074 * Default implementation: not supported (most scopes don't have children) 075 */ 076 @Override 077 public void addChild(INamespace namespace, String alias, boolean nullable) { 078 throw new UnsupportedOperationException( 079 "Scope type " + scopeType + " does not support adding children"); 080 } 081 082 /** 083 * Default implementation: empty list 084 */ 085 @Override 086 public List<ScopeChild> getChildren() { 087 return Collections.emptyList(); 088 } 089 090 /** 091 * Default implementation: delegate to parent 092 */ 093 @Override 094 public List<INamespace> getVisibleNamespaces() { 095 return parent.getVisibleNamespaces(); 096 } 097 098 /** 099 * Default implementation: delegate to parent 100 */ 101 @Override 102 public QualifiedName fullyQualify(String name) { 103 return parent.fullyQualify(name); 104 } 105 106 /** 107 * Default implementation: check ancestry 108 */ 109 @Override 110 public boolean isWithin(IScope ancestorScope) { 111 if (this == ancestorScope) { 112 return true; 113 } 114 if (parent == null) { 115 return false; 116 } 117 return parent.isWithin(ancestorScope); 118 } 119 120 @Override 121 public String toString() { 122 StringBuilder sb = new StringBuilder(); 123 sb.append(scopeType); 124 if (node != null) { 125 sb.append("(").append(node.getClass().getSimpleName()).append(")"); 126 } 127 return sb.toString(); 128 } 129}