public void ThreeItems()
		{
			var dict = new SmallDictionary<int, string>();
			dict[2] = "abc";
			dict[5] = "def";
			dict[11] = "third";
			Assert.AreEqual(3, dict.Count);
			Assert.AreEqual("abc", dict[2]);
			Assert.AreEqual("def", dict[5]);
			Assert.AreEqual("third", dict[11]);
			string output;
			Assert.IsFalse(dict.TryGetValue(3, out output));
			Assert.IsNull(output);
			Assert.IsTrue(dict.TryGetValue(2, out output));
			Assert.AreEqual("abc", output);
			Assert.IsTrue(dict.TryGetValue(5, out output));
			Assert.AreEqual("def", output);
			Assert.IsTrue(dict.TryGetValue(11, out output));
			Assert.AreEqual("third", output);

			Assert.IsFalse(dict.ContainsKey(3));
			Assert.IsTrue(dict.ContainsKey(2));
			Assert.IsTrue(dict.ContainsKey(5));
			Assert.IsTrue(dict.ContainsKey(11));
		}
Beispiel #2
0
        public override void VisitFinallyClause(FinallyClauseSyntax node)
        {
            // NOTE: We're going to cheat a bit - we know that the block is definitely going
            // to get a map entry, so we don't need to worry about the WithAdditionalFlags
            // binder being dropped.  That is, there's no point in adding the WithAdditionalFlags
            // binder to the map ourselves and having VisitBlock unconditionally overwrite it.

            // If this finally block is nested inside a catch block, we need to use a distinct
            // binder flag so that we can detect the nesting order for error CS074: A throw
            // statement with no arguments is not allowed in a finally clause that is nested inside
            // the nearest enclosing catch clause.

            var additionalFlags = BinderFlags.InFinallyBlock;

            if (_enclosing.Flags.Includes(BinderFlags.InCatchBlock))
            {
                additionalFlags |= BinderFlags.InNestedFinallyBlock;
            }

            Visit(node.Block, _enclosing.WithAdditionalFlags(additionalFlags));

            Binder finallyBinder;

            Debug.Assert(_map.TryGetValue(node.Block, out finallyBinder) && finallyBinder.Flags.Includes(BinderFlags.InFinallyBlock));
        }
		public void OneItem()
		{
			var dict = new SmallDictionary<int, string>();
			dict[2] = "abc";
			Assert.AreEqual(1, dict.Count);
			Assert.AreEqual("abc", dict[2]);
			string output;
			Assert.IsFalse(dict.TryGetValue(3, out output));
			Assert.IsNull(output);
			Assert.IsTrue(dict.TryGetValue(2, out output));
			Assert.AreEqual("abc", output);
			Assert.IsFalse(dict.ContainsKey(3));
			Assert.IsTrue(dict.ContainsKey(2));
		}
Beispiel #4
0
                private void AddIfCaptured(Symbol symbol, SyntaxNode syntax)
                {
                    Debug.Assert(
                        symbol.Kind == SymbolKind.Local ||
                        symbol.Kind == SymbolKind.Parameter ||
                        symbol.Kind == SymbolKind.Method);

                    if (_currentClosure == null)
                    {
                        // Can't be captured if we're not in a closure
                        return;
                    }

                    if (symbol is LocalSymbol local && local.IsConst)
                    {
                        // consts aren't captured since they're inlined
                        return;
                    }

                    if (symbol.ContainingSymbol != _currentClosure.OriginalMethodSymbol)
                    {
                        // Restricted types can't be hoisted, so they are not permitted to be captured
                        AddDiagnosticIfRestrictedType(symbol, syntax);

                        // Record the captured variable where it's captured
                        var scope   = _currentScope;
                        var closure = _currentClosure;
                        while (closure != null && symbol.ContainingSymbol != closure.OriginalMethodSymbol)
                        {
                            closure.CapturedVariables.Add(symbol);

                            // Also mark captured in enclosing scopes
                            while (scope.ContainingClosureOpt == closure)
                            {
                                scope = scope.Parent;
                            }
                            closure = scope.ContainingClosureOpt;
                        }

                        // Also record where the captured variable lives

                        // No need to record where local functions live: that was recorded
                        // in the Closures list in each scope
                        if (symbol.Kind == SymbolKind.Method)
                        {
                            return;
                        }

                        if (_localToScope.TryGetValue(symbol, out var declScope))
                        {
                            declScope.DeclaredVariables.Add(symbol);
                        }
                        else
                        {
                            // Parameters and locals from expression tree lambdas
                            // don't get recorded
                            Debug.Assert(_inExpressionTree);
                        }
                    }
                }
        public void TestSmallDict()
        {
            var       ht       = new SmallDictionary <int, int>();
            const int elements = 150;

            for (int i = 0; i < elements; i += 4)
            {
                ht.Add(i, i);
                ht.Add(i - 1, i - 1);
                ht.Add(i - 2, i - 2);
                ht.Add(i - 3, i - 3);
            }

            Assert.Equal(152, ht.Count());

            for (int j = 0; j < 100; j++)
            {
                for (int i = 0; i < elements; i += 4)
                {
                    int v;
                    ht.TryGetValue(i, out v);
                    Assert.Equal(i, v);

                    ht.TryGetValue(i - 1, out v);
                    Assert.Equal(i - 1, v);

                    ht.TryGetValue(i - 2, out v);
                    Assert.Equal(i - 2, v);

                    ht.TryGetValue(i - 3, out v);
                    Assert.Equal(i - 3, v);
                }
            }

            foreach (var p in ht)
            {
                Assert.Equal(p.Key, p.Value);
            }

            var keys   = ht.Keys.ToArray();
            var values = ht.Values.ToArray();

            for (int i = 0, l = ht.Count(); i < l; i++)
            {
                Assert.Equal(keys[i], values[i]);
            }
        }
        public void TestSmallDict()
        {
            var ht = new SmallDictionary<int, int>();
            const int elements = 150; 

            for (int i = 0; i < elements; i += 4)
            {
                ht.Add(i, i);
                ht.Add(i - 1, i - 1);
                ht.Add(i - 2, i - 2);
                ht.Add(i - 3, i - 3);
            }

            Assert.Equal(152, ht.Count());

            for (int j = 0; j < 100; j++)
            {
                for (int i = 0; i < elements; i += 4)
                {
                    int v;
                    ht.TryGetValue(i, out v);
                    Assert.Equal(i, v);

                    ht.TryGetValue(i - 1, out v);
                    Assert.Equal(i - 1, v);

                    ht.TryGetValue(i - 2, out v);
                    Assert.Equal(i - 2, v);

                    ht.TryGetValue(i - 3, out v);
                    Assert.Equal(i - 3, v);
                }
            }

            foreach(var p in ht)
            {
                Assert.Equal(p.Key, p.Value);
            }

            var keys = ht.Keys.ToArray();
            var values = ht.Values.ToArray();

            for (int i = 0, l = ht.Count(); i < l; i++)
            {
                Assert.Equal(keys[i], values[i]);
            }
        }
Beispiel #7
0
            static bool isValueType(
                TypeParameterSymbol thisTypeParameter,
                ImmutableArray <TypeParameterConstraintClause> constraintClauses,
                SmallDictionary <TypeParameterSymbol, bool> isValueTypeMap,
                ConsList <TypeParameterSymbol> inProgress
                )
            {
                if (inProgress.ContainsReference(thisTypeParameter))
                {
                    return(false);
                }

                if (isValueTypeMap.TryGetValue(thisTypeParameter, out bool knownIsValueType))
                {
                    return(knownIsValueType);
                }

                TypeParameterConstraintClause constraintClause = constraintClauses[
                    thisTypeParameter.Ordinal
                                                                 ];

                bool result = false;

                if (
                    (constraintClause.Constraints & TypeParameterConstraintKind.AllValueTypeKinds)
                    != 0
                    )
                {
                    result = true;
                }
                else
                {
                    Symbol container = thisTypeParameter.ContainingSymbol;
                    inProgress = inProgress.Prepend(thisTypeParameter);

                    foreach (TypeWithAnnotations constraintType in constraintClause.ConstraintTypes)
                    {
                        TypeSymbol type = constraintType.IsResolved
                            ? constraintType.Type
                            : constraintType.DefaultType;

                        if (
                            type is TypeParameterSymbol typeParameter &&
                            (object)typeParameter.ContainingSymbol == (object)container
                            )
                        {
                            if (
                                isValueType(
                                    typeParameter,
                                    constraintClauses,
                                    isValueTypeMap,
                                    inProgress
                                    )
                                )
                            {
                                result = true;
                                break;
                            }
                        }
Beispiel #8
0
                private void AddIfCaptured(Symbol symbol)
                {
                    if (_currentClosure == null)
                    {
                        // Can't be captured if we're not in a closure
                        return;
                    }

                    if (symbol is LocalSymbol local && local.IsConst)
                    {
                        // consts aren't captured since they're inlined
                        return;
                    }

                    if (symbol.ContainingSymbol != _currentClosure.OriginalMethodSymbol)
                    {
                        // Record the captured variable where it's captured
                        var scope   = _currentScope;
                        var closure = _currentClosure;
                        while (closure != null && symbol.ContainingSymbol != closure.OriginalMethodSymbol)
                        {
                            closure.CapturedVariables.Add(symbol);

                            // Also mark captured in enclosing scopes
                            while (scope.ContainingClosure == closure)
                            {
                                scope = scope.Parent;
                            }
                            closure = scope.ContainingClosure;
                        }

                        // Also record where the captured variable lives

                        // No need to record where local functions live: that was recorded
                        // in the Closures list in each scope
                        if (symbol.Kind == SymbolKind.Method)
                        {
                            return;
                        }

                        // The 'this' parameter isn't declared in method scope
                        if (symbol is ParameterSymbol param && param.IsThis)
                        {
                            return;
                        }

                        if (_localToScope.TryGetValue(symbol, out var declScope))
                        {
                            declScope.DeclaredVariables.Add(symbol);
                        }
                        else
                        {
                            // Parameters and locals from expression tree lambdas
                            // don't get recorded
                            Debug.Assert(_inExpressionTree);
                        }
                    }
                }
		public void Empty()
		{
			var dict = new SmallDictionary<int, string>();
			Assert.AreEqual(0, dict.Count);
			string output;
			Assert.IsFalse(dict.TryGetValue(2, out output));
			Assert.IsNull(output);
			Assert.IsFalse(dict.ContainsKey(3));
		}
Beispiel #10
0
        private LocalFuncUsages GetOrCreateLocalFuncUsages(LocalFunctionSymbol localFunc)
        {
            LocalFuncUsages usages;

            if (!_localFuncVarUsages.TryGetValue(localFunc, out usages))
            {
                usages = _localFuncVarUsages[localFunc] = new LocalFuncUsages(UnreachableState());
            }
            return(usages);
        }
Beispiel #11
0
        private LocalFuncUsages GetOrCreateLocalFuncUsages(LocalFunctionSymbol localFunc)
        {
            LocalFuncUsages usages;

            if (!_localFuncVarUsages.TryGetValue(localFunc, out usages))
            {
                usages = new LocalFuncUsages();
                _localFuncVarUsages[localFunc] = usages;
            }
            return(usages);
        }
        protected TLocalFunctionState GetOrCreateLocalFuncUsages(LocalFunctionSymbol localFunc)
        {
            _localFuncVarUsages ??= new SmallDictionary <LocalFunctionSymbol, TLocalFunctionState>();

            if (!_localFuncVarUsages.TryGetValue(localFunc, out TLocalFunctionState usages))
            {
                usages = CreateLocalFunctionState();
                _localFuncVarUsages[localFunc] = usages;
            }
            return(usages);
        }
Beispiel #13
0
        protected sealed override TypeSymbol SubstituteTypeParameter(TypeParameterSymbol typeParameter)
        {
            // It might need to be substituted directly.
            TypeSymbol result;

            if (Mapping.TryGetValue(typeParameter, out result))
            {
                return(result);
            }

            return(typeParameter);
        }
Beispiel #14
0
        protected sealed override TypeWithAnnotations SubstituteTypeParameter(TypeParameterSymbol typeParameter)
        {
            // It might need to be substituted directly.
            TypeWithAnnotations result;

            if (Mapping.TryGetValue(typeParameter, out result))
            {
                return(result);
            }

            return(TypeWithAnnotations.Create(typeParameter));
        }
Beispiel #15
0
        protected sealed override TypeWithModifiers SubstituteTypeParameter(TypeParameterSymbol typeParameter)
        {
            // It might need to be substituted directly.
            TypeWithModifiers result;

            if (Mapping.TryGetValue(typeParameter, out result))
            {
                if (typeParameter.NullabilityPreservation == CodeAnalysis.Symbols.NullabilityPreservationKind.None && result.Type.Kind == SymbolKind.NonNullableReference)
                {
                    return(new TypeWithModifiers(((NonNullableReferenceTypeSymbol)result.Type).UnderlyingType));
                }
                return(result);
            }

            return(new TypeWithModifiers(typeParameter));
        }
        /// <summary>
        /// Report an error if adding the edge (method1, method2) to the ctor-initializer
        /// graph would add a new cycle to that graph.
        /// </summary>
        /// <param name="method1">a calling ctor</param>
        /// <param name="method2">the chained-to ctor</param>
        /// <param name="syntax">where to report a cyclic error if needed</param>
        /// <param name="diagnostics">a diagnostic bag for receiving the diagnostic</param>
        internal void ReportCtorInitializerCycles(MethodSymbol method1, MethodSymbol method2, CSharpSyntaxNode syntax, DiagnosticBag diagnostics)
        {
            // precondition and postcondition: the graph _constructorInitializers is acyclic.
            // If adding the edge (method1, method2) would induce a cycle, we report an error
            // and do not add it to the set of edges. If it would not induce a cycle we add
            // it to the set of edges and return.

            if (method1 == method2)
            {
                // direct recursion is diagnosed elsewhere
                throw ExceptionUtilities.Unreachable;
            }

            if (_constructorInitializers == null)
            {
                _constructorInitializers = new SmallDictionary <MethodSymbol, MethodSymbol>();
                _constructorInitializers.Add(method1, method2);
                return;
            }

            MethodSymbol next = method2;

            while (true)
            {
                if (_constructorInitializers.TryGetValue(next, out next))
                {
                    Debug.Assert((object)next != null);
                    if (method1 == next)
                    {
                        // We found a (new) cycle containing the edge (method1, method2). Report an
                        // error and do not add the edge.
                        diagnostics.Add(ErrorCode.ERR_IndirectRecursiveConstructorCall, syntax.Location, method1);
                        return;
                    }
                }
                else
                {
                    // we've reached the end of the path without finding a cycle. Add the new edge.
                    _constructorInitializers.Add(method1, method2);
                    return;
                }
            }
        }
        /// <summary>
        /// Given a meaning, ensure that it is the only meaning within this scope (or report a diagnostic that it isn't).
        /// Returns true if a diagnostic was reported.  Sets done=true if there is no need to check further enclosing
        /// scopes (for example, when this meaning is the same as a previous meaning, or it can be determined that a
        /// diagnostic had previously been reported).
        /// </summary>
        private bool EnsureSingleDefinition(SingleMeaning newMeaning, DiagnosticBag diagnostics, ref bool done)
        {
            if (singleMeaningTable == null)
            {
                Interlocked.CompareExchange(ref singleMeaningTable, new SmallDictionary <string, SingleMeaning>(), null);
            }

            lock (singleMeaningTable)
            {
                SingleMeaning oldMeaning;
                if (singleMeaningTable.TryGetValue(newMeaning.Name, out oldMeaning))
                {
                    if (oldMeaning.Direct)
                    {
                        return(ResolveConflict(oldMeaning, newMeaning, diagnostics, ref done));
                    }
                    else
                    {
                        if (newMeaning.Direct)
                        {
                            singleMeaningTable[newMeaning.Name] = newMeaning;
                            return(ResolveConflict(oldMeaning, newMeaning, diagnostics, ref done));
                        }
                        else
                        {
                            // both indirect
                            if ((object)oldMeaning.Symbol != null &&
                                newMeaning.Symbol == oldMeaning.Symbol &&
                                !newMeaning.IsDefinition)
                            {
                                done = true; // optimization
                            }
                            return(false);
                        }
                    }
                }
                else
                {
                    singleMeaningTable.Add(newMeaning.Name, newMeaning);
                    return(false);
                }
            }
        }
Beispiel #18
0
        private static void DecodeGlobalSuppressMessageAttributes(Compilation compilation, ISymbol symbol, GlobalSuppressions globalSuppressions, IEnumerable <AttributeData> attributes)
        {
            foreach (var instance in attributes)
            {
                SuppressMessageInfo info;
                if (!TryDecodeSuppressMessageAttributeData(instance, out info))
                {
                    continue;
                }

                string scopeString = info.Scope != null?info.Scope.ToLowerInvariant() : null;

                TargetScope scope;

                if (s_suppressMessageScopeTypes.TryGetValue(scopeString, out scope))
                {
                    if ((scope == TargetScope.Module || scope == TargetScope.None) && info.Target == null)
                    {
                        // This suppression is applies to the entire compilation
                        globalSuppressions.AddCompilationWideSuppression(info);
                        continue;
                    }
                }
                else
                {
                    // Invalid value for scope
                    continue;
                }

                // Decode Target
                if (info.Target == null)
                {
                    continue;
                }

                foreach (var target in ResolveTargetSymbols(compilation, info.Target, scope))
                {
                    globalSuppressions.AddGlobalSymbolSuppression(target, info);
                }
            }
        }
 private static bool TryGetTargetScope(SuppressMessageInfo info, out TargetScope scope)
 => s_suppressMessageScopeTypes.TryGetValue(info.Scope ?? string.Empty, out scope);
Beispiel #20
0
        public ITsString get_String(int ws)
        {
            ITsString tss;

            return(m_strings.TryGetValue(ws, out tss) ? tss : TsStringUtils.EmptyString(ws));
        }
		public void Remove()
		{
			var dict = new SmallDictionary<int, string>();
			Assert.IsFalse(dict.Remove(2), "Remove a missing item from an empty dictionary");
			dict.Add(2, "abc");
			Assert.IsFalse(dict.Remove(3), "Remove a missing item from a dictionary with one item");
			Assert.IsTrue(dict.Remove(2), "Remove the only item from a dictionary");
			Assert.AreEqual(0, dict.Count, "Nothing remains after removing the only item");
			dict.Add(2, "abc");
			dict.Add(5, "def");
			dict.Add(11, "third");
			Assert.IsFalse(dict.Remove(7), "Remove a missing item from a dictionary with three items");
			Assert.IsTrue(dict.Remove(2), "Remove the first item from a dictionary with three items");
			Assert.AreEqual(2, dict.Count, "Two items remain after removing the first of three");
			string output;
			Assert.IsFalse(dict.TryGetValue(2, out output), "Removed item (first) should be gone from original three");
			Assert.AreEqual("def", dict[5]);
			Assert.AreEqual("third", dict[11]);
			dict.Add(2, "abc");
			Assert.IsTrue(dict.Remove(5), "Remove first of two items in others");
			Assert.AreEqual(2, dict.Count);
			Assert.IsFalse(dict.TryGetValue(5, out output));
			Assert.AreEqual("abc", dict[2]);
			Assert.AreEqual("third", dict[11]);

			Assert.IsTrue(dict.Remove(2), "Remove only item in others");
			Assert.AreEqual(1, dict.Count);
			Assert.IsFalse(dict.TryGetValue(2, out output));
			Assert.AreEqual("third", dict[11]);

			Assert.IsTrue(dict.Remove(11), "Remove only item in dictionary which previously had three");
			Assert.AreEqual(0, dict.Count);
			Assert.IsFalse(dict.TryGetValue(11, out output));

			dict.Add(2, "abc");
			dict.Add(5, "def");
			dict.Add(11, "third");
			dict.Add(13, "fourth");
			Assert.IsTrue(dict.Remove(11), "Remove middle of three items in others");
			Assert.AreEqual(3, dict.Count);
			Assert.IsFalse(dict.TryGetValue(11, out output));
			Assert.AreEqual("abc", dict[2]);
			Assert.AreEqual("def", dict[5]);
			Assert.AreEqual("fourth", dict[13]);

			Assert.IsTrue(dict.Remove(13), "Remove last of two items in others");
			Assert.AreEqual(2, dict.Count);
			Assert.IsFalse(dict.TryGetValue(13, out output));
			Assert.AreEqual("abc", dict[2]);
			Assert.AreEqual("def", dict[5]);

			Assert.IsTrue(dict.Remove(2), "Remove first item when others contains exactly one");
			Assert.AreEqual(1, dict.Count);
			Assert.IsFalse(dict.TryGetValue(2, out output));
			Assert.AreEqual("def", dict[5]);
		}