Beispiel #1
0
        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));
            }
        }
Beispiel #3
0
        // 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);
                }
            }
        }
Beispiel #6
0
 // 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));
 }
Beispiel #7
0
 // 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();
        }