internal sealed override void LookupSymbolsInSingleBinder( LookupResult result, string name, int arity, ConsList <Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.NamespacesOrTypesOnly | LookupOptions.LabelsOnly)) != 0) { return; } var local = this.LookupPlaceholder(name); if ((object)local == null) { base.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics); } else { result.MergeEqual(this.CheckViability(local, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved)); } }
internal sealed override void LookupSymbolsInSingleBinder( LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.NamespacesOrTypesOnly | LookupOptions.LabelsOnly)) != 0) { return; } var local = this.LookupPlaceholder(name); if ((object)local == null) { base.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics); } else { result.MergeEqual(this.CheckViability(local, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved)); } }
// Given two looksup in two scopes, whereby viable results in resultHiding should hide results // in resultHidden, merge the lookups. private LookupResult MergeHidingLookups(LookupResult resultHiding, LookupResult resultHidden) { // Methods hide non-methods, non-methods hide everything. We do not implement hiding by signature // here; that can be handled later in overload lookup. Doing this efficiently is a little complex... if (resultHiding.IsViable && resultHidden.IsViable) { if (resultHiding.IsSingleton) { if (resultHiding.SingleSymbol.Kind != SymbolKind.Method) { return(resultHiding); } } else { foreach (Symbol sym in resultHiding.Symbols) { if (sym.Kind != SymbolKind.Method) { return(resultHiding); // any non-method hides everything in the hiding scope. } } } // "resultHiding" only has methods. Hide all non-methods from resultHidden. if (resultHidden.IsSingleton) { if (resultHidden.SingleSymbol.Kind == SymbolKind.Method) { return(resultHiding.MergeEqual(resultHidden)); } else { return(resultHiding); } } else { LookupResult result = resultHiding; foreach (Symbol sym in resultHidden.Symbols) { if (sym.Kind == SymbolKind.Method) { result = result.MergeEqual(LookupResult.Good(sym)); } } return(result); } } else { return(resultHiding.MergePrioritized(resultHidden)); } }
internal sealed override void LookupSymbolsInSingleBinder( LookupResult result, string name, int arity, ConsList <Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.NamespacesOrTypesOnly | LookupOptions.LabelsOnly)) != 0) { return; } if (name.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { var valueText = name.Substring(2); ulong address; if (!ulong.TryParse(valueText, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out address)) { // Invalid value should have been caught by Lexer. throw ExceptionUtilities.UnexpectedValue(valueText); } var local = new ObjectAddressLocalSymbol(_containingMethod, name, this.Compilation.GetSpecialType(SpecialType.System_Object), address); result.MergeEqual(this.CheckViability(local, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved)); } else { LocalSymbol lowercaseReturnValueAlias; if (_lowercaseReturnValueAliases.TryGetValue(name, out lowercaseReturnValueAlias)) { result.MergeEqual(this.CheckViability(lowercaseReturnValueAlias, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved)); } else { base.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics); } } }
internal sealed override void LookupSymbolsInSingleBinder( LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.NamespacesOrTypesOnly | LookupOptions.LabelsOnly)) != 0) { return; } if (name.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { var valueText = name.Substring(2); ulong address; if (!ulong.TryParse(valueText, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out address)) { // Invalid value should have been caught by Lexer. throw ExceptionUtilities.UnexpectedValue(valueText); } var local = new ObjectAddressLocalSymbol(_containingMethod, name, this.Compilation.GetSpecialType(SpecialType.System_Object), address); result.MergeEqual(this.CheckViability(local, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved)); } else { LocalSymbol lowercaseReturnValueAlias; if (_lowercaseReturnValueAliases.TryGetValue(name, out lowercaseReturnValueAlias)) { result.MergeEqual(this.CheckViability(lowercaseReturnValueAlias, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved)); } else { base.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics); } } }
// Give lookups in two scopes which should be ambiguous toward eachother; merge the results. private LookupResult MergeAmbiguousLookups(LookupResult result1, LookupResult result2) { // TODO: Make sure that this merging works correctly. return(result1.MergeEqual(result2)); }
// Given two lookups done in the same scope, merge the results. private LookupResult MergeLookupsInSameScope(LookupResult result1, LookupResult result2) { // TODO: Make sure that this merging gives the correct semantics. return(result1.MergeEqual(result2)); }
protected override void LookupSymbolsInSingleBinder(LookupResult result, string name, int arity, ConsList <Symbol> basesBeingResolved, LookupOptions options, bool diagnose) { LookupResult tmp = LookupResult.GetInstance(); LookupResult nonViable = LookupResult.GetInstance(); // Member definitions of different kinds hide each other (field defs hide method defs, etc.). // So even if the caller asks only for invocable members find any member first and then reject the result if a non-invokable is found. LookupOptions anyMemberLookupOptions = options & ~LookupOptions.MustBeInvocableMember; // TODO: optimize lookup (there might be many interactions in the chain) for (ICompilation commonSubmission = Compilation.PreviousSubmission; commonSubmission != null; commonSubmission = commonSubmission.PreviousSubmission) { // TODO (tomat): cross-language binding - for now, skip non-C# submissions Compilation submission = commonSubmission as Compilation; if (submission == null) { continue; } tmp.Clear(); Imports imports = GetImports(submission); imports.LookupSymbolInAliases(this, tmp, name, arity, basesBeingResolved, anyMemberLookupOptions, diagnose); // If a viable using alias and a matching member are both defined in the submission an error is reported elsewhere. // Ignore the member in such case. if (!tmp.IsMultiViable && (options & LookupOptions.NamespaceAliasesOnly) == 0) { this.LookupMembers(tmp, submission.ScriptClass, name, arity, basesBeingResolved, anyMemberLookupOptions, diagnose); } // found a non-method in the current submission: if (tmp.Symbols.Count > 0 && tmp.Symbols.First().Kind != SymbolKind.Method) { if (!tmp.IsMultiViable) { // skip non-viable members, but remember them in case no viable members are found in previous submissions: nonViable.MergePrioritized(tmp); continue; } if (result.Symbols.Count == 0) { result.MergeEqual(tmp); } break; } // merge overloads: Debug.Assert(result.Symbols.Count == 0 || result.Symbols.All(s => s.Kind == SymbolKind.Method)); result.MergeEqual(tmp); } // Set a proper error if we found a symbol that is not invocable but were asked for invocable only. // Only a single non-method can be present in the result; methods are always invocable. if ((options & LookupOptions.MustBeInvocableMember) != 0 && result.Symbols.Count == 1) { Symbol symbol = result.Symbols.First(); AliasSymbol alias = symbol as AliasSymbol; if (alias != null) { symbol = alias.GetAliasTarget(basesBeingResolved); } if (IsNonInvocableMember(symbol)) { result.SetFrom(LookupResult.NotInvocable(symbol, result.Symbols.First(), diagnose)); } } else if (result.Symbols.Count == 0) { result.SetFrom(nonViable); } tmp.Free(); nonViable.Free(); }
// Give lookups in two scopes which should be ambiguous toward eachother; merge the results. private LookupResult MergeAmbiguousLookups(LookupResult result1, LookupResult result2) { // TODO: Make sure that this merging works correctly. return result1.MergeEqual(result2); }
// Given two looksup in two scopes, whereby viable results in resultHiding should hide results // in resultHidden, merge the lookups. private LookupResult MergeHidingLookups(LookupResult resultHiding, LookupResult resultHidden) { // Methods hide non-methods, non-methods hide everything. We do not implement hiding by signature // here; that can be handled later in overload lookup. Doing this efficiently is a little complex... if (resultHiding.IsViable && resultHidden.IsViable) { if (resultHiding.IsSingleton) { if (resultHiding.SingleSymbol.Kind != SymbolKind.Method) return resultHiding; } else { foreach (Symbol sym in resultHiding.Symbols) { if (sym.Kind != SymbolKind.Method) return resultHiding; // any non-method hides everything in the hiding scope. } } // "resultHiding" only has methods. Hide all non-methods from resultHidden. if (resultHidden.IsSingleton) { if (resultHidden.SingleSymbol.Kind == SymbolKind.Method) return resultHiding.MergeEqual(resultHidden); else return resultHiding; } else { LookupResult result = resultHiding; foreach (Symbol sym in resultHidden.Symbols) { if (sym.Kind == SymbolKind.Method) result = result.MergeEqual(LookupResult.Good(sym)); } return result; } } else { return resultHiding.MergePrioritized(resultHidden); } }
// Given two lookups done in the same scope, merge the results. private LookupResult MergeLookupsInSameScope(LookupResult result1, LookupResult result2) { // TODO: Make sure that this merging gives the correct semantics. return result1.MergeEqual(result2); }
protected override void LookupSymbolsInSingleBinder(LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, bool diagnose) { LookupResult tmp = LookupResult.GetInstance(); LookupResult nonViable = LookupResult.GetInstance(); // Member definitions of different kinds hide each other (field defs hide method defs, etc.). // So even if the caller asks only for invocable members find any member first and then reject the result if a non-invokable is found. LookupOptions anyMemberLookupOptions = options & ~LookupOptions.MustBeInvocableMember; // TODO: optimize lookup (there might be many interactions in the chain) for (ICompilation commonSubmission = Compilation.PreviousSubmission; commonSubmission != null; commonSubmission = commonSubmission.PreviousSubmission) { // TODO (tomat): cross-language binding - for now, skip non-C# submissions Compilation submission = commonSubmission as Compilation; if (submission == null) { continue; } tmp.Clear(); Imports imports = GetImports(submission); imports.LookupSymbolInAliases(this, tmp, name, arity, basesBeingResolved, anyMemberLookupOptions, diagnose); // If a viable using alias and a matching member are both defined in the submission an error is reported elsewhere. // Ignore the member in such case. if (!tmp.IsMultiViable && (options & LookupOptions.NamespaceAliasesOnly) == 0) { this.LookupMembers(tmp, submission.ScriptClass, name, arity, basesBeingResolved, anyMemberLookupOptions, diagnose); } // found a non-method in the current submission: if (tmp.Symbols.Count > 0 && tmp.Symbols.First().Kind != SymbolKind.Method) { if (!tmp.IsMultiViable) { // skip non-viable members, but remember them in case no viable members are found in previous submissions: nonViable.MergePrioritized(tmp); continue; } if (result.Symbols.Count == 0) { result.MergeEqual(tmp); } break; } // merge overloads: Debug.Assert(result.Symbols.Count == 0 || result.Symbols.All(s => s.Kind == SymbolKind.Method)); result.MergeEqual(tmp); } // Set a proper error if we found a symbol that is not invocable but were asked for invocable only. // Only a single non-method can be present in the result; methods are always invocable. if ((options & LookupOptions.MustBeInvocableMember) != 0 && result.Symbols.Count == 1) { Symbol symbol = result.Symbols.First(); AliasSymbol alias = symbol as AliasSymbol; if (alias != null) { symbol = alias.GetAliasTarget(basesBeingResolved); } if (IsNonInvocableMember(symbol)) { result.SetFrom(LookupResult.NotInvocable(symbol, result.Symbols.First(), diagnose)); } } else if (result.Symbols.Count == 0) { result.SetFrom(nonViable); } tmp.Free(); nonViable.Free(); }