// 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); } }
internal AdditionalSourcesCollection(ImmutableArray <GeneratedSourceText> sources) : this() { foreach (var source in sources) { _sourcesAdded.Add(source.HintName, source.Text); } }
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); }
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); }
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; } }
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)); }
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)); }
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); }
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 } } }
/// <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); }
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); } } }
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)); }
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); } }
/// <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); }
/// <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); } } }
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]); } }
/// <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)); }
/// <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); } }
/// <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); }