예제 #1
0
            // Local functions
            static void ProcessWildcardName(NameParts parts, PooledDictionary <SymbolKind, PooledDictionary <string, TValue> > wildcardNamesBuilder)
            {
                Debug.Assert(parts.SymbolName[parts.SymbolName.Length - 1] == WildcardChar);
                Debug.Assert(parts.SymbolName.Length >= 2);

                if (parts.SymbolName[1] != ':')
                {
                    if (!wildcardNamesBuilder.ContainsKey(AllKinds))
                    {
                        wildcardNamesBuilder.Add(AllKinds, PooledDictionary <string, TValue> .GetInstance());
                    }
                    wildcardNamesBuilder[AllKinds].Add(parts.SymbolName.Substring(0, parts.SymbolName.Length - 1), parts.AssociatedValue);
                    return;
                }

                var symbolKind = parts.SymbolName[0] switch
                {
                    'E' => (SymbolKind?)SymbolKind.Event,
                    'F' => SymbolKind.Field,
                    'M' => SymbolKind.Method,
                    'N' => SymbolKind.Namespace,
                    'P' => SymbolKind.Property,
                    'T' => SymbolKind.NamedType,
                    _ => null,
                };

                if (symbolKind != null)
                {
                    if (!wildcardNamesBuilder.ContainsKey(symbolKind.Value))
                    {
                        wildcardNamesBuilder.Add(symbolKind.Value, PooledDictionary <string, TValue> .GetInstance());
                    }
                    wildcardNamesBuilder[symbolKind.Value].Add(parts.SymbolName.Substring(2, parts.SymbolName.Length - 3), parts.AssociatedValue);
                }
            }
예제 #2
0
 internal AdditionalSourcesCollection(ImmutableArray <GeneratedSourceText> sources)
     : this()
 {
     foreach (var source in sources)
     {
         _sourcesAdded.Add(source.HintName, source.Text);
     }
 }
예제 #3
0
            public void AddThrow(TypeSymbol type, SyntaxNode syntax)
            {
                PooledHashSet <SyntaxNode> nodes;

                if (!ThrowLocations.TryGetValue(type, out nodes))
                {
                    nodes = PooledHashSet <SyntaxNode> .GetInstance();

                    ThrowLocations.Add(type, nodes);
                }
                nodes.Add(syntax);
            }
예제 #4
0
                public BoundExpression GetTemp(BoundDagTemp dagTemp)
                {
                    if (!_map.TryGetValue(dagTemp, out BoundExpression result))
                    {
                        LocalSymbol temp = _factory.SynthesizedLocal(dagTemp.Type, syntax: _node, kind: SynthesizedLocalKind.SwitchCasePatternMatching);
                        result = _factory.Local(temp);
                        _map.Add(dagTemp, result);
                        _temps.Add(temp);
                    }

                    return(result);
                }
                public BoundExpression GetTemp(BoundDagTemp dagTemp)
                {
                    if (!_map.TryGetValue(dagTemp, out BoundExpression result))
                    {
                        var         kind = _generateSequencePoints ? SynthesizedLocalKind.SwitchCasePatternMatching : SynthesizedLocalKind.LoweringTemp;
                        LocalSymbol temp = _factory.SynthesizedLocal(dagTemp.Type, syntax: _node, kind: kind);
                        result = _factory.Local(temp);
                        _map.Add(dagTemp, result);
                        _temps.Add(temp);
                    }

                    return(result);
                }
예제 #6
0
        private void EmitSavePreviousSequencePoint(BoundSavePreviousSequencePoint statement)
        {
            if (!_emitPdbSequencePoints)
            {
                return;
            }

            ArrayBuilder <RawSequencePoint> sequencePoints = _builder.SeqPointsOpt;

            if (sequencePoints is null)
            {
                return;
            }

            for (int i = sequencePoints.Count - 1; i >= 0; i--)
            {
                var span = sequencePoints[i].Span;
                if (span == RawSequencePoint.HiddenSequencePointSpan)
                {
                    continue;
                }

                // Found the previous non-hidden sequence point.  Save it.
                _savedSequencePoints ??= PooledDictionary <object, TextSpan> .GetInstance();

                _savedSequencePoints.Add(statement.Identifier, span);
                return;
            }
        }
예제 #7
0
        public static CompletionItem Create(INamedTypeSymbol typeSymbol, string containingNamespace)
        {
            PooledDictionary <string, string> propertyBuilder = null;

            if (typeSymbol.Arity > 0)
            {
                propertyBuilder = PooledDictionary <string, string> .GetInstance();

                propertyBuilder.Add(TypeAritySuffixName, GetAritySuffix(typeSymbol.Arity));
            }

            // Hack: add tildes (ASCII: 126) to name and namespace as sort text:
            // 1. '~' before type name makes import items show after in-scope items
            // 2. ' ' before namespace makes types with identical type name but from different namespace all show up in the list,
            //    it also makes sure type with shorter name shows first, e.g. 'SomeType` before 'SomeTypeWithLongerName'.
            var sortTextBuilder = PooledStringBuilder.GetInstance();

            sortTextBuilder.Builder.AppendFormat(SortTextFormat, typeSymbol.Name, containingNamespace);

            // TODO:
            // 1. Suffix should be language specific, i.e. `(Of ...)` if triggered from VB.
            // 2. Sort the import items to be after in-scope symbols in a less hacky way.
            // 3. Editor support for resolving item text conflicts?
            return(CompletionItem.Create(
                       displayText: typeSymbol.Name,
                       filterText: typeSymbol.Name,
                       sortText: sortTextBuilder.ToStringAndFree(),
                       properties: propertyBuilder?.ToImmutableDictionaryAndFree(),
                       tags: GlyphTags.GetTags(typeSymbol.GetGlyph()),
                       rules: CompletionItemRules.Default,
                       displayTextPrefix: null,
                       displayTextSuffix: typeSymbol.Arity == 0 ? string.Empty : "<>",
                       inlineDescription: containingNamespace));
        }
예제 #8
0
        public static CompletionItem Create(INamedTypeSymbol typeSymbol, string containingNamespace, string genericTypeSuffix)
        {
            PooledDictionary <string, string> propertyBuilder = null;

            if (typeSymbol.Arity > 0)
            {
                propertyBuilder = PooledDictionary <string, string> .GetInstance();

                propertyBuilder.Add(TypeAritySuffixName, GetAritySuffix(typeSymbol.Arity));
            }

            // Add tildes (ASCII: 126) to name and namespace as sort text:
            // 1. '~' before type name makes import items show after in-scope items
            // 2. ' ' before namespace makes types with identical type name but from different namespace all show up in the list,
            //    it also makes sure type with shorter name shows first, e.g. 'SomeType` before 'SomeTypeWithLongerName'.
            var sortTextBuilder = PooledStringBuilder.GetInstance();

            sortTextBuilder.Builder.AppendFormat(SortTextFormat, typeSymbol.Name, containingNamespace);

            return(CompletionItem.Create(
                       displayText: typeSymbol.Name,
                       filterText: typeSymbol.Name,
                       sortText: sortTextBuilder.ToStringAndFree(),
                       properties: propertyBuilder?.ToImmutableDictionaryAndFree(),
                       tags: GlyphTags.GetTags(typeSymbol.GetGlyph()),
                       rules: CompletionItemRules.Default,
                       displayTextPrefix: null,
                       displayTextSuffix: typeSymbol.Arity == 0 ? string.Empty : genericTypeSuffix,
                       inlineDescription: containingNamespace));
        }
예제 #9
0
 static void ProcessName(NameParts parts, PooledDictionary <string, TValue> namesBuilder)
 {
     if (!namesBuilder.ContainsKey(parts.SymbolName))
     {
         namesBuilder.Add(parts.SymbolName, parts.AssociatedValue);
     }
 }
        public void GlobalSetup()
        {
            pooled = CreatePooled(N);
            dict   = CreateDictionary(N);

            // needs a specific seed to prevent key collision with TestData
            dict.Add(key, 12);
            pooled.Add(key, 12);
        }
예제 #11
0
        protected virtual int GetOrCreateSlot(Symbol symbol, int containingSlot = 0, bool forceSlotEvenIfEmpty = false)
        {
            Debug.Assert(containingSlot >= 0);
            Debug.Assert(symbol != null);

            if (symbol.Kind == SymbolKind.RangeVariable)
            {
                return(-1);
            }

            containingSlot = DescendThroughTupleRestFields(ref symbol, containingSlot, forceContainingSlotsToExist: true);

            if (containingSlot < 0)
            {
                // Error case. Diagnostics should already have been produced.
                return(-1);
            }

            VariableIdentifier identifier = new VariableIdentifier(symbol, containingSlot);
            int slot;

            // Since analysis may proceed in multiple passes, it is possible the slot is already assigned.
            if (!_variableSlot.TryGetValue(identifier, out slot))
            {
                var variableType = symbol.GetTypeOrReturnType().Type;
                if (!forceSlotEvenIfEmpty && IsEmptyStructType(variableType))
                {
                    return(-1);
                }

                if (_maxSlotDepth > 0 && GetSlotDepth(containingSlot) >= _maxSlotDepth)
                {
                    return(-1);
                }

                slot = nextVariableSlot++;
                _variableSlot.Add(identifier, slot);
                if (slot >= variableBySlot.Length)
                {
                    Array.Resize(ref this.variableBySlot, slot * 2);
                }

                variableBySlot[slot] = identifier;
            }

            if (IsConditionalState)
            {
                Normalize(ref this.StateWhenTrue);
                Normalize(ref this.StateWhenFalse);
            }
            else
            {
                Normalize(ref this.State);
            }

            return(slot);
        }
            protected virtual LabelSymbol GetDagNodeLabel(BoundDecisionDagNode dag)
            {
                if (!_dagNodeLabels.TryGetValue(dag, out LabelSymbol? label))
                {
                    _dagNodeLabels.Add(dag, label = dag is BoundLeafDecisionDagNode d ? d.Label : _factory.GenerateLabel("dagNode"));
                }

                return(label);
            }
 static void AddPlatformsFromMsBuildOptions(PooledDictionary <string, int> knownPlatforms, ImmutableArray <string> msBuildPlatforms)
 {
     foreach (var platform in msBuildPlatforms)
     {
         if (!knownPlatforms.ContainsKey(platform))
         {
             knownPlatforms.Add(platform, 4); // Default version count is 4
         }
     }
 }
예제 #14
0
        /// <summary>
        /// Creates a <see cref="PooledDictionary{TKey,TValue}"/> from a <see cref="ReadOnlySpan{TSource}"/> according to specified
        /// key selector and element selector functions, as well as a comparer.
        /// </summary>
        public static PooledDictionary <TKey, TValue> ToPooledDictionary <TSource, TKey, TValue>(this ReadOnlySpan <TSource> source,
                                                                                                 Func <TSource, TKey> keySelector, Func <TSource, TValue> valueSelector, IEqualityComparer <TKey> comparer = null)
        {
            var dict = new PooledDictionary <TKey, TValue>(source.Length, comparer);

            foreach (var item in source)
            {
                dict.Add(keySelector(item), valueSelector(item));
            }
            return(dict);
        }
        public void Dictionary_Generic_ValueCollection_GetEnumerator(int count)
        {
            var dictionary = new PooledDictionary <string, string>();
            int seed       = 13453;

            while (dictionary.Count < count)
            {
                dictionary.Add(CreateT(seed++), CreateT(seed++));
            }
            dictionary.Values.GetEnumerator();
            dictionary.Dispose();
        }
        public virtual void GlobalSetup()
        {
            pooled = new PooledDictionary <T, T>(Comparer);
            dict   = new Dictionary <T, T>(Comparer);

            for (int i = 0; i < N; i++)
            {
                T t = GetT(i);
                pooled.Add(t, t);
                dict.Add(t, t);
            }
        }
        protected override ICollection NonGenericICollectionFactory(int count)
        {
            var dict = new PooledDictionary <string, string>();

            RegisterForDispose(dict);
            int seed = 13453;

            for (int i = 0; i < count; i++)
            {
                dict.Add(CreateT(seed++), CreateT(seed++));
            }
            return(dict.Values);
        }
예제 #18
0
            static void ProcessSymbolName(NameParts parts, Compilation compilation, string?optionalPrefix, PooledDictionary <ISymbol, TValue> symbolsBuilder)
            {
                var nameWithPrefix = (string.IsNullOrEmpty(optionalPrefix) || parts.SymbolName.StartsWith(optionalPrefix, StringComparison.Ordinal))
                    ? parts.SymbolName
                    : optionalPrefix + parts.SymbolName;

#pragma warning disable CA1307 // Specify StringComparison - https://github.com/dotnet/roslyn-analyzers/issues/1552
                // Documentation comment ID for constructors uses '#ctor', but '#' is a comment start token for editorconfig.
                // We instead search for a '..ctor' in editorconfig and replace it with a '.#ctor' here.
                // Similarly, handle static constructors ".cctor"
                nameWithPrefix = nameWithPrefix.Replace("..ctor", ".#ctor");
                nameWithPrefix = nameWithPrefix.Replace("..cctor", ".#cctor");
#pragma warning restore

                foreach (var symbol in DocumentationCommentId.GetSymbolsForDeclarationId(nameWithPrefix, compilation))
                {
                    if (symbol == null)
                    {
                        continue;
                    }

                    if (symbol is INamespaceSymbol namespaceSymbol &&
                        namespaceSymbol.ConstituentNamespaces.Length > 1)
                    {
                        foreach (var constituentNamespace in namespaceSymbol.ConstituentNamespaces)
                        {
                            if (!symbolsBuilder.ContainsKey(constituentNamespace))
                            {
                                symbolsBuilder.Add(constituentNamespace, parts.AssociatedValue);
                            }
                        }
                    }

                    if (!symbolsBuilder.ContainsKey(symbol))
                    {
                        symbolsBuilder.Add(symbol, parts.AssociatedValue);
                    }
                }
            }
예제 #19
0
        public void GlobalSetup()
        {
            dict   = new Dictionary <long?, long?>(N);
            pooled = new PooledDictionary <long?, long?>(N);
            items  = new long?[N];

            for (long i = 0; i < N; ++i)
            {
                items[i] = i;
                dict.Add(i, i);
                pooled.Add(i, i);
            }
        }
        public void Dictionary_Generic_ContainsValue_Present(int count)
        {
            PooledDictionary <TKey, TValue> dictionary = (PooledDictionary <TKey, TValue>)GenericIDictionaryFactory(count);
            int seed = 4315;
            KeyValuePair <TKey, TValue> notPresent = CreateT(seed++);

            while (dictionary.Contains(notPresent))
            {
                notPresent = CreateT(seed++);
            }
            dictionary.Add(notPresent.Key, notPresent.Value);
            Assert.True(dictionary.ContainsValue(notPresent.Value));
        }
예제 #21
0
        public void GlobalSetup()
        {
            pooled = new PooledDictionary <int?, int?>();
            for (int i = 0; i < N; i++)
            {
                pooled.Add(i, i);
            }

            dict = new Dictionary <int?, int?>();
            for (int i = 0; i < N; i++)
            {
                dict.Add(i, i);
            }
        }
        public void GlobalSetup()
        {
            pooled = CreatePooled(N);
            for (int i = 1; i <= 9; i++)
            {
                pooled.Add(i, 0);
            }

            dict = CreateDictionary(N);
            for (int i = 1; i <= 9; i++)
            {
                dict.Add(i, 0);
            }
        }
예제 #23
0
        /// <summary>
        /// Creates a <see cref="PooledDictionary{TKey,TValue}"/> from an <see cref="IEnumerable{TSource}"/> according to specified
        /// key selector and element selector functions, as well as a comparer.
        /// </summary>
        public static PooledDictionary <TKey, TValue> ToPooledDictionary <TSource, TKey, TValue>(this IEnumerable <TSource> source,
                                                                                                 Func <TSource, TKey> keySelector, Func <TSource, TValue> valueSelector, IEqualityComparer <TKey> comparer = null)
        {
            if (source == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
            }
            var dict = new PooledDictionary <TKey, TValue>((source as ICollection <TSource>)?.Count ?? 0, comparer);

            foreach (var item in source)
            {
                dict.Add(keySelector(item), valueSelector(item));
            }
            return(dict);
        }
예제 #24
0
 /// <summary>
 /// If an expression node that declares synthesized short-lived locals (currently only sequence) contains
 /// a spill sequence (from an await or switch expression), these locals become long-lived since their
 /// values may be read by code that follows. We promote these variables to long-lived of kind
 /// <see cref="SynthesizedLocalKind.Spill"/>.
 /// </summary>
 private void PromoteAndAddLocals(BoundSpillSequenceBuilder builder, ImmutableArray <LocalSymbol> locals)
 {
     foreach (var local in locals)
     {
         if (local.SynthesizedKind.IsLongLived())
         {
             builder.AddLocal(local);
         }
         else
         {
             LocalSymbol longLived = local.WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind.Spill, _F.Syntax);
             _tempSubstitution.Add(local, longLived);
             builder.AddLocal(longLived);
         }
     }
 }
예제 #25
0
        public void TestResize()
        {
            using var dict = new PooledDictionary <int, int>();

            for (int i = 0; i < 25; i++)
            {
                dict.Add(new KeyValuePair <int, int>(i, i));
            }

            Assert.True(dict.Capacity > 25);

            for (int i = 0; i < 25; i++)
            {
                Assert.Equal(i, dict[i]);
            }
        }
예제 #26
0
 /// <summary>
 /// If an expression node that declares synthesized short-lived locals (currently only sequence) contains an await, these locals become long-lived since their
 /// values may be read by code that follows the await. We promote these variables to long-lived of kind <see cref="SynthesizedLocalKind.AwaitSpill"/>.
 /// </summary>
 private void PromoteAndAddLocals(BoundSpillSequenceBuilder builder, ImmutableArray <LocalSymbol> locals)
 {
     foreach (var local in locals)
     {
         if (local.SynthesizedKind.IsLongLived())
         {
             builder.AddLocal(local, _F.Diagnostics);
         }
         else
         {
             Debug.Assert(_F.Syntax.IsKind(SyntaxKind.AwaitExpression));
             LocalSymbol longLived = local.WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind.AwaitSpill, _F.Syntax);
             _tempSubstitution.Add(local, longLived);
             builder.AddLocal(longLived, _F.Diagnostics);
         }
     }
 }
        public async Task DictionaryConcurrentAccessDetection_ValueTypeKey(Type comparerType)
        {
            IEqualityComparer <int> customComparer = null;

            PooledDictionary <int, int> dic = comparerType == null ?
                                              new PooledDictionary <int, int>() :
                                              new PooledDictionary <int, int>((customComparer = (IEqualityComparer <int>)Activator.CreateInstance(comparerType)));

            dic.Add(1, 1);

            await DictionaryConcurrentAccessDetection(dic,
                                                      typeof(int).IsValueType,
                                                      customComparer,
                                                      add : d => d.Add(1, 1),
                                                      get : d => { var v = d[1]; },
                                                      remove : d => d.Remove(1),
                                                      removeOutParam : d => d.Remove(1, out int value));
        }
예제 #28
0
        /// <summary>
        /// If an expression node that declares synthesized short-lived locals (currently only sequence) contains an await, these locals become long-lived since their
        /// values may be read by code that follows the await. We promote these variables to long-lived of kind <see cref="SynthesizedLocalKind.AwaitSpill"/>.
        /// </summary>
        private void PromoteAndAddLocals(BoundSpillSequenceBuilder builder, ImmutableArray <LocalSymbol> locals)
        {
            foreach (var local in locals)
            {
                if (local.SynthesizedLocalKind.IsLongLived())
                {
                    builder.AddLocal(local, F.Diagnostics);
                }
                else
                {
                    SynthesizedLocal shortLived = (SynthesizedLocal)local;
                    SynthesizedLocal longLived  = shortLived.WithSynthesizedLocalKind(SynthesizedLocalKind.AwaitSpill);
                    tempSubstitution.Add(shortLived, longLived);

                    builder.AddLocal(longLived, F.Diagnostics);
                }
            }
        }
            protected BaseSwitchLocalRewriter(
                SyntaxNode node,
                LocalRewriter localRewriter,
                ImmutableArray <SyntaxNode> arms,
                bool isSwitchStatement)
                : base(node, localRewriter)
            {
                this._isSwitchStatement = isSwitchStatement;
                foreach (var arm in arms)
                {
                    var armBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                    // We start each switch block with a hidden sequence point so that
                    // we do not appear to be in the previous switch block when we begin.
                    armBuilder.Add(_factory.HiddenSequencePoint());
                    _switchArms.Add(arm, armBuilder);
                }
            }
예제 #30
0
        /// <summary>
        /// Force a variable to have a slot.  Returns -1 if the variable has an empty struct type.
        /// </summary>
        protected int GetOrCreateSlot(Symbol symbol, int containingSlot = 0)
        {
            if (symbol.Kind == SymbolKind.RangeVariable)
            {
                return(-1);
            }

            containingSlot = DescendThroughTupleRestFields(ref symbol, containingSlot, forceContainingSlotsToExist: true);

            VariableIdentifier identifier = new VariableIdentifier(symbol, containingSlot);
            int slot;

            // Since analysis may proceed in multiple passes, it is possible the slot is already assigned.
            if (!_variableSlot.TryGetValue(identifier, out slot))
            {
                var variableType = VariableType(symbol).TypeSymbol;
                if (_emptyStructTypeCache.IsEmptyStructType(variableType))
                {
                    return(-1);
                }

                slot = nextVariableSlot++;
                _variableSlot.Add(identifier, slot);
                if (slot >= variableBySlot.Length)
                {
                    Array.Resize(ref this.variableBySlot, slot * 2);
                }

                variableBySlot[slot] = identifier;
            }

            if (IsConditionalState)
            {
                Normalize(ref this.StateWhenTrue);
                Normalize(ref this.StateWhenFalse);
            }
            else
            {
                Normalize(ref this.State);
            }

            return(slot);
        }