@@ -1100,100 +1100,128 @@ function symbLookupTypeNS _
11001100 '' Because symbols are added in the order that they are defined,
11011101 '' in some cases we can't just take the first symbol we find.
11021102
1103- '' keyword?
1104- hashtb = symb.hashlist.tail
1105- do
1106- dim as FBSYMBOL ptr sym = hashLookupEx( @hashtb->tb, id, index )
1107- while ( sym )
1108- if ( sym-> class = FB_SYMBCLASS_KEYWORD ) then
1109- tk = sym-> key .id
1110- tk_class = sym-> key .tkclass
1111- '' return if it's a KEYWORD or a OPERATOR token, they
1112- '' can't never be redefined, even inside namespaces
1113- if ( tk_class <> FB_TKCLASS_QUIRKWD ) then
1103+ scope
1104+ '' keyword?
1105+ hashtb = symb.hashlist.tail
1106+ do
1107+ dim as FBSYMBOL ptr sym = hashLookupEx( @hashtb->tb, id, index )
1108+ while ( sym )
1109+ if ( sym-> class = FB_SYMBCLASS_KEYWORD ) then
1110+ tk = sym-> key .id
1111+ tk_class = sym-> key .tkclass
1112+ '' return if it's a KEYWORD or a OPERATOR token, they
1113+ '' can't never be redefined, even inside namespaces
1114+ if ( tk_class <> FB_TKCLASS_QUIRKWD ) then
1115+ return symbNewChainpool( sym )
1116+ end if
1117+ end if
1118+ sym = sym->hash.next
1119+ wend
1120+ hashtb = hashtb->prev
1121+ loop while ( hashtb <> NULL )
1122+ end scope
1123+
1124+ scope
1125+ '' Search locals - if we are in a procedure, and the symbol can be found
1126+ '' directly, return the first one on the top of the stack
1127+ hashtb = symb.hashlist.tail
1128+ do
1129+ dim as FBSYMBOL ptr sym = hashLookupEx( @hashtb->tb, id, index )
1130+ while ( sym )
1131+ if ( symbIsLocal( sym ) ) then
11141132 return symbNewChainpool( sym )
11151133 end if
1116- end if
1117- sym = sym->hash.next
1118- wend
1119- hashtb = hashtb->prev
1120- loop while ( hashtb <> NULL )
1134+ sym = sym->hash.next
1135+ wend
1136+ hashtb = hashtb->prev
1137+ loop while ( hashtb <> NULL )
1138+ end scope
11211139
1122- '' any symbol not in the global namespace or we are already in the global namespace?
1123- '' check the whole list before we check the imports
1124- hashtb = symb.hashlist.tail
1125- do
1126- dim as FBSYMBOL ptr sym = hashLookupEx( @hashtb->tb, id, index )
1140+
1141+ scope
1142+ '' Search symbols in the UDT's namespace
1143+ dim as FBSYMBOL ptr ns = symbGetCurrentNamespc( )
1144+
1145+ '' search in UDT's (TYPE or CLASS) hash tb first
1146+ dim as FBSYMBOL ptr sym = hashLookupEx( @symbGetCompHashTb( ns ).tb, id, index )
1147+
1148+ '' don't access locals in a TYPE's namespace
11271149 while ( sym )
1128- '' return if it's not the global ns (as in C++, any nested
1129- '' symbol has precedence over any imported one, even if the
1130- '' latter was imported in the current ns)
1131- if ( hashtb->owner <> @symbGetGlobalNamespc( ) ) then
1132- return symbNewChainpool( sym )
1150+ if ( symbIsLocal( sym ) ) then
1151+ sym = sym->hash.next
11331152 else
1134- '' also if we are at the global ns, no need to check the imports
1135- if ( symbGetCurrentNamespc( ) = @symbGetGlobalNamespc( ) ) then
1136- return symbNewChainpool( sym )
1137- else
1138- if ( first_ancestor = NULL ) then
1139- first_ancestor = sym
1140- end if
1141- end if
1153+ exit while
11421154 end if
1143- sym = sym->hash.next
11441155 wend
1145- hashtb = hashtb->prev
1146- loop while ( hashtb <> NULL )
1147-
1148- dim as FBSYMBOL ptr ns = symbGetCurrentNamespc( )
11491156
1150- '' search in UDT's (TYPE or CLASS) hash tb first
1151- dim as FBSYMBOL ptr sym = hashLookupEx( @symbGetCompHashTb( ns ).tb, id, index )
1152-
1153- '' don't access local variables in an explicit namespace
1154- while ( sym )
1155- if ( symbIsLocal( sym ) and symbIsVar( sym ) ) then
1156- sym = sym->hash.next
1157- else
1158- exit while
1157+ '' Found the symbol in the type's namespace?
1158+ if ( sym ) then
1159+ dim as FBSYMCHAIN ptr chain_ = symbNewChainpool( sym )
1160+ return chain_
11591161 end if
1160- wend
1162+ end scope
1163+
1164+ scope
1165+ '' Search symbols in the the type's imports, but only if inherieted from
1166+ '' a parent type - don't check imports from a normal namespace
1167+
1168+ '' we already know that the current namespace is a TYPE
1169+ dim as FBSYMBOL ptr ns = symbGetCurrentNamespc( )
1170+
1171+ if ( (symbGetCompExt( ns ) <> NULL) and (symbGetCompImportHead( ns ) <> NULL) ) then
1172+ dim as FBSYMCHAIN ptr chain_ = hLookupImportList( ns, id, index )
1173+ dim as FBSYMBOL ptr sym = NULL
1174+
1175+ '' search UDT variables
1176+ while ( chain_ )
1177+ sym = chain_->sym
1178+ while ( sym )
1179+ dim as FBSYMBOL ptr parent = symbGetParent( sym )
1180+ if ( symbGetType( parent ) = FB_DATATYPE_STRUCT ) then
1181+ if ( symbGetUDTBaseLevel( ns, parent ) > 0 ) then
1182+ return symbNewChainpool( chain_->sym )
1183+ end if
1184+ end if
1185+ sym = sym->hash.next
1186+ wend
11611187
1162- '' Found the symbol in the type's namespace?
1163- if ( sym ) then
1164- dim as FBSYMCHAIN ptr chain_ = symbNewChainpool( sym )
1165- return chain_
1166- end if
1188+ chain_ = symbChainGetNext( chain_ )
1189+ wend
11671190
1168- '' Search the type's imports
1169- if ( (symbGetCompExt( ns ) <> NULL) and (symbGetCompImportHead( ns ) <> NULL) ) then
1170- dim as FBSYMCHAIN ptr chain_ = hLookupImportList( ns, id, index )
1171- if ( chain_ ) then
1172- '' return the first one
1173- return symbNewChainpool( chain_->sym )
11741191 end if
1175- end if
1176-
1177- '' search all the imports?
1178- dim as FBSYMCHAIN ptr imp_chain = hashLookupEx( @symb.imphashtb, id, index )
1179- if ( imp_chain <> NULL ) then
1192+ end scope
11801193
1181- if ( first_ancestor ) then
1182- dim as FBSYMCHAIN ptr chain_ = symbNewChainpool( first_ancestor )
1183- chain_-> next = imp_chain
1184- return chain_
1194+ scope
1195+ '' any symbol not in the global namespace or we are already in the global namespace?
1196+ '' check the whole list before we check the imports
1197+ hashtb = symb.hashlist.tail
1198+ do
1199+ dim as FBSYMBOL ptr sym = hashLookupEx( @hashtb->tb, id, index )
1200+ if ( sym ) then
1201+ return symbNewChainpool( sym )
1202+ end if
1203+ hashtb = hashtb->prev
1204+ loop while ( hashtb <> NULL )
1205+ end scope
1206+
1207+ scope
1208+ '' search the current namespace
1209+ dim as FBSYMBOL ptr ns = symbGetCurrentNamespc( )
1210+
1211+ if ( (symbGetCompExt( ns ) <> NULL) and (symbGetCompImportHead( ns ) <> NULL) ) then
1212+ dim as FBSYMCHAIN ptr chain_ = hLookupImportList( ns, id, index )
1213+ if ( chain_ ) then
1214+ '' return the first one
1215+ return symbNewChainpool( chain_->sym )
1216+ end if
11851217 end if
1218+ end scope
11861219
1187- return imp_chain
1188- end if
1189-
1190- '' no imports? return only first ancestor (if we already found it)
1191- if ( first_ancestor ) then
1192- return symbNewChainpool( first_ancestor )
1193- end if
1220+ '' search all the imports
1221+ dim as FBSYMCHAIN ptr imp_chain = hashLookupEx( @symb.imphashtb, id, index )
11941222
11951223 '' never found
1196- return NULL
1224+ return imp_chain
11971225
11981226end function
11991227
@@ -1345,6 +1373,9 @@ function symbLookupAt _
13451373 '' search in UDT's (NAMESPACE, TYPE, CLASS or ENUM) hash tb first
13461374 dim as FBSYMBOL ptr sym = hashLookupEx( @symbGetCompHashTb( ns ).tb, id, index )
13471375
1376+ '' !!!TODO!!! some imports won't make sense in an explicit namespace
1377+ '' for example this.proc() where proc() is imported from a plain old namespace
1378+
13481379 '' don't access local variables in an explicit namespace
13491380 while ( sym )
13501381 if ( symbIsLocal( sym ) and symbIsVar( sym ) ) then
0 commit comments