Example #1
0
        public override void LookupSymbolsInSingleBinder(LookupResult result, LookupConstraints constraints)
        {
            Debug.Assert(result.IsClear);

            if (IsSubmission)
            {
                this.LookupMembersInternal(result, constraints.WithQualifier(_container));
                return;
            }

            var imports = GetImports(constraints.BasesBeingResolved);

            // first lookup members of the namespace
            if ((constraints.Options & LookupOptions.NamespaceAliasesOnly) == 0 && _container != null)
            {
                this.LookupMembersInternal(result, constraints.WithQualifier(_container));

                if (result.IsMultiViable)
                {
                    // symbols cannot conflict with using alias names
                    if (constraints.MetadataName == constraints.Name && imports.IsUsingAlias(constraints.Name, constraints.OriginalBinder.IsSemanticModelBinder))
                    {
                        LanguageDiagnosticInfo diagInfo = new LanguageDiagnosticInfo(InternalErrorCode.ERR_ConflictAliasAndMember, constraints.Name, _container);
                        var error = new ExtendedErrorTypeSymbol((NamespaceOrTypeSymbol)null, constraints.Name, constraints.MetadataName, diagInfo, unreported: true);
                        result.SetFrom(LookupResult.Good(error)); // force lookup to be done w/ error symbol as result
                    }

                    return;
                }
            }

            // next try using aliases or symbols in imported namespaces
            imports.LookupSymbol(result, constraints);
        }
Example #2
0
        public override void LookupSymbolsInSingleBinder(LookupResult result, LookupConstraints constraints)
        {
            Debug.Assert(result.IsClear);

            var specialSymbol = Compilation.GetSpecialSymbol(constraints.MetadataName);

            if (specialSymbol.Kind != LanguageSymbolKind.ErrorType)
            {
                result.SetFrom(LookupResult.Good(specialSymbol));
            }
        }
        public override void LookupSymbolsInSingleBinder(LookupResult result, LookupConstraints constraints)
        {
            var hostObjectType = GetHostObjectType();

            if (hostObjectType.Kind == LanguageSymbolKind.ErrorType)
            {
                // The name '{0}' does not exist in the current context (are you missing a reference to assembly '{1}'?)
                result.SetFrom(new LanguageDiagnosticInfo(
                                   InternalErrorCode.ERR_NameNotInContextPossibleMissingReference,
                                   new object[] { constraints.Name, ((MissingMetadataTypeSymbol)hostObjectType).ContainingAssembly.Identity },
                                   ImmutableArray <Symbol> .Empty,
                                   ImmutableArray <Location> .Empty
                                   ));
            }
            else
            {
                LookupMembersInternal(result, constraints.WithQualifier(hostObjectType));
            }
        }
        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();
        }
        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();
        }