protected 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.MustBeInvocableIfMember)) != 0)
            {
                return;
            }

            Debug.Assert(result.IsClear);

            var count = parameterMap.GetCountForKey(name);
            if (count == 1)
            {
                ParameterSymbol p;
                parameterMap.TryGetSingleValue(name, out p);
                result.MergeEqual(originalBinder.CheckViability(p, arity, options, null, diagnose, ref useSiteDiagnostics));
            }
            else if (count > 1)
            {
                var parameters = parameterMap[name];
                foreach (var sym in parameters)
                {
                    result.MergeEqual(originalBinder.CheckViability(sym, arity, options, null, diagnose, ref useSiteDiagnostics));
                }
            }
        }
Example #2
0
        internal static ImmutableArray<BoundInitializer> BindFieldInitializers(
            SourceMemberContainerTypeSymbol containingType,
            MethodSymbol scriptCtor,
            ImmutableArray<FieldInitializers> initializers,
            DiagnosticBag diagnostics,
            bool generateDebugInfo,
            out ConsList<Imports> firstDebugImports)
        {
            if (initializers.IsEmpty)
            {
                firstDebugImports = null;
                return ImmutableArray<BoundInitializer>.Empty;
            }

            CSharpCompilation compilation = containingType.DeclaringCompilation;
            ArrayBuilder<BoundInitializer> boundInitializers = ArrayBuilder<BoundInitializer>.GetInstance();

            if ((object)scriptCtor == null)
            {
                BindRegularCSharpFieldInitializers(compilation, initializers, boundInitializers, diagnostics, generateDebugInfo, out firstDebugImports);
            }
            else
            {
                BindScriptFieldInitializers(compilation, scriptCtor, initializers, boundInitializers, diagnostics, generateDebugInfo, out firstDebugImports);
            }

            return boundInitializers.ToImmutableAndFree();
        }
        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));
            }
        }
Example #4
0
        /// <summary>
        /// Determine the effective base type, effective interface set, and set of type
        /// parameters (excluding cycles) from the type parameter constraints. Conflicts
        /// within the constraints and constraint types are returned as diagnostics.
        /// 'inherited' should be true if the type parameters are from an overridden
        /// generic method. In those cases, additional constraint checks are applied.
        /// </summary>
        public static TypeParameterBounds ResolveBounds(
            this TypeParameterSymbol typeParameter,
            AssemblySymbol corLibrary,
            ConsList<TypeParameterSymbol> inProgress,
            ImmutableArray<TypeSymbol> constraintTypes,
            bool inherited,
            CSharpCompilation currentCompilation,
            DiagnosticBag diagnostics)
        {
            var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
            ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var bounds = typeParameter.ResolveBounds(corLibrary, inProgress, constraintTypes, inherited, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, pair.TypeParameter.Locations[0]));
            }

            diagnosticsBuilder.Free();
            return bounds;
        }
        internal override TypeSymbol GetFieldType(ConsList<FieldSymbol> fieldsBeingBound)
        {
            if ((object)_lazyType == null)
            {
                Interlocked.CompareExchange(ref _lazyType, _containingType.TypeSubstitution.SubstituteType(_originalDefinition.GetFieldType(fieldsBeingBound)).Type, null);
            }

            return _lazyType;
        }
        private Imports GetImports(ConsList<Symbol> basesBeingResolved)
        {
            if (_imports == null)
            {
                Interlocked.CompareExchange(ref _imports, Imports.FromSyntax(_declarationSyntax, this, basesBeingResolved, _inUsing), null);
            }

            return _imports;
        }
Example #7
0
        /// <summary>
        /// In regular C#, all field initializers are assignments to fields and the assigned expressions
        /// may not reference instance members.
        /// </summary>
        private static void BindRegularCSharpFieldInitializers(
            CSharpCompilation compilation,
            ImmutableArray<ImmutableArray<FieldInitializer>> initializers,
            ArrayBuilder<BoundInitializer> boundInitializers,
            DiagnosticBag diagnostics,
            bool generateDebugInfo,
            out ConsList<Imports> firstDebugImports)
        {
            firstDebugImports = null;

            foreach (ImmutableArray<FieldInitializer> siblingInitializers in initializers)
            {
                // All sibling initializers share the same parent node and tree so we can reuse the binder 
                // factory across siblings.  Unfortunately, we cannot reuse the binder itself, because
                // individual fields might have their own binders (e.g. because of being declared unsafe).
                BinderFactory binderFactory = null;

                foreach (FieldInitializer initializer in siblingInitializers)
                {
                    FieldSymbol fieldSymbol = initializer.Field;
                    Debug.Assert((object)fieldSymbol != null);

                    // A constant field of type decimal needs a field initializer, so
                    // check if it is a metadata constant, not just a constant to exclude
                    // decimals. Other constants do not need field initializers.
                    if (!fieldSymbol.IsMetadataConstant)
                    {
                        //Can't assert that this is a regular C# compilation, because we could be in a nested type of a script class.
                        SyntaxReference syntaxRef = initializer.Syntax;
                        var initializerNode = (CSharpSyntaxNode)syntaxRef.GetSyntax();

                        if (binderFactory == null)
                        {
                            binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree);
                        }

                        Binder parentBinder = binderFactory.GetBinder(initializerNode);
                        Debug.Assert(parentBinder.ContainingMemberOrLambda == fieldSymbol.ContainingType || //should be the binder for the type
                            fieldSymbol.ContainingType.IsImplicitClass); //however, we also allow fields in namespaces to help support script scenarios

                        if (generateDebugInfo && firstDebugImports == null)
                        {
                            firstDebugImports = parentBinder.ImportsList;
                        }

                        BoundInitializer boundInitializer = BindFieldInitializer(
                            new LocalScopeBinder(parentBinder).WithAdditionalFlagsAndContainingMemberOrLambda(parentBinder.Flags | BinderFlags.FieldInitializer, fieldSymbol),
                            fieldSymbol,
                            (EqualsValueClauseSyntax)initializerNode,
                            diagnostics);

                        boundInitializers.Add(boundInitializer);
                    }
                }
            }
        }
Example #8
0
 /// <summary>
 /// Builds a string builder from a cons list
 /// </summary>
 /// <param name="s">ConsList of prefix's</param>
 /// <returns>A stringbuilder with spaces seperating prefixes</returns>
 private string BuildStringBuilder(ConsList<string> s)
 {
     StringBuilder st = new StringBuilder();
     while (s != null)
     {
         st.Append(s.Head + " ");
         s = s.Tail;
     }
     return st.ToString();
 }
Example #9
0
 /// <summary>
 /// Checks if 'symbol' is accessible from within type 'within', with
 /// an qualifier of type "throughTypeOpt". Sets "failedThroughTypeCheck" to true
 /// if it failed the "through type" check.
 /// </summary>
 public static bool IsSymbolAccessible(
     Symbol symbol,
     NamedTypeSymbol within,
     TypeSymbol throughTypeOpt,
     out bool failedThroughTypeCheck,
     ref HashSet<DiagnosticInfo> useSiteDiagnostics,
     ConsList<Symbol> basesBeingResolved = null)
 {
     return IsSymbolAccessibleCore(symbol, within, throughTypeOpt, out failedThroughTypeCheck, within.DeclaringCompilation, ref useSiteDiagnostics, basesBeingResolved);
 }
Example #10
0
 /// <remarks>
 /// CONSIDER: in the case of field initializers, it is possible that different parts of a method could have different
 /// namespace scopes (i.e. if they come from different parts of a partial type).  Currently, we're following Dev10's
 /// approach of using the context of the (possibly synthesized) constructor into which the field initializers are
 /// inserted.  It might be possible to give field initializers their own scopes, assuming the EE supports it.
 /// </remarks>
 public ImmutableArray<Cci.NamespaceScope> GetNamespaceScopes(ConsList<Imports> debugImports)
 {
     if (debugImports == null)
     {
         return ImmutableArray<Cci.NamespaceScope>.Empty;
     }
     else
     {
         return cache.GetOrAdd(debugImports, buildNamespaceScopes);
     }
 }
Example #11
0
        internal override Imports GetImports(ConsList<Symbol> basesBeingResolved)
        {
            Debug.Assert(_lazyImports != null || _computeImports != null, "Have neither imports nor a way to compute them.");

            if (_lazyImports == null)
            {
                Interlocked.CompareExchange(ref _lazyImports, _computeImports(basesBeingResolved), null);
            }

            return _lazyImports;
        }
        private static ConsList<FieldSymbol> SubstituteFields(ConsList<FieldSymbol> fields, TypeMap typeMap)
        {
            if (!fields.Any())
            {
                return ConsList<FieldSymbol>.Empty;
            }

            var head = SubstituteField(fields.Head, typeMap);
            var tail = SubstituteFields(fields.Tail, typeMap);
            return tail.Prepend(head);
        }
Example #13
0
        private bool CheckStruct(ConsList<NamedTypeSymbol> typesWithMembersOfThisType, NamedTypeSymbol nts)
        {
            // Break recursive cycles. If we find a member that contains us, it is considered empty 
            if (!typesWithMembersOfThisType.ContainsReference(nts))
            {
                // Remember that we're in the process of doing this type while checking members.
                typesWithMembersOfThisType = new ConsList<NamedTypeSymbol>(nts, typesWithMembersOfThisType);
                return CheckStructInstanceFields(typesWithMembersOfThisType, nts);
            }

            return true;
        }
        internal DisplayClassVariable(string name, DisplayClassVariableKind kind, DisplayClassInstance displayClassInstance, ConsList<FieldSymbol> displayClassFields)
        {
            Debug.Assert(displayClassFields.Any());

            this.Name = name;
            this.Kind = kind;
            this.DisplayClassInstance = displayClassInstance;
            this.DisplayClassFields = displayClassFields;

            // Verify all type parameters are substituted.
            Debug.Assert(this.ContainingSymbol.IsContainingSymbolOfAllTypeParameters(this.Type));
        }
Example #15
0
        internal override void LookupSymbolsInSingleBinder(LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
        {
            _sourceBinder.LookupSymbolsInSingleBinder(result, name, arity, basesBeingResolved, options, this, diagnose, ref useSiteDiagnostics);

            var symbols = result.Symbols;
            for (int i = 0; i < symbols.Count; i++)
            {
                // Type parameters requiring mapping to the target type and
                // should be found by WithMethodTypeParametersBinder instead.
                var parameter = (ParameterSymbol)symbols[i];
                Debug.Assert(parameter.ContainingSymbol == _sourceBinder.ContainingMemberOrLambda);
                symbols[i] = _targetParameters[parameter.Ordinal + _parameterOffset];
            }
        }
        internal override void LookupSymbolsInSingleBinder(
            LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
        {
            Debug.Assert(result.IsClear);

            if ((options & LookupOptions.NamespaceAliasesOnly) != 0)
            {
                return;
            }

            foreach (var parameterSymbol in parameterMap[name])
            {
                result.MergeEqual(originalBinder.CheckViability(parameterSymbol, arity, options, null, diagnose, ref useSiteDiagnostics));
            }
        }
Example #17
0
        protected 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.MustBeInvocableIfMember)) != 0)
            {
                return;
            }

            Debug.Assert(result.IsClear);

            foreach (ParameterSymbol parameter in parameters)
            {
                if (parameter.Name == name)
                {
                    result.MergeEqual(originalBinder.CheckViability(parameter, arity, options, null, diagnose, ref useSiteDiagnostics));
                }
            }
        }
        internal override TypeSymbol GetFieldType(ConsList<FieldSymbol> fieldsBeingBound)
        {
            Debug.Assert(fieldsBeingBound != null);

            if ((object)_lazyType != null)
            {
                return _lazyType;
            }

            var typeSyntax = TypeSyntax;

            var compilation = this.DeclaringCompilation;

            var diagnostics = DiagnosticBag.GetInstance();
            TypeSymbol type;

            var binderFactory = compilation.GetBinderFactory(SyntaxTree);
            var binder = binderFactory.GetBinder(typeSyntax);

            bool isVar;
            type = binder.BindType(typeSyntax, diagnostics, out isVar);

            Debug.Assert((object)type != null || isVar);

            if (isVar && !fieldsBeingBound.ContainsReference(this))
            {
                InferFieldType(fieldsBeingBound, binder);
                Debug.Assert((object)_lazyType != null);
            }
            else
            {
                if (isVar)
                {
                    diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this);
                    type = binder.CreateErrorType("var");
                }

                SetType(compilation, diagnostics, type);
            }

            diagnostics.Free();
            return _lazyType;
        }
Example #19
0
 internal override void LookupSymbolsInSingleBinder(
     LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
 {
     var hostObjectType = GetHostObjectType();
     if (hostObjectType.Kind == SymbolKind.ErrorType)
     {
         // The name '{0}' does not exist in the current context (are you missing a reference to assembly '{1}'?)
         result.SetFrom(new CSDiagnosticInfo(
             ErrorCode.ERR_NameNotInContextPossibleMissingReference,
             new object[] { name, ((MissingMetadataTypeSymbol)hostObjectType).ContainingAssembly.Identity },
             ImmutableArray<Symbol>.Empty,
             ImmutableArray<Location>.Empty
         ));
     }
     else
     {
         LookupMembersInternal(result, hostObjectType, name, arity, basesBeingResolved, options, originalBinder, diagnose, ref useSiteDiagnostics);
     }
 }
        /// <summary>
        /// Gets the set of interfaces that this type directly implements. This set does not include
        /// interfaces that are base interfaces of directly implemented interfaces.
        /// </summary>
        internal sealed override ImmutableArray<NamedTypeSymbol> InterfacesNoUseSiteDiagnostics(ConsList<Symbol> basesBeingResolved)
        {
            if (_lazyInterfaces.IsDefault)
            {
                if (basesBeingResolved != null && basesBeingResolved.ContainsReference(this.OriginalDefinition))
                {
                    return ImmutableArray<NamedTypeSymbol>.Empty;
                }

                var diagnostics = DiagnosticBag.GetInstance();
                var acyclicInterfaces = MakeAcyclicInterfaces(basesBeingResolved, diagnostics);
                if (ImmutableInterlocked.InterlockedCompareExchange(ref _lazyInterfaces, acyclicInterfaces, default(ImmutableArray<NamedTypeSymbol>)).IsDefault)
                {
                    AddDeclarationDiagnostics(diagnostics);
                }
                diagnostics.Free();
            }

            return _lazyInterfaces;
        }
Example #21
0
        internal override void LookupSymbolsInSingleBinder(
            LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
        {
            if (!ShouldLookInUsings(options))
            {
                return;
            }

            LookupResult tmp = LookupResult.GetInstance();

            // usings:
            Imports.Empty.LookupSymbolInUsings(ConsolidatedUsings, originalBinder, tmp, name, arity, basesBeingResolved, options, diagnose, ref useSiteDiagnostics);

            // if we found a viable result in imported namespaces, use it instead of unviable symbols found in source:
            if (tmp.IsMultiViable)
            {
                result.MergeEqual(tmp);
            }

            tmp.Free();
        }
Example #22
0
        /// <summary>
        /// Determine if the given type is an empty struct type,. "typesWithMembersOfThisType" contains
        /// a list of types that have members (directly or indirectly) of this type.
        /// to remove circularity.
        /// </summary>
        private bool IsEmptyStructType(TypeSymbol type, ConsList<NamedTypeSymbol> typesWithMembersOfThisType)
        {
            var nts = type as NamedTypeSymbol;
            if ((object)nts == null || !IsTrackableStructType(nts))
            {
                return false;
            }

            // Consult the cache.
            bool result;
            if (Cache.TryGetValue(nts, out result))
            {
                return result;
            }

            result = CheckStruct(typesWithMembersOfThisType, nts);
            Debug.Assert(!Cache.ContainsKey(nts) || Cache[nts] == result);
            Cache[nts] = result;

            return result;
        }
Example #23
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;
            }

            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);
                }
            }
        }
 private bool UsesIsNullable(ImmutableArray <TypeSymbolWithAnnotations> types, ConsList <TypeParameterSymbol> inProgress)
 {
     return(types.Any(t => UsesIsNullable(t, inProgress)));
 }
Example #25
0
        /// <summary>
        /// Determine if "type" inherits from or implements "baseType", ignoring constructed types, and dealing
        /// only with original types.
        /// </summary>
        private static bool InheritsFromOrImplementsIgnoringConstruction(
            this TypeSymbol type,
            NamedTypeSymbol baseType,
            CSharpCompilation compilation,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics,
            ConsList <TypeSymbol> basesBeingResolved = null)
        {
            Debug.Assert(type.IsDefinition);
            Debug.Assert(baseType.IsDefinition);

            PooledHashSet <NamedTypeSymbol> interfacesLookedAt = null;
            ArrayBuilder <NamedTypeSymbol>  baseInterfaces     = null;

            bool baseTypeIsInterface = baseType.IsInterface;

            if (baseTypeIsInterface)
            {
                interfacesLookedAt = PooledHashSet <NamedTypeSymbol> .GetInstance();

                baseInterfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance();
            }

            PooledHashSet <NamedTypeSymbol> visited = null;
            var  current = type;
            bool result  = false;

            while ((object)current != null)
            {
                Debug.Assert(current.IsDefinition);
                if (baseTypeIsInterface == current.IsInterfaceType() &&
                    current == (object)baseType)
                {
                    result = true;
                    break;
                }

                if (baseTypeIsInterface)
                {
                    getBaseInterfaces(current, baseInterfaces, interfacesLookedAt, basesBeingResolved);
                }

                // NOTE(cyrusn): The base type of an 'original' type may not be 'original'. i.e.
                // "class Goo : IBar<int>".  We must map it back to the 'original' when as we walk up
                // the base type hierarchy.
                var next = current.GetNextBaseTypeNoUseSiteDiagnostics(basesBeingResolved, compilation, ref visited);
                if ((object)next == null)
                {
                    current = null;
                }
                else
                {
                    current = (TypeSymbol)next.OriginalDefinition;
                    current.AddUseSiteDiagnostics(ref useSiteDiagnostics);
                }
            }

            visited?.Free();

            if (!result && baseTypeIsInterface)
            {
                Debug.Assert(!result);

                while (baseInterfaces.Count != 0)
                {
                    NamedTypeSymbol currentBase = baseInterfaces.Pop();

                    if (!currentBase.IsInterface)
                    {
                        continue;
                    }

                    Debug.Assert(currentBase.IsDefinition);
                    if (currentBase == (object)baseType)
                    {
                        result = true;
                        break;
                    }

                    getBaseInterfaces(currentBase, baseInterfaces, interfacesLookedAt, basesBeingResolved);
                }

                if (!result)
                {
                    foreach (var candidate in interfacesLookedAt)
                    {
                        candidate.AddUseSiteDiagnostics(ref useSiteDiagnostics);
                    }
                }
            }

            interfacesLookedAt?.Free();
            baseInterfaces?.Free();
            return(result);
 private bool AddIfUsesIsNullable(Symbol symbol, TypeSymbolWithAnnotations type, ConsList <TypeParameterSymbol> inProgress)
 {
     if (UsesIsNullable(type, inProgress))
     {
         Add(symbol);
         return(true);
     }
     return(false);
 }
 internal override ImmutableArray <TypeWithAnnotations> GetConstraintTypes(ConsList <TypeParameterSymbol> inProgress)
 {
     return(ImmutableArray <TypeWithAnnotations> .Empty);
 }
Example #28
0
 internal override bool IsAccessibleHelper(Symbol symbol, TypeSymbol accessThroughType, out bool failedThroughTypeCheck, ref HashSet <DiagnosticInfo> useSiteDiagnostics, ConsList <TypeSymbol> basesBeingResolved)
 {
     failedThroughTypeCheck = false;
     return(IsSymbolAccessibleConditional(symbol, Compilation.Assembly, ref useSiteDiagnostics));
 }
 internal override ImmutableArray<TypeWithAnnotations> GetConstraintTypes(ConsList<TypeParameterSymbol> inProgress)
 {
     return this.RetargetingTranslator.Retarget(_underlyingTypeParameter.GetConstraintTypes(inProgress));
 }
 internal override NamedTypeSymbol GetDeclaredBaseType(ConsList<Symbol> basesBeingResolved)
 {
     return this.Manager.System_Object;
 }
 internal sealed override ImmutableArray<NamedTypeSymbol> InterfacesNoUseSiteDiagnostics(ConsList<Symbol> basesBeingResolved)
 {
     return _unbound ? ImmutableArray<NamedTypeSymbol>.Empty : Map.SubstituteNamedTypes(OriginalDefinition.InterfacesNoUseSiteDiagnostics(basesBeingResolved));
 }
Example #32
0
 internal override ImmutableArray <NamedTypeSymbol> InterfacesNoUseSiteDiagnostics(ConsList <Symbol> basesBeingResolved)
 {
     throw new NotImplementedException();
 }
 internal override TypeSymbol GetDeducedBaseType(ConsList <TypeParameterSymbol> inProgress)
 {
     return(null);
 }
 internal override NamedTypeSymbol GetEffectiveBaseClass(ConsList <TypeParameterSymbol> inProgress)
 {
     return(null);
 }
 internal override ImmutableArray <NamedTypeSymbol> GetInterfaces(ConsList <TypeParameterSymbol> inProgress)
 {
     return(ImmutableArray <NamedTypeSymbol> .Empty);
 }
Example #36
0
        /// <summary>
        /// Is a protected symbol inside "originalContainingType" accessible from within "within",
        /// which much be a named type or an assembly.
        /// </summary>
        private static bool IsProtectedSymbolAccessible(
            NamedTypeSymbol withinType,
            TypeSymbol throughTypeOpt,
            NamedTypeSymbol originalContainingType,
            out bool failedThroughTypeCheck,
            CSharpCompilation compilation,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics,
            ConsList <TypeSymbol> basesBeingResolved = null)
        {
            failedThroughTypeCheck = false;

            // It is not an error to define protected member in a sealed Script class, it's just a
            // warning. The member behaves like a private one - it is visible in all subsequent
            // submissions.
            if (originalContainingType.TypeKind == TypeKind.Submission)
            {
                return(true);
            }

            if ((object)withinType == null)
            {
                // If we're not within a type, we can't access a protected symbol
                return(false);
            }

            // A protected symbol is accessible if we're (optionally nested) inside the type that it
            // was defined in.

            // It is helpful to think about 'protected' as *increasing* the
            // accessibility domain of a private member, rather than *decreasing* that of a public
            // member. Members are naturally private; the protected, internal and public access
            // modifiers all increase the accessibility domain. Since private members are accessible
            // to nested types, so are protected members.

            // We do this check up front as it is very fast and easy to do.
            if (IsNestedWithinOriginalContainingType(withinType, originalContainingType))
            {
                return(true);
            }

            // Protected is really confusing.  Check out 3.5.3 of the language spec "protected access
            // for instance members" to see how it works.  I actually got the code for this from
            // LangCompiler::CheckAccessCore
            {
                var current = withinType.OriginalDefinition;
                var originalThroughTypeOpt = (object)throughTypeOpt == null ? null : throughTypeOpt.OriginalDefinition as TypeSymbol;
                while ((object)current != null)
                {
                    Debug.Assert(current.IsDefinition);

                    if (current.InheritsFromOrImplementsIgnoringConstruction(originalContainingType, compilation, ref useSiteDiagnostics, basesBeingResolved))
                    {
                        // NOTE(cyrusn): We're continually walking up the 'throughType's inheritance
                        // chain.  We could compute it up front and cache it in a set.  However, we
                        // don't want to allocate memory in this function.  Also, in practice
                        // inheritance chains should be very short.  As such, it might actually be
                        // slower to create and check inside the set versus just walking the
                        // inheritance chain.
                        if ((object)originalThroughTypeOpt == null ||
                            originalThroughTypeOpt.InheritsFromOrImplementsIgnoringConstruction(current, compilation, ref useSiteDiagnostics))
                        {
                            return(true);
                        }
                        else
                        {
                            failedThroughTypeCheck = true;
                        }
                    }

                    // NOTE(cyrusn): The container of an original type is always original.
                    current = current.ContainingType;
                }
            }

            return(false);
        }
 internal override ImmutableArray<NamedTypeSymbol> GetInterfaces(ConsList<TypeParameterSymbol> inProgress)
 {
     return this.RetargetingTranslator.Retarget(_underlyingTypeParameter.GetInterfaces(inProgress));
 }
Example #38
0
            static void getBaseInterfaces(TypeSymbol derived, ArrayBuilder <NamedTypeSymbol> baseInterfaces, PooledHashSet <NamedTypeSymbol> interfacesLookedAt, ConsList <TypeSymbol> basesBeingResolved)
            {
                if (basesBeingResolved != null && basesBeingResolved.ContainsReference(derived))
                {
                    return;
                }

                ImmutableArray <NamedTypeSymbol> declaredInterfaces;

                switch (derived)
                {
                case TypeParameterSymbol typeParameter:
                    declaredInterfaces = typeParameter.AllEffectiveInterfacesNoUseSiteDiagnostics;
                    break;

                case NamedTypeSymbol namedType:
                    declaredInterfaces = namedType.GetDeclaredInterfaces(basesBeingResolved);
                    break;

                default:
                    declaredInterfaces = derived.InterfacesNoUseSiteDiagnostics(basesBeingResolved);
                    break;
                }

                foreach (var @interface in declaredInterfaces)
                {
                    NamedTypeSymbol definition = @interface.OriginalDefinition;
                    if (interfacesLookedAt.Add(definition))
                    {
                        baseInterfaces.Add(definition);
                    }
                }
            }
 internal override TypeSymbol GetDeducedBaseType(ConsList<TypeParameterSymbol> inProgress)
 {
     return this.RetargetingTranslator.Retarget(_underlyingTypeParameter.GetDeducedBaseType(inProgress), RetargetOptions.RetargetPrimitiveTypesByTypeCode);
 }
Example #40
0
        /// <summary>
        /// Is the named type <paramref name="type"/> accessible from within <paramref name="within"/>,
        /// which must be a named type or an assembly.
        /// </summary>
        private static bool IsNamedTypeAccessible(NamedTypeSymbol type, Symbol within, ref HashSet <DiagnosticInfo> useSiteDiagnostics, ConsList <TypeSymbol> basesBeingResolved = null)
        {
            Debug.Assert(within is NamedTypeSymbol || within is AssemblySymbol);
            Debug.Assert((object)type != null);

            var compilation = within.DeclaringCompilation;

            bool unused;

            if (!type.IsDefinition)
            {
                // All type argument must be accessible.
                var typeArgs = type.TypeArgumentsWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics);
                foreach (var typeArg in typeArgs)
                {
                    // type parameters are always accessible, so don't check those (so common it's
                    // worth optimizing this).
                    if (typeArg.Type.Kind != SymbolKind.TypeParameter && !IsSymbolAccessibleCore(typeArg.Type, within, null, out unused, compilation, ref useSiteDiagnostics, basesBeingResolved))
                    {
                        return(false);
                    }
                }
            }

            var containingType = type.ContainingType;

            return((object)containingType == null
                ? IsNonNestedTypeAccessible(type.ContainingAssembly, type.DeclaredAccessibility, within)
                : IsMemberAccessible(containingType, type.DeclaredAccessibility, within, null, out unused, compilation, ref useSiteDiagnostics, basesBeingResolved));
        }
Example #41
0
        private static bool IsNonPublicMemberAccessible(
            NamedTypeSymbol containingType,              // the symbol's containing type
            Accessibility declaredAccessibility,
            Symbol within,
            TypeSymbol throughTypeOpt,
            out bool failedThroughTypeCheck,
            CSharpCompilation compilation,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics,
            ConsList <TypeSymbol> basesBeingResolved = null)
        {
            failedThroughTypeCheck = false;

            var originalContainingType = containingType.OriginalDefinition;
            var withinType             = within as NamedTypeSymbol;
            var withinAssembly         = (object)withinType != null ? withinType.ContainingAssembly : (AssemblySymbol)within;

            switch (declaredAccessibility)
            {
            case Accessibility.NotApplicable:
                return(true);

            case Accessibility.Private:
                // All expressions in the current submission (top-level or nested in a method or
                // type) can access previous submission's private top-level members. Previous
                // submissions are treated like outer classes for the current submission - the
                // inner class can access private members of the outer class.
                if (containingType.TypeKind == TypeKind.Submission)
                {
                    return(true);
                }

                // private members never accessible from outside a type.
                return((object)withinType != null && IsPrivateSymbolAccessible(withinType, originalContainingType));

            case Accessibility.Internal:
                // An internal type is accessible if we're in the same assembly or we have
                // friend access to the assembly it was defined in.
                return(withinAssembly.HasInternalAccessTo(containingType.ContainingAssembly));

            case Accessibility.ProtectedAndInternal:
                if (!withinAssembly.HasInternalAccessTo(containingType.ContainingAssembly))
                {
                    // We require internal access.  If we don't have it, then this symbol is
                    // definitely not accessible to us.
                    return(false);
                }

                // We had internal access.  Also have to make sure we have protected access.
                return(IsProtectedSymbolAccessible(withinType, throughTypeOpt, originalContainingType, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved));

            case Accessibility.ProtectedOrInternal:
                if (withinAssembly.HasInternalAccessTo(containingType.ContainingAssembly))
                {
                    // If we have internal access to this symbol, then that's sufficient.  no
                    // need to do the complicated protected case.
                    return(true);
                }

                // We don't have internal access.  But if we have protected access then that's
                // sufficient.
                return(IsProtectedSymbolAccessible(withinType, throughTypeOpt, originalContainingType, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved));

            case Accessibility.Protected:
                return(IsProtectedSymbolAccessible(withinType, throughTypeOpt, originalContainingType, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved));

            default:
                throw ExceptionUtilities.UnexpectedValue(declaredAccessibility);
            }
        }
Example #42
0
        /// <summary>
        /// Checks if 'symbol' is accessible from within 'within', which must be a NamedTypeSymbol
        /// or an AssemblySymbol.
        /// </summary>
        /// <remarks>
        /// Note that NamedTypeSymbol, if available, is the type that is associated with the binder
        /// that found the 'symbol', not the inner-most type that contains the access to the
        /// 'symbol'.
        /// <para>
        /// If 'symbol' is accessed off of an expression then 'throughTypeOpt' is the type of that
        /// expression. This is needed to properly do protected access checks. Sets
        /// "failedThroughTypeCheck" to true if this protected check failed.
        /// </para>
        /// <para>
        /// This function is expected to be called a lot.  As such, it avoids memory
        /// allocations in the function itself (including not making any iterators).  This means
        /// that certain helper functions that could otherwise be called are inlined in this method to
        /// prevent the overhead of returning collections or enumerators.
        /// </para>
        /// </remarks>
        private static bool IsSymbolAccessibleCore(
            Symbol symbol,
            Symbol within,  // must be assembly or named type symbol
            TypeSymbol throughTypeOpt,
            out bool failedThroughTypeCheck,
            CSharpCompilation compilation,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics,
            ConsList <TypeSymbol> basesBeingResolved = null)
        {
            Debug.Assert((object)symbol != null);
            Debug.Assert((object)within != null);
            Debug.Assert(within.IsDefinition);
            Debug.Assert(within is NamedTypeSymbol || within is AssemblySymbol);

            failedThroughTypeCheck = false;

            switch (symbol.Kind)
            {
            case SymbolKind.ArrayType:
                return(IsSymbolAccessibleCore(((ArrayTypeSymbol)symbol).ElementType, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved));

            case SymbolKind.PointerType:
                return(IsSymbolAccessibleCore(((PointerTypeSymbol)symbol).PointedAtType, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved));

            case SymbolKind.NamedType:
                return(IsNamedTypeAccessible((NamedTypeSymbol)symbol, within, ref useSiteDiagnostics, basesBeingResolved));

            case SymbolKind.Alias:
                return(IsSymbolAccessibleCore(((AliasSymbol)symbol).Target, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved));

            case SymbolKind.Discard:
                return(IsSymbolAccessibleCore(((DiscardSymbol)symbol).TypeWithAnnotations.Type, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved));

            case SymbolKind.ErrorType:
                // Always assume that error types are accessible.
                return(true);

            case SymbolKind.TypeParameter:
            case SymbolKind.Parameter:
            case SymbolKind.Local:
            case SymbolKind.Label:
            case SymbolKind.Namespace:
            case SymbolKind.DynamicType:
            case SymbolKind.Assembly:
            case SymbolKind.NetModule:
            case SymbolKind.RangeVariable:
                // These types of symbols are always accessible (if visible).
                return(true);

            case SymbolKind.Method:
            case SymbolKind.Property:
            case SymbolKind.Event:
            case SymbolKind.Field:
                if (!symbol.RequiresInstanceReceiver())
                {
                    // static members aren't accessed "through" an "instance" of any type.  So we
                    // null out the "through" instance here.  This ensures that we'll understand
                    // accessing protected statics properly.
                    throughTypeOpt = null;
                }

                return(IsMemberAccessible(symbol.ContainingType, symbol.DeclaredAccessibility, within, throughTypeOpt, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics));

            default:
                throw ExceptionUtilities.UnexpectedValue(symbol.Kind);
            }
        }
Example #43
0
 internal override ImmutableArray <NamedTypeSymbol> GetDeclaredInterfaces(ConsList <Symbol> basesBeingResolved)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Check the parameters of a method or property, but report that method/property rather than
 /// the parameter itself.
 /// </summary>
 private bool AddIfUsesIsNullable(Symbol symbol, ImmutableArray <ParameterSymbol> parameters, ConsList <TypeParameterSymbol> inProgress)
 {
     foreach (var parameter in parameters)
     {
         if (UsesIsNullable(parameter.Type, inProgress))
         {
             Add(symbol);
             return(true);
         }
     }
     return(false);
 }
Example #45
0
 internal override Imports GetImports(ConsList <TypeSymbol> basesBeingResolved)
 {
     return(Imports.Empty);
 }
 internal override NamedTypeSymbol GetEffectiveBaseClass(ConsList<TypeParameterSymbol> inProgress)
 {
     return this.RetargetingTranslator.Retarget(_underlyingTypeParameter.GetEffectiveBaseClass(inProgress), RetargetOptions.RetargetPrimitiveTypesByTypeCode);
 }
 internal override TypeSymbol GetFieldType(ConsList<FieldSymbol> fieldsBeingBound)
 {
     return this.type;
 }
 private bool AddIfUsesIsNullable(Symbol symbol, ImmutableArray <NamedTypeSymbol> types, ConsList <TypeParameterSymbol> inProgress)
 {
     foreach (var type in types)
     {
         if (UsesIsNullable(type, inProgress))
         {
             Add(symbol);
             return(true);
         }
     }
     return(false);
 }
Example #49
0
 internal abstract override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound);
Example #50
0
 internal override NamedTypeSymbol GetDeclaredBaseType(ConsList <Symbol> basesBeingResolved)
 {
     return(GetDeclaredBases(basesBeingResolved).Item1);
 }
Example #51
0
 internal override NamedTypeSymbol GetDeclaredBaseType(ConsList <TypeSymbol> basesBeingResolved)
 {
     return(_baseType);
 }
Example #52
0
 internal override NamedTypeSymbol GetDeclaredBaseType(ConsList <Symbol> basesBeingResolved)
 {
     throw new NotImplementedException();
 }
 internal sealed override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList<Symbol> basesBeingResolved)
 {
     return _unbound ? ImmutableArray<NamedTypeSymbol>.Empty : Map.SubstituteNamedTypes(OriginalDefinition.GetDeclaredInterfaces(basesBeingResolved));
 }
Example #54
0
 internal override ImmutableArray <NamedTypeSymbol> GetDeclaredInterfaces(ConsList <TypeSymbol> basesBeingResolved)
 {
     throw ExceptionUtilities.Unreachable;
 }
 internal override ImmutableArray<NamedTypeSymbol> InterfacesNoUseSiteDiagnostics(ConsList<Symbol> basesBeingResolved)
 {
     return ImmutableArray<NamedTypeSymbol>.Empty;
 }
Example #56
0
 internal override ImmutableArray <NamedTypeSymbol> InterfacesNoUseSiteDiagnostics(ConsList <TypeSymbol> basesBeingResolved)
 {
     throw ExceptionUtilities.Unreachable;
 }
 internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList<Symbol> basesBeingResolved)
 {
     return ImmutableArray<NamedTypeSymbol>.Empty;
 }
Example #58
0
 internal override TypeSymbol GetFieldType(ConsList <FieldSymbol> fieldsBeingBound)
 {
     return(this.RetargetingTranslator.Retarget(_underlyingField.GetFieldType(fieldsBeingBound), RetargetOptions.RetargetPrimitiveTypesByTypeCode));
 }
Example #59
0
 internal override bool IsAccessible(Symbol symbol, TypeSymbol accessThroughType, out bool failedThroughTypeCheck, ref HashSet<DiagnosticInfo> useSiteDiagnostics, ConsList<Symbol> basesBeingResolved = null)
 {
     failedThroughTypeCheck = false;
     return this.IsSymbolAccessibleConditional(symbol, Compilation.Assembly, ref useSiteDiagnostics);
 }
Example #60
0
        internal Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > GetDeclaredBases(ConsList <Symbol> basesBeingResolved)
        {
            if (ReferenceEquals(_lazyDeclaredBases, null))
            {
                DiagnosticBag diagnostics = DiagnosticBag.GetInstance();
                if (Interlocked.CompareExchange(ref _lazyDeclaredBases, MakeDeclaredBases(basesBeingResolved, diagnostics), null) == null)
                {
                    AddDeclarationDiagnostics(diagnostics);
                }

                diagnostics.Free();
            }

            return(_lazyDeclaredBases);
        }