int[] myArray = ArrayBuilder.Create(1, 2, 3, 4, 5);
string[] myArray = ArrayBuilder.Create(10);
object[] myArray = ArrayBuilder.Create(); myArray[0] = "hello"; myArray[1] = 123; In all three examples, the created array is returned using the static Create method of the ArrayBuilder class. The first example uses the predefined values to create an array, while the second example sets an initial capacity of 10 for the array. In the third example, the array is created with a dynamic size and values are added afterwards. The CSharp ArrayBuilder library belongs to the .NET framework's System.Collections.Generic namespace. C# (CSharp) ArrayBuilder - 60 examples found. These are the top rated real world C# (CSharp) examples of ArrayBuilder extracted from open source projects. You can rate examples to help us improve the quality of examples. Frequently Used Methods Show Hide Add(30) Clear(30) Build(30) AddIfNotNull(20) Any(19) Append(19) AddRange(16) Contains(15) Create(9) AddIfNotExists(5) All(4) AddOptional(3) Close(3) CopyTo(2) AppendToArray(2) AsSlice(2) AsSpan(2) Clip(2) Concat(1) CloseAndSlice(1) AsReadonlySpan(1) ChangeArrayType(1) BuildSquareArray(1) BinarySearch(1) Add2(1) AsImmutable(1) AsEnumerable(1) AddMany(1) AddLast(1) Add4(1) Where(1) Frequently Used Methods Add (30) Clear (30) Build (30) AddIfNotNull (20) Any (19) Append (19) AddRange (16) Contains (15) Create (9) AddIfNotExists (5) Frequently Used Methods All (4) AddOptional (3) Close (3) CopyTo (2) AppendToArray (2) AsSlice (2) AsSpan (2) Clip (2) Concat (1) CloseAndSlice (1) AsReadonlySpan (1) ChangeArrayType (1) BuildSquareArray (1) BinarySearch (1) Add2 (1) AsImmutable (1) AsEnumerable (1) AddMany (1) AddLast (1) Add4 (1) Frequently Used Methods AsReadonlySpan (1) ChangeArrayType (1) BuildSquareArray (1) BinarySearch (1) Add2 (1) AsImmutable (1) AsEnumerable (1) AddMany (1) AddLast (1) Add4 (1) Where (1) Related in langs vfsStreamWrapper (PHP) WC_Gateway_Paypal (PHP) forward_mulpv_op_dir (C++) timer_enable (C++) Open (Go) StringProperty (Go) TaskTracker (Java) TaskExecutionInfo (Java) getRole (Python) loads (Python) Frequently Used Methods Where (1) Related Order XsollaPricepoint PushData PREPreferentialLog ExportNsiItemModel ResourceHarvestSuccessEventArgs ListProductores CG_ASK_STORYCOPYSCENE_SWEEP CustomerProfileFromTransactionRequestData SysEnvironmentSerialize Example #1 0 Show file File: SymbolDescriptionVisitor.Types.cs Project: EkardNT/Roslyn protected internal override object VisitPointerType(PointerTypeSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder) { VisitType(symbol.PointedAtType, builder); AddPunctuation(SyntaxKind.AsteriskToken, builder); return null; } Example #2 0 Show file File: SourceGeneratorExtensions.cs Project: Rookieek/roslyn internal Context(ArrayBuilder<SyntaxTree> builder, Compilation compilation, string path, bool writeToDisk) { _builder = builder; _compilation = compilation; _path = path; _writeToDisk = writeToDisk; } Example #3 0 Show file File: SymbolDescriptionVisitor.Types.cs Project: EkardNT/Roslyn protected internal override object VisitArrayType(ArrayTypeSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder) { //See spec section 12.1 for the order of rank specificiers //e.g. int[][,][,,] is stored as // ArrayType // Rank = 1 // ElementType = ArrayType // Rank = 2 // ElementType = ArrayType // Rank = 3 // ElementType = int TypeSymbol underlyingNonArrayType = symbol.ElementType; while (underlyingNonArrayType.TypeKind == TypeKind.ArrayType) { underlyingNonArrayType = ((ArrayTypeSymbol)underlyingNonArrayType).ElementType; } VisitType(underlyingNonArrayType, builder); ArrayTypeSymbol arrayType = symbol; while (arrayType != null) { AddArrayRank(arrayType, builder); arrayType = arrayType.ElementType as ArrayTypeSymbol; } return null; } Example #4 0 Show file File: VbStringDisplay.cs Project: EkardNT/Roslyn internal static void AddSymbolDisplayParts(ArrayBuilder<SymbolDisplayPart> parts, string str) { PooledStringBuilder pooledBuilder = PooledStringBuilder.GetInstance(); StringBuilder sb = pooledBuilder.Builder; int lastKind = -1; foreach (int token in TokenizeString(str, quote: true, nonPrintableSubstitute: '\0', useHexadecimalNumbers: true)) { int kind = token >> 16; // merge contiguous tokens of the same kind into a single part: if (lastKind >= 0 && lastKind != kind) { parts.Add(new SymbolDisplayPart((SymbolDisplayPartKind)lastKind, null, sb.ToString())); sb.Clear(); } lastKind = kind; sb.Append(unchecked((char)token)); } if (lastKind >= 0) { parts.Add(new SymbolDisplayPart((SymbolDisplayPartKind)lastKind, null, sb.ToString())); } pooledBuilder.Free(); } Example #5 0 Show file File: LocalRewriter_PatternSwitchStatement.cs Project: Rickinio/roslyn /// <summary> /// Lower the given decision tree into the given statement builder. /// </summary> public void LowerDecisionTree(BoundExpression expression, DecisionTree decisionTree, ArrayBuilder<BoundStatement> loweredDecisionTree) { var oldLoweredDecisionTree = this._loweredDecisionTree; this._loweredDecisionTree = loweredDecisionTree; LowerDecisionTree(expression, decisionTree); this._loweredDecisionTree = oldLoweredDecisionTree; } Example #6 0 Show file File: TupleExpansion.cs Project: orthoxerox/roslyn internal override void GetRows( ResultProvider resultProvider, ArrayBuilder<EvalResult> rows, DkmInspectionContext inspectionContext, EvalResultDataItem parent, DkmClrValue value, int startIndex, int count, bool visitAll, ref int index) { var fields = GetFields(); int startIndex2; int count2; GetIntersection(startIndex, count, index, fields.Count, out startIndex2, out count2); int offset = startIndex2 - index; for (int i = 0; i < count2; i++) { var row = GetMemberRow(resultProvider, inspectionContext, value, fields[i + offset], parent); rows.Add(row); } index += fields.Count; } Example #7 0 Show file File: MergedAliases.cs Project: SoumikMukherjeeDOTNET/roslyn /// <summary> /// Adds aliases of a specified reference to the merged set of aliases. /// Consider the following special cases: /// /// o {} + {} = {} /// If neither reference has any aliases then the result has no aliases. /// /// o {A} + {} = {A, global} /// {} + {A} = {A, global} /// /// If one and only one of the references has aliases we add the global alias since the /// referenced declarations should now be accessible both via existing aliases /// as well as unqualified. /// /// o {A, A} + {A, B, B} = {A, A, B, B} /// We preserve dups in each alias array, but avoid making more dups when merging. /// </summary> internal void Merge(MetadataReference reference) { if (reference.Properties.HasRecursiveAliases) { if (RecursiveAliasesOpt == null) { RecursiveAliasesOpt = ArrayBuilder<string>.GetInstance(); RecursiveAliasesOpt.AddRange(reference.Properties.Aliases); return; } } else { if (AliasesOpt == null) { AliasesOpt = ArrayBuilder<string>.GetInstance(); AliasesOpt.AddRange(reference.Properties.Aliases); return; } } Merge( aliases: reference.Properties.HasRecursiveAliases ? RecursiveAliasesOpt : AliasesOpt, newAliases: reference.Properties.Aliases); } Example #8 0 Show file File: LocalRewriter_DeconstructionAssignmentOperator.cs Project: Rickinio/roslyn private void AccessTupleFields(BoundDeconstructionAssignmentOperator node, BoundDeconstructionDeconstructStep deconstruction, ArrayBuilder<LocalSymbol> temps, ArrayBuilder<BoundExpression> stores, ArrayBuilder<BoundValuePlaceholderBase> placeholders) { var target = PlaceholderReplacement(deconstruction.TargetPlaceholder); var tupleType = target.Type.IsTupleType ? target.Type : TupleTypeSymbol.Create((NamedTypeSymbol)target.Type); var tupleElementTypes = tupleType.TupleElementTypes; var numElements = tupleElementTypes.Length; CSharpSyntaxNode syntax = node.Syntax; // save the target as we need to access it multiple times BoundAssignmentOperator assignmentToTemp; var savedTuple = _factory.StoreToTemp(target, out assignmentToTemp); stores.Add(assignmentToTemp); temps.Add(savedTuple.LocalSymbol); // list the tuple fields accessors var fields = tupleType.TupleElementFields; for (int i = 0; i < numElements; i++) { var field = fields[i]; DiagnosticInfo useSiteInfo = field.GetUseSiteDiagnostic(); if ((object)useSiteInfo != null && useSiteInfo.Severity == DiagnosticSeverity.Error) { Symbol.ReportUseSiteDiagnostic(useSiteInfo, _diagnostics, syntax.Location); } var fieldAccess = MakeTupleFieldAccess(syntax, field, savedTuple, null, LookupResultKind.Empty); AddPlaceholderReplacement(deconstruction.OutputPlaceholders[i], fieldAccess); placeholders.Add(deconstruction.OutputPlaceholders[i]); } } Example #9 0 Show file File: SequencePointList.cs Project: SoumikMukherjeeDOTNET/roslyn /// <summary> /// Create a SequencePointList with the raw sequence points from an ArrayBuilder. /// A linked list of instances for each syntax tree is created (almost always of length one). /// </summary> public static SequencePointList Create(ArrayBuilder<RawSequencePoint> seqPointBuilder, ILBuilder builder) { if (seqPointBuilder.Count == 0) { return SequencePointList.s_empty; } SequencePointList first = null, current = null; int totalPoints = seqPointBuilder.Count; int last = 0; for (int i = 1; i <= totalPoints; ++i) { if (i == totalPoints || seqPointBuilder[i].SyntaxTree != seqPointBuilder[i - 1].SyntaxTree) { // Create a new list SequencePointList next = new SequencePointList(seqPointBuilder[i - 1].SyntaxTree, GetSubArray(seqPointBuilder, last, i - last, builder)); last = i; // Link together with any additional. if (current == null) { first = current = next; } else { current._next = next; current = next; } } } return first; } Example #10 0 Show file File: MergedAliases.cs Project: SoumikMukherjeeDOTNET/roslyn private static void AddNonIncluded(ArrayBuilder<string> builder, string item) { if (!builder.Contains(item)) { builder.Add(item); } } Example #11 0 Show file File: PdbHelpers.cs Project: SoumikMukherjeeDOTNET/roslyn private static void GetAllScopes( ISymUnmanagedScope root, ArrayBuilder<ISymUnmanagedScope> allScopes, ArrayBuilder<ISymUnmanagedScope> containingScopes, int offset, bool isScopeEndInclusive) { var stack = ArrayBuilder<ISymUnmanagedScope>.GetInstance(); stack.Push(root); while (stack.Any()) { var scope = stack.Pop(); allScopes.Add(scope); if (offset >= 0 && scope.IsInScope(offset, isScopeEndInclusive)) { containingScopes.Add(scope); } foreach (var nested in scope.GetScopes()) { stack.Push(nested); } } stack.Free(); } Example #12 0 Show file File: DynamicFlagsCustomTypeInfo.cs Project: GloryChou/roslyn private DynamicFlagsCustomTypeInfo(ArrayBuilder<bool> dynamicFlags, int startIndex) { Debug.Assert(dynamicFlags != null); Debug.Assert(startIndex >= 0); int numFlags = dynamicFlags.Count - startIndex; Debug.Assert(numFlags > 0); int numBytes = (numFlags + 7) / 8; byte[] bytes = new byte[numBytes]; bool seenTrue = false; for (int b = 0; b < numBytes; b++) { for (int i = 0; i < 8; i++) { var f = b * 8 + i; if (f >= numFlags) { Debug.Assert(f == numFlags); goto ALL_FLAGS_READ; } if (dynamicFlags[startIndex + f]) { seenTrue = true; bytes[b] |= (byte)(1 << i); } } } ALL_FLAGS_READ: _bytes = seenTrue ? new ReadOnlyCollection<byte>(bytes) : null; } Example #13 0 Show file File: LocalRewriter_DeconstructionAssignmentOperator.cs Project: otawfik-ms/roslyn /// <summary> /// Applies the conversions. /// Adds any new locals to the temps and any new expressions to be evaluated to the stores. /// </summary> private void ApplyConversions(BoundDeconstructionAssignmentOperator node, ArrayBuilder<LocalSymbol> temps, ArrayBuilder<BoundExpression> stores, ArrayBuilder<BoundValuePlaceholderBase> placeholders) { int numConversions = node.ConversionSteps.Length; var conversionLocals = ArrayBuilder<BoundExpression>.GetInstance(); foreach (var conversionInfo in node.ConversionSteps) { // lower the conversions and assignments to locals var localSymbol = new SynthesizedLocal(_factory.CurrentMethod, conversionInfo.OutputPlaceholder.Type, SynthesizedLocalKind.LoweringTemp); var localBound = new BoundLocal(node.Syntax, localSymbol, null, conversionInfo.OutputPlaceholder.Type) { WasCompilerGenerated = true }; temps.Add(localSymbol); conversionLocals.Add(localBound); AddPlaceholderReplacement(conversionInfo.OutputPlaceholder, localBound); placeholders.Add(conversionInfo.OutputPlaceholder); var conversion = VisitExpression(conversionInfo.Assignment); stores.Add(conversion); } } Example #14 0 Show file File: IteratorConstructor.cs Project: riversky/roslyn internal override void AddSynthesizedAttributes(ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(ref attributes); var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); } Example #15 0 Show file File: SynthesizedFieldSymbolBase.cs Project: Rickinio/roslyn internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(compilationState, ref attributes); CSharpCompilation compilation = this.DeclaringCompilation; // do not emit CompilerGenerated attributes for fields inside compiler generated types: if (!_containingType.IsImplicitlyDeclared) { AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); } if (!this.SuppressDynamicAttribute && this.Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes() && compilation.CanEmitBoolean()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length)); } if (Type.ContainsTuple() && compilation.HasTupleNamesAttributes && compilation.CanEmitSpecialType(SpecialType.System_String)) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttributeOpt(Type)); } } Example #16 0 Show file File: SpillBuilder.cs Project: EkardNT/Roslyn internal SpillBuilder() { locals = ArrayBuilder<LocalSymbol>.GetInstance(); temps = ArrayBuilder<BoundSpillTemp>.GetInstance(); statements = ArrayBuilder<BoundStatement>.GetInstance(); fields = ArrayBuilder<FieldSymbol>.GetInstance(); } Example #17 0 Show file File: LargeTextWriter.cs Project: jeffanders/roslyn public LargeTextWriter(Encoding encoding, SourceHashAlgorithm checksumAlgorithm, int length) { _encoding = encoding; _checksumAlgorithm = checksumAlgorithm; _chunks = ArrayBuilder<char[]>.GetInstance(1 + length / LargeText.ChunkSize); _bufferSize = Math.Min(LargeText.ChunkSize, length); } Example #18 0 Show file File: SynthesizedFieldLikeEventAccessorSymbol.cs Project: riversky/roslyn internal override void AddSynthesizedAttributes(ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(ref attributes); var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); } Example #19 0 Show file File: EvaluationContextBase.cs Project: GloryChou/roslyn internal abstract ReadOnlyCollection<byte> CompileGetLocals( ArrayBuilder<LocalAndMethod> locals, bool argumentsOnly, ImmutableArray<Alias> aliases, DiagnosticBag diagnostics, out string typeName, CompilationTestData testData); Example #20 0 Show file File: LocalRewriter_ObjectOrCollectionInitializerExpression.cs Project: Rickinio/roslyn // Rewrite collection initializer add method calls: // 2) new List<int> { 1 }; // ~ private void AddCollectionInitializers(ref ArrayBuilder<BoundExpression> dynamicSiteInitializers, ArrayBuilder<BoundExpression> result, BoundExpression rewrittenReceiver, ImmutableArray<BoundExpression> initializers) { Debug.Assert(rewrittenReceiver != null || _inExpressionLambda); foreach (var initializer in initializers) { // In general bound initializers may contain bad expressions or element initializers. // We don't lower them if they contain errors, so it's safe to assume an element initializer. BoundExpression rewrittenInitializer; if (initializer.Kind == BoundKind.CollectionElementInitializer) { rewrittenInitializer = MakeCollectionInitializer(rewrittenReceiver, (BoundCollectionElementInitializer)initializer); } else { Debug.Assert(!_inExpressionLambda); Debug.Assert(initializer.Kind == BoundKind.DynamicCollectionElementInitializer); rewrittenInitializer = MakeDynamicCollectionInitializer(rewrittenReceiver, (BoundDynamicCollectionElementInitializer)initializer); } // the call to Add may be omitted if (rewrittenInitializer != null) { result.Add(rewrittenInitializer); } } } Example #21 0 Show file File: ForEachLoopBinder.cs Project: GuilhermeSa/roslyn internal void CollectLocalsFromDeconstruction( ExpressionSyntax declaration, LocalDeclarationKind kind, ArrayBuilder<LocalSymbol> locals, SyntaxNode deconstructionStatement, Binder enclosingBinderOpt = null) { switch (declaration.Kind()) { case SyntaxKind.TupleExpression: { var tuple = (TupleExpressionSyntax)declaration; foreach (var arg in tuple.Arguments) { CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt); } break; } case SyntaxKind.DeclarationExpression: { var declarationExpression = (DeclarationExpressionSyntax)declaration; CollectLocalsFromDeconstruction( declarationExpression.Designation, declarationExpression.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); break; } case SyntaxKind.IdentifierName: break; default: throw ExceptionUtilities.UnexpectedValue(declaration.Kind()); } } Example #22 0 Show file File: LookupResult.cs Project: modulexcite/pattern-matching-csharp private LookupResult(ObjectPool<LookupResult> pool) { this.pool = pool; this.kind = LookupResultKind.Empty; this.symbolList = new ArrayBuilder<Symbol>(); this.error = null; } Example #23 0 Show file File: InterfaceDispatchMapNode.cs Project: TerabyteX/corert DispatchMapEntry[] BuildDispatchMap(NodeFactory factory) { ArrayBuilder<DispatchMapEntry> dispatchMapEntries = new ArrayBuilder<DispatchMapEntry>(); for (int i = 0; i < _type.RuntimeInterfaces.Length; i++) { var interfaceType = _type.RuntimeInterfaces[i]; Debug.Assert(interfaceType.IsInterface); List<MethodDesc> virtualSlots; factory.VirtualSlots.TryGetValue(interfaceType, out virtualSlots); if (virtualSlots != null) { for (int j = 0; j < virtualSlots.Count; j++) { MethodDesc declMethod = virtualSlots[j]; var implMethod = VirtualFunctionResolution.ResolveInterfaceMethodToVirtualMethodOnType(declMethod, _type.GetClosestMetadataType()); // Interface methods first implemented by a base type in the hierarchy will return null for the implMethod (runtime interface // dispatch will walk the inheritance chain). if (implMethod != null) { var entry = new DispatchMapEntry(); entry.InterfaceIndex = checked((short)i); entry.InterfaceMethodSlot = checked((short)j); entry.ImplementationMethodSlot = checked((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, implMethod)); dispatchMapEntries.Add(entry); } } } } return dispatchMapEntries.ToArray(); } Example #24 0 Show file File: ForEachLoopBinder.cs Project: XieShuquan/roslyn internal void CollectLocalsFromDeconstruction( ExpressionSyntax declaration, LocalDeclarationKind kind, ArrayBuilder<LocalSymbol> locals, SyntaxNode deconstructionStatement, Binder enclosingBinderOpt = null) { switch (declaration.Kind()) { case SyntaxKind.TupleExpression: { var tuple = (TupleExpressionSyntax)declaration; foreach (var arg in tuple.Arguments) { CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt); } break; } case SyntaxKind.DeclarationExpression: { var declarationExpression = (DeclarationExpressionSyntax)declaration; CollectLocalsFromDeconstruction( declarationExpression.Designation, declarationExpression.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); break; } case SyntaxKind.IdentifierName: break; default: // In broken code, we can have an arbitrary expression here. Collect its expression variables. ExpressionVariableFinder.FindExpressionVariables(this, locals, declaration); break; } } Example #25 0 Show file File: Binder_Deconstruct.cs Project: natidea/roslyn /// <summary> /// There are two kinds of deconstruction-assignments which this binding handles: tuple and non-tuple. /// /// Returns a BoundDeconstructionAssignmentOperator with a list of deconstruction steps and assignment steps. /// Deconstruct steps for tuples have no invocation to Deconstruct, but steps for non-tuples do. /// The caller is responsible for releasing all the ArrayBuilders in checkedVariables. /// </summary> private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment( CSharpSyntaxNode node, ExpressionSyntax right, ArrayBuilder<DeconstructionVariable> checkedVariables, DiagnosticBag diagnostics, bool isDeclaration, BoundDeconstructValuePlaceholder rhsPlaceholder = null) { // receiver for first Deconstruct step var boundRHS = rhsPlaceholder ?? BindValue(right, diagnostics, BindValueKind.RValue); boundRHS = FixTupleLiteral(checkedVariables, boundRHS, node, diagnostics); if ((object)boundRHS.Type == null) { // we could still not infer a type for the RHS FailRemainingInferences(checkedVariables, diagnostics); return new BoundDeconstructionAssignmentOperator( node, isDeclaration, FlattenDeconstructVariables(checkedVariables), boundRHS, ImmutableArray<BoundDeconstructionDeconstructStep>.Empty, ImmutableArray<BoundDeconstructionAssignmentStep>.Empty, ImmutableArray<BoundDeconstructionAssignmentStep>.Empty, ImmutableArray<BoundDeconstructionConstructionStep>.Empty, GetSpecialType(SpecialType.System_Void, diagnostics, node), hasErrors: true); } var deconstructionSteps = ArrayBuilder<BoundDeconstructionDeconstructStep>.GetInstance(1); var conversionSteps = ArrayBuilder<BoundDeconstructionAssignmentStep>.GetInstance(1); var assignmentSteps = ArrayBuilder<BoundDeconstructionAssignmentStep>.GetInstance(1); var constructionStepsOpt = isDeclaration ? null : ArrayBuilder<BoundDeconstructionConstructionStep>.GetInstance(1); bool hasErrors = !DeconstructIntoSteps( new BoundDeconstructValuePlaceholder(boundRHS.Syntax, boundRHS.Type), node, diagnostics, checkedVariables, deconstructionSteps, conversionSteps, assignmentSteps, constructionStepsOpt); TypeSymbol returnType = isDeclaration ? GetSpecialType(SpecialType.System_Void, diagnostics, node) : hasErrors ? CreateErrorType() : constructionStepsOpt.Last().OutputPlaceholder.Type; var deconstructions = deconstructionSteps.ToImmutableAndFree(); var conversions = conversionSteps.ToImmutableAndFree(); var assignments = assignmentSteps.ToImmutableAndFree(); var constructions = isDeclaration ? default(ImmutableArray<BoundDeconstructionConstructionStep>) : constructionStepsOpt.ToImmutableAndFree(); FailRemainingInferences(checkedVariables, diagnostics); return new BoundDeconstructionAssignmentOperator( node, isDeclaration, FlattenDeconstructVariables(checkedVariables), boundRHS, deconstructions, conversions, assignments, constructions, returnType, hasErrors: hasErrors); } Example #26 0 Show file File: LookupResult.cs Project: ehsansajjad465/roslyn private LookupResult(ObjectPool<LookupResult> pool) { _pool = pool; _kind = LookupResultKind.Empty; _symbolList = new ArrayBuilder<Symbol>(); _error = null; } Example #27 0 Show file File: SourceParameterSymbolBase.cs Project: jkotas/roslyn internal sealed override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(compilationState, ref attributes); var compilation = this.DeclaringCompilation; if (this.IsParams) { AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_ParamArrayAttribute__ctor)); } // Synthesize DecimalConstantAttribute if we don't have an explicit custom attribute already: var defaultValue = this.ExplicitDefaultConstantValue; if (defaultValue != ConstantValue.NotAvailable && defaultValue.SpecialType == SpecialType.System_Decimal && DefaultValueFromAttributes == ConstantValue.NotAvailable) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDecimalConstantAttribute(defaultValue.DecimalValue)); } if (this.Type.ContainsDynamic()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind)); } if (Type.ContainsTupleNames()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(Type)); } } Example #28 0 Show file File: Binder_Initializers.cs Project: EkardNT/Roslyn /// <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<FieldInitializers> initializers, ArrayBuilder<BoundInitializer> boundInitializers, DiagnosticBag diagnostics, bool generateDebugInfo, out ConsList<Imports> firstDebugImports) { firstDebugImports = null; foreach (FieldInitializers siblingInitializers in initializers) { var infos = ArrayBuilder<FieldInitializerInfo>.GetInstance(); // Exact size is not known up front. var locals = GetFieldInitializerInfos(compilation, siblingInitializers, infos, generateDebugInfo, ref firstDebugImports); ArrayBuilder<BoundInitializer> initializersBuilder = locals.IsDefaultOrEmpty ? boundInitializers : ArrayBuilder<BoundInitializer>.GetInstance(infos.Count); foreach (var info in infos) { BoundFieldInitializer boundInitializer = BindFieldInitializer(info.Binder, info.Initializer.Field, info.EqualsValue, diagnostics); initializersBuilder.Add(boundInitializer); } Debug.Assert(locals.IsDefaultOrEmpty == (initializersBuilder == boundInitializers)); if (!locals.IsDefaultOrEmpty) { boundInitializers.Add(new BoundInitializationScope((CSharpSyntaxNode)siblingInitializers.TypeDeclarationSyntax.GetSyntax(), locals, initializersBuilder.ToImmutableAndFree())); } infos.Free(); } } Example #29 0 Show file File: SourceAssemblySymbol.cs Project: iolevel/peachpie public SourceAssemblySymbol( PhpCompilation compilation, string assemblySimpleName, string moduleName) { Debug.Assert(compilation != null); Debug.Assert(!String.IsNullOrWhiteSpace(assemblySimpleName)); Debug.Assert(!String.IsNullOrWhiteSpace(moduleName)); _compilation = compilation; _simpleName = assemblySimpleName; var moduleBuilder = new ArrayBuilder<ModuleSymbol>(1); moduleBuilder.Add(new SourceModuleSymbol(this, compilation.SourceSymbolTables, moduleName)); //var importOptions = (compilation.Options.MetadataImportOptions == MetadataImportOptions.All) ? // MetadataImportOptions.All : MetadataImportOptions.Internal; //foreach (PEModule netModule in netModules) //{ // moduleBuilder.Add(new PEModuleSymbol(this, netModule, importOptions, moduleBuilder.Count)); // // SetReferences will be called later by the ReferenceManager (in CreateSourceAssemblyFullBind for // // a fresh manager, in CreateSourceAssemblyReuseData for a reused one). //} _modules = moduleBuilder.ToImmutableAndFree(); } Example #30 0 Show file File: EcmaType.MethodImpls.cs Project: noahfalk/corert // Virtual function related functionality public override MethodImplRecord[] FindMethodsImplWithMatchingDeclName(string declName) { MetadataReader metadataReader = _module.MetadataReader; var stringComparer = metadataReader.StringComparer; ArrayBuilder<MethodImplRecord> foundRecords = new ArrayBuilder<MethodImplRecord>(); foreach (var methodImplHandle in _typeDefinition.GetMethodImplementations()) { MethodImplementation methodImpl = metadataReader.GetMethodImplementation(methodImplHandle); EntityHandle methodDeclCheckHandle = methodImpl.MethodDeclaration; HandleKind methodDeclHandleKind = methodDeclCheckHandle.Kind; // We want to check that the method name matches before actually getting the MethodDesc. For MethodSpecifications // we need to dereference that handle to the underlying member reference to look at name matching. if (methodDeclHandleKind == HandleKind.MethodSpecification) { methodDeclCheckHandle = metadataReader.GetMethodSpecification((MethodSpecificationHandle)methodDeclCheckHandle).Method; methodDeclHandleKind = methodDeclCheckHandle.Kind; } bool foundRecord = false; switch (methodDeclHandleKind) { case HandleKind.MethodDefinition: if (stringComparer.Equals(metadataReader.GetMethodDefinition((MethodDefinitionHandle)methodDeclCheckHandle).Name, declName)) { foundRecord = true; } break; case HandleKind.MemberReference: if (stringComparer.Equals(metadataReader.GetMemberReference((MemberReferenceHandle)methodDeclCheckHandle).Name, declName)) { foundRecord = true; } break; default: Debug.Assert(false, "unexpected methodDeclHandleKind"); break; } if (foundRecord) { MethodImplRecord newRecord = new MethodImplRecord(); newRecord.Decl = (MethodDesc)_module.GetObject(methodImpl.MethodDeclaration); newRecord.Body = (MethodDesc)_module.GetObject(methodImpl.MethodBody); foundRecords.Add(newRecord); } } if (foundRecords.Count != 0) return foundRecords.ToArray(); return null; } Example #31 0 Show file File: ExpressionLambdaRewriter.cs Project: weswigham/roslyn private BoundExpression VisitInitializer(BoundExpression node, out InitializerKind kind) { switch (node.Kind) { case BoundKind.ObjectInitializerExpression: { var oi = (BoundObjectInitializerExpression)node; var builder = ArrayBuilder <BoundExpression> .GetInstance(); foreach (BoundAssignmentOperator a in oi.Initializers) { var sym = ((BoundObjectInitializerMember)a.Left).MemberSymbol; // An error is reported in diagnostics pass when a dynamic object initializer is encountered in an ET: Debug.Assert((object)sym != null); InitializerKind elementKind; var value = VisitInitializer(a.Right, out elementKind); switch (elementKind) { case InitializerKind.CollectionInitializer: { var left = InitializerMemberGetter(sym); builder.Add(ExprFactory("ListBind", left, value)); break; } case InitializerKind.Expression: { var left = InitializerMemberSetter(sym); builder.Add(ExprFactory("Bind", left, value)); break; } case InitializerKind.MemberInitializer: { var left = InitializerMemberGetter(sym); builder.Add(ExprFactory("MemberBind", left, value)); break; } default: throw ExceptionUtilities.UnexpectedValue(elementKind); } } kind = InitializerKind.MemberInitializer; return(_bound.Array(MemberBindingType, builder.ToImmutableAndFree())); } case BoundKind.CollectionInitializerExpression: { var ci = (BoundCollectionInitializerExpression)node; Debug.Assert(ci.Initializers.Length != 0); kind = InitializerKind.CollectionInitializer; var builder = ArrayBuilder <BoundExpression> .GetInstance(); // The method invocation must be a static call. // Dynamic calls are not allowed in ETs, an error is reported in diagnostics pass. foreach (BoundCollectionElementInitializer i in ci.Initializers) { BoundExpression elementInit = ExprFactory("ElementInit", _bound.MethodInfo(i.AddMethod), Expressions(i.Arguments)); builder.Add(elementInit); } return(_bound.Array(ElementInitType, builder.ToImmutableAndFree())); } default: { kind = InitializerKind.Expression; return(Visit(node)); } } } Example #32 0 Show file // Returns true if there were any applicable candidates. private bool CandidateOperators(ArrayBuilder <UnaryOperatorSignature> operators, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { bool anyApplicable = false; foreach (var op in operators) { var conversion = Conversions.ClassifyConversionFromExpression(operand, op.OperandType, ref useSiteDiagnostics); if (conversion.IsImplicit) { anyApplicable = true; results.Add(UnaryOperatorAnalysisResult.Applicable(op, conversion)); } else { results.Add(UnaryOperatorAnalysisResult.Inapplicable(op, conversion)); } } return(anyApplicable); } Example #33 0 Show file private void GetAllBuiltInOperators(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { // The spec states that overload resolution is performed upon the infinite set of // operators defined on enumerated types, pointers and delegates. Clearly we cannot // construct the infinite set; we have to pare it down. Previous implementations of C# // implement a much stricter rule; they only add the special operators to the candidate // set if one of the operands is of the relevant type. This means that operands // involving user-defined implicit conversions from class or struct types to enum, // pointer and delegate types do not cause the right candidates to participate in // overload resolution. It also presents numerous problems involving delegate variance // and conversions from lambdas to delegate types. // // It is onerous to require the actually specified behavior. We should change the // specification to match the previous implementation. var operators = ArrayBuilder <UnaryOperatorSignature> .GetInstance(); this.Compilation.builtInOperators.GetSimpleBuiltInOperators(kind, operators); GetEnumOperations(kind, operand, operators); var pointerOperator = GetPointerOperation(kind, operand); if (pointerOperator != null) { operators.Add(pointerOperator.Value); } CandidateOperators(operators, operand, results, ref useSiteDiagnostics); operators.Free(); } Example #34 0 Show file // Returns true if there were any applicable candidates. private bool GetUserDefinedOperators(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(operand != null); if ((object)operand.Type == null) { // If the operand has no type -- because it is a null reference or a lambda or a method group -- // there is no way we can determine what type to search for user-defined operators. return(false); } // Spec 7.3.5 Candidate user-defined operators // SPEC: Given a type T and an operation op(A) ... the set of candidate user-defined // SPEC: operators provided by T for op(A) is determined as follows: // SPEC: If T is a nullable type then T0 is its underlying type; otherwise T0 is T. // SPEC: For all operator declarations in T0 and all lifted forms of such operators, if // SPEC: at least one operator is applicable with respect to A then the set of candidate // SPEC: operators consists of all such applicable operators. Otherwise, if T0 is object // SPEC: then the set of candidate operators is empty. Otherwise, the set of candidate // SPEC: operators is the set provided by the direct base class of T0, or the effective // SPEC: base class of T0 if T0 is a type parameter. TypeSymbol type0 = operand.Type.StrippedType(); // Searching for user-defined operators is expensive; let's take an early out if we can. if (OperatorFacts.DefinitelyHasNoUserDefinedOperators(type0)) { return(false); } string name = OperatorFacts.UnaryOperatorNameFromOperatorKind(kind); var operators = ArrayBuilder <UnaryOperatorSignature> .GetInstance(); bool hadApplicableCandidates = false; NamedTypeSymbol current = type0 as NamedTypeSymbol; if ((object)current == null) { current = type0.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics); } if ((object)current == null && type0.IsTypeParameter()) { current = ((TypeParameterSymbol)type0).EffectiveBaseClass(ref useSiteDiagnostics); } for (; (object)current != null; current = current.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics)) { operators.Clear(); GetUserDefinedUnaryOperatorsFromType(current, kind, name, operators); results.Clear(); if (CandidateOperators(operators, operand, results, ref useSiteDiagnostics)) { hadApplicableCandidates = true; break; } } operators.Free(); return(hadApplicableCandidates); } Example #35 0 Show file private void GetEnumOperations(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorSignature> operators) { Debug.Assert(operand != null); var enumType = operand.Type; if ((object)enumType == null) { return; } enumType = enumType.StrippedType(); if (!enumType.IsValidEnumType()) { return; } var nullableEnum = MakeNullable(enumType); switch (kind) { case UnaryOperatorKind.PostfixIncrement: case UnaryOperatorKind.PostfixDecrement: case UnaryOperatorKind.PrefixIncrement: case UnaryOperatorKind.PrefixDecrement: case UnaryOperatorKind.BitwiseComplement: operators.Add(new UnaryOperatorSignature(kind | UnaryOperatorKind.Enum, enumType, enumType)); operators.Add(new UnaryOperatorSignature(kind | UnaryOperatorKind.Lifted | UnaryOperatorKind.Enum, nullableEnum, nullableEnum)); break; } } Example #36 0 Show file File: AsyncExceptionHandlerRewriter.cs Project: zouql/roslyn public override BoundNode VisitCatchBlock(BoundCatchBlock node) { if (!_analysis.CatchContainsAwait(node)) { var origCurrentAwaitCatchFrame = _currentAwaitCatchFrame; _currentAwaitCatchFrame = null; var result = base.VisitCatchBlock(node); _currentAwaitCatchFrame = origCurrentAwaitCatchFrame; return(result); } var currentAwaitCatchFrame = _currentAwaitCatchFrame; if (currentAwaitCatchFrame == null) { Debug.Assert(node.Syntax.IsKind(SyntaxKind.CatchClause)); var tryStatementSyntax = (TryStatementSyntax)node.Syntax.Parent; currentAwaitCatchFrame = _currentAwaitCatchFrame = new AwaitCatchFrame(_F, tryStatementSyntax); } var catchType = node.ExceptionTypeOpt ?? _F.SpecialType(SpecialType.System_Object); var catchTemp = _F.SynthesizedLocal(catchType); var storePending = _F.AssignmentExpression( _F.Local(currentAwaitCatchFrame.pendingCaughtException), _F.Convert(currentAwaitCatchFrame.pendingCaughtException.Type, _F.Local(catchTemp))); var setPendingCatchNum = _F.Assignment( _F.Local(currentAwaitCatchFrame.pendingCatch), _F.Literal(currentAwaitCatchFrame.handlers.Count + 1)); // catch (ExType exTemp) // { // pendingCaughtException = exTemp; // catchNo = X; // } BoundCatchBlock catchAndPend; ImmutableArray <LocalSymbol> handlerLocals; var filterPrologueOpt = node.ExceptionFilterPrologueOpt; var filterOpt = node.ExceptionFilterOpt; if (filterOpt == null) { Debug.Assert(filterPrologueOpt is null); // store pending exception // as the first statement in a catch catchAndPend = node.Update( ImmutableArray.Create(catchTemp), _F.Local(catchTemp), catchType, exceptionFilterPrologueOpt: filterPrologueOpt, exceptionFilterOpt: null, body: _F.Block( _F.HiddenSequencePoint(), _F.ExpressionStatement(storePending), setPendingCatchNum), isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll); // catch locals live on the synthetic catch handler block handlerLocals = node.Locals; } else { handlerLocals = ImmutableArray <LocalSymbol> .Empty; // catch locals move up into hoisted locals // since we might need to access them from both the filter and the catch foreach (var local in node.Locals) { currentAwaitCatchFrame.HoistLocal(local, _F); } // store pending exception // as the first expression in a filter var sourceOpt = node.ExceptionSourceOpt; var rewrittenPrologue = (BoundStatementList)this.Visit(filterPrologueOpt); var rewrittenFilter = (BoundExpression)this.Visit(filterOpt); var newFilter = sourceOpt == null? _F.MakeSequence( storePending, rewrittenFilter) : _F.MakeSequence( storePending, AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame), rewrittenFilter); catchAndPend = node.Update( ImmutableArray.Create(catchTemp), _F.Local(catchTemp), catchType, exceptionFilterPrologueOpt: rewrittenPrologue, exceptionFilterOpt: newFilter, body: _F.Block( _F.HiddenSequencePoint(), setPendingCatchNum), isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll); } var handlerStatements = ArrayBuilder <BoundStatement> .GetInstance(); handlerStatements.Add(_F.HiddenSequencePoint()); if (filterOpt == null) { var sourceOpt = node.ExceptionSourceOpt; if (sourceOpt != null) { BoundExpression assignSource = AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame); handlerStatements.Add(_F.ExpressionStatement(assignSource)); } } handlerStatements.Add((BoundStatement)this.Visit(node.Body)); var handler = _F.Block( handlerLocals, handlerStatements.ToImmutableAndFree() ); currentAwaitCatchFrame.handlers.Add(handler); return(catchAndPend); } Example #37 0 Show file /// <summary> /// Populates a list of unary operator results with those from any /// witness in scope at the operator site. /// </summary> /// <param name="kind"> /// The unary operator kind of the expression. /// </param> /// <param name="operand"> /// The operand expression. /// </param> /// <param name="results"> /// The results list to populate. /// </param> /// <param name="useSiteDiagnostics"> /// The set of diagnostics to populate with any errors. /// </param> /// <returns> /// True if we managed to find candidate operators from the concept /// witnesses in scope; false otherwise. /// </returns> private bool GetUnaryWitnessOperators(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(operand != null); string name = OperatorFacts.UnaryOperatorNameFromOperatorKind(kind); var operators = ArrayBuilder <UnaryOperatorSignature> .GetInstance(); foreach (var method in GetWitnessOperators(name, 1, ref useSiteDiagnostics)) { // TODO: nullability operators.Add(new UnaryOperatorSignature(UnaryOperatorKind.UserDefined | kind, method.ParameterTypes[0], method.ReturnType, method)); } bool hasCandidates = CandidateOperators(operators, operand, results, ref useSiteDiagnostics); operators.Free(); return(hasCandidates); } Example #38 0 Show file internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); AddSynthesizedAttribute(ref attributes, this.DeclaringCompilation.TrySynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); } Example #39 0 Show file File: IteratorMethodToStateMachineRewriter.cs Project: shibutamang/roslyn public override BoundNode VisitTryStatement(BoundTryStatement node) { // if node contains no yields, do regular rewrite in the current frame. if (!ContainsYields(node)) { _tryNestingLevel++; var result = node.Update( (BoundBlock)Visit(node.TryBlock), VisitList(node.CatchBlocks), (BoundBlock)Visit(node.FinallyBlockOpt), node.PreferFaultHandler); _tryNestingLevel--; return(result); } Debug.Assert(node.CatchBlocks.IsEmpty, "try with yields must have no catches"); Debug.Assert(node.FinallyBlockOpt != null, "try with yields must have finally"); // rewrite TryBlock in a new frame. var frame = PushFrame(node); _tryNestingLevel++; var rewrittenBody = (BoundStatement)this.Visit(node.TryBlock); Debug.Assert(!frame.IsRoot()); Debug.Assert(frame.parent.knownStates.ContainsValue(frame), "parent must be aware about states in the child frame"); var finallyMethod = frame.handler; var origMethod = F.CurrentFunction; // rewrite finally block into a Finally method. F.CurrentFunction = finallyMethod; var rewrittenHandler = (BoundStatement)this.Visit(node.FinallyBlockOpt); _tryNestingLevel--; PopFrame(); // { // this.state = parentFinalizeState; // body; // return; // } Debug.Assert(frame.parent.finalizeState == _currentFinallyFrame.finalizeState); rewrittenHandler = F.Block((object)this.cachedThis != null ? ImmutableArray.Create(this.cachedThis) : ImmutableArray <LocalSymbol> .Empty, F.Assignment(F.Field(F.This(), stateField), F.Literal(frame.parent.finalizeState)), CacheThisIfNeeded(), rewrittenHandler, F.Return() ); F.CloseMethod(rewrittenHandler); F.CurrentFunction = origMethod; var bodyStatements = ArrayBuilder <BoundStatement> .GetInstance(); // add a call to the handler after the try body. // // { // this.state = finalizeState; // body; // this.Finally(); // will reset the state to the finally state of the parent. // } bodyStatements.Add(F.Assignment(F.Field(F.This(), stateField), F.Literal(frame.finalizeState))); bodyStatements.Add(rewrittenBody); bodyStatements.Add(F.ExpressionStatement(F.Call(F.This(), finallyMethod))); // handle proxy labels if have any if (frame.proxyLabels != null) { var dropThrough = F.GenerateLabel("dropThrough"); bodyStatements.Add(F.Goto(dropThrough)); var parent = frame.parent; foreach (var p in frame.proxyLabels) { var proxy = p.Value; var destination = p.Key; // branch lands here bodyStatements.Add(F.Label(proxy)); // finalize current state, proceed to destination. bodyStatements.Add(F.ExpressionStatement(F.Call(F.This(), finallyMethod))); // let the parent forward the branch appropriately var parentProxy = parent.ProxyLabelIfNeeded(destination); bodyStatements.Add(F.Goto(parentProxy)); } bodyStatements.Add(F.Label(dropThrough)); } return(F.Block(bodyStatements.ToImmutableAndFree())); } Example #40 0 Show file File: SourceEventSymbol.cs Project: wenming2014/roslyn internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData>?attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); var compilation = this.DeclaringCompilation; var type = this.TypeWithAnnotations; if (type.Type.ContainsDynamic()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length)); } if (type.Type.ContainsTupleNames()) { AddSynthesizedAttribute(ref attributes, DeclaringCompilation.SynthesizeTupleNamesAttribute(type.Type)); } if (compilation.ShouldEmitNullableAttributes(this)) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttributeIfNecessary(this, containingType.GetNullableContextValue(), type)); } } Example #41 0 Show file internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { // Emit [Dynamic] on synthesized parameter symbols when the original parameter was dynamic // in order to facilitate debugging. In the case the necessary attributes are missing // this is a no-op. Emitting an error here, or when the original parameter was bound, would // adversely effect the compilation or potentially change overload resolution. var compilation = this.DeclaringCompilation; var type = this.TypeWithAnnotations; if (type.Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes(BindingDiagnosticBag.Discarded, Location.None) && compilation.CanEmitBoolean()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); } if (type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } if (type.Type.ContainsTupleNames() && compilation.HasTupleNamesAttributes(BindingDiagnosticBag.Discarded, Location.None) && compilation.CanEmitSpecialType(SpecialType.System_String)) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(type.Type)); } if (compilation.ShouldEmitNullableAttributes(this)) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttributeIfNecessary(this, GetNullableContextValue(), type)); } if (this.RefKind == RefKind.RefReadOnly) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this)); } } Example #42 0 Show file private BoundExpression HoistExpression( BoundExpression expr, AwaitExpressionSyntax awaitSyntaxOpt, int syntaxOffset, RefKind refKind, ArrayBuilder <BoundExpression> sideEffects, ArrayBuilder <StateMachineFieldSymbol> hoistedFields, ref bool needsSacrificialEvaluation) { switch (expr.Kind) { case BoundKind.ArrayAccess: { var array = (BoundArrayAccess)expr; BoundExpression expression = HoistExpression(array.Expression, awaitSyntaxOpt, syntaxOffset, RefKind.None, sideEffects, hoistedFields, ref needsSacrificialEvaluation); var indices = ArrayBuilder <BoundExpression> .GetInstance(); foreach (var index in array.Indices) { indices.Add(HoistExpression(index, awaitSyntaxOpt, syntaxOffset, RefKind.None, sideEffects, hoistedFields, ref needsSacrificialEvaluation)); } needsSacrificialEvaluation = true; // need to force array index out of bounds exceptions return(array.Update(expression, indices.ToImmutableAndFree(), array.Type)); } case BoundKind.FieldAccess: { var field = (BoundFieldAccess)expr; if (field.FieldSymbol.IsStatic) { // the address of a static field, and the value of a readonly static field, is stable if (refKind != RefKind.None || field.FieldSymbol.IsLet) { return(expr); } goto default; } if (refKind == RefKind.None) { goto default; } var isFieldOfStruct = !field.FieldSymbol.ContainingType.IsReferenceType; var receiver = HoistExpression(field.ReceiverOpt, awaitSyntaxOpt, syntaxOffset, isFieldOfStruct ? refKind : RefKind.None, sideEffects, hoistedFields, ref needsSacrificialEvaluation); if (receiver.Kind != BoundKind.ThisReference && !isFieldOfStruct) { needsSacrificialEvaluation = true; // need the null check in field receiver } return(F.Field(receiver, field.FieldSymbol)); } case BoundKind.ThisReference: case BoundKind.BaseReference: case BoundKind.DefaultExpression: return(expr); case BoundKind.Call: var call = (BoundCall)expr; // NOTE: There are two kinds of 'In' arguments that we may see at this point: // - `RefKindExtensions.StrictIn` (originally specified with 'In' modifier) // - `RefKind.In` (specified with no modifiers and matched an 'In' parameter) // // It is allowed to spill ordinary `In` arguments by value if reference-preserving spilling is not possible. // The "strict" ones do not permit implicit copying, so the same situation should result in an error. if (refKind != RefKind.None && refKind != RefKind.In) { Debug.Assert(call.Method.RefKind != RefKind.None); F.Diagnostics.Add(ErrorCode.ERR_RefReturningCallAndAwait, F.Syntax.Location, call.Method); } // method call is not referentially transparent, we can only spill the result value. refKind = RefKind.None; goto default; case BoundKind.ConditionalOperator: var conditional = (BoundConditionalOperator)expr; // NOTE: There are two kinds of 'In' arguments that we may see at this point: // - `RefKindExtensions.StrictIn` (originally specified with 'In' modifier) // - `RefKind.In` (specified with no modifiers and matched an 'In' parameter) // // It is allowed to spill ordinary `In` arguments by value if reference-preserving spilling is not possible. // The "strict" ones do not permit implicit copying, so the same situation should result in an error. if (refKind != RefKind.None && refKind != RefKind.RefReadOnly) { Debug.Assert(conditional.IsRef); F.Diagnostics.Add(ErrorCode.ERR_RefConditionalAndAwait, F.Syntax.Location); } // conditional expr is not referentially transparent, we can only spill the result value. refKind = RefKind.None; goto default; default: if (expr.ConstantValue != null) { return(expr); } if (refKind != RefKind.None) { throw ExceptionUtilities.UnexpectedValue(expr.Kind); } TypeSymbol fieldType = expr.Type; StateMachineFieldSymbol hoistedField; if (F.Compilation.Options.OptimizationLevel == OptimizationLevel.Debug) { const SynthesizedLocalKind kind = SynthesizedLocalKind.AwaitByRefSpill; Debug.Assert(awaitSyntaxOpt != null); int ordinal = _synthesizedLocalOrdinals.AssignLocalOrdinal(kind, syntaxOffset); var id = new LocalDebugId(syntaxOffset, ordinal); // Editing await expression is not allowed. Thus all spilled fields will be present in the previous state machine. // However, it may happen that the type changes, in which case we need to allocate a new slot. int slotIndex; if (slotAllocatorOpt == null || !slotAllocatorOpt.TryGetPreviousHoistedLocalSlotIndex( awaitSyntaxOpt, F.ModuleBuilderOpt.Translate(fieldType, awaitSyntaxOpt, Diagnostics), kind, id, Diagnostics, out slotIndex)) { slotIndex = _nextFreeHoistedLocalSlot++; } string fieldName = GeneratedNames.MakeHoistedLocalFieldName(kind, slotIndex); hoistedField = F.StateMachineField(expr.Type, fieldName, new LocalSlotDebugInfo(kind, id), slotIndex); } else { hoistedField = GetOrAllocateReusableHoistedField(fieldType, reused: out _); } hoistedFields.Add(hoistedField); var replacement = F.Field(F.This(), hoistedField); sideEffects.Add(F.AssignmentExpression(replacement, expr)); return(replacement); } } Example #43 0 Show file /// <summary> /// Translate a statement that declares a given set of locals. Also allocates and frees hoisted temps as /// required for the translation. /// </summary> /// <param name="locals">The set of locals declared in the original version of this statement</param> /// <param name="wrapped">A delegate to return the translation of the body of this statement</param> private BoundStatement PossibleIteratorScope(ImmutableArray <LocalSymbol> locals, Func <BoundStatement> wrapped) { if (locals.IsDefaultOrEmpty) { return(wrapped()); } var hoistedLocalsWithDebugScopes = ArrayBuilder <StateMachineFieldSymbol> .GetInstance(); foreach (var local in locals) { if (!NeedsProxy(local)) { continue; } // Ref synthesized variables have proxies that are allocated in VisitAssignmentOperator. if (local.RefKind != RefKind.None) { Debug.Assert(local.SynthesizedKind == SynthesizedLocalKind.Spill); continue; } Debug.Assert(local.SynthesizedKind.IsLongLived()); CapturedSymbolReplacement proxy; bool reused = false; if (!proxies.TryGetValue(local, out proxy)) { proxy = new CapturedToStateMachineFieldReplacement(GetOrAllocateReusableHoistedField(TypeMap.SubstituteType(local.Type.TypeSymbol).TypeSymbol, out reused, local), isReusable: true); proxies.Add(local, proxy); } // We need to produce hoisted local scope debug information for user locals as well as // lambda display classes, since Dev12 EE uses them to determine which variables are displayed // in Locals window. if ((local.SynthesizedKind == SynthesizedLocalKind.UserDefined && local.ScopeDesignatorOpt?.Kind() != SyntaxKind.SwitchSection) || local.SynthesizedKind == SynthesizedLocalKind.LambdaDisplayClass) { // NB: This is the case when the local backed by recycled field will not be visible in debugger. // It may be possible in the future, but for now a backing field can be mapped only to a single local. if (!reused) { hoistedLocalsWithDebugScopes.Add(((CapturedToStateMachineFieldReplacement)proxy).HoistedField); } } } var translatedStatement = wrapped(); var variableCleanup = ArrayBuilder <BoundAssignmentOperator> .GetInstance(); // produce cleanup code for all fields of locals defined by this block // as well as all proxies allocated by VisitAssignmentOperator within this block: foreach (var local in locals) { CapturedSymbolReplacement proxy; if (!proxies.TryGetValue(local, out proxy)) { continue; } var simpleProxy = proxy as CapturedToStateMachineFieldReplacement; if (simpleProxy != null) { AddVariableCleanup(variableCleanup, simpleProxy.HoistedField); if (proxy.IsReusable) { FreeReusableHoistedField(simpleProxy.HoistedField); } } else { foreach (var field in ((CapturedToExpressionSymbolReplacement)proxy).HoistedFields) { AddVariableCleanup(variableCleanup, field); if (proxy.IsReusable) { FreeReusableHoistedField(field); } } } } if (variableCleanup.Count != 0) { translatedStatement = F.Block( translatedStatement, F.Block(variableCleanup.SelectAsArray((e, f) => (BoundStatement)f.ExpressionStatement(e), F))); } variableCleanup.Free(); // wrap the node in an iterator scope for debugging if (hoistedLocalsWithDebugScopes.Count != 0) { translatedStatement = MakeStateMachineScope(hoistedLocalsWithDebugScopes.ToImmutable(), translatedStatement); } hoistedLocalsWithDebugScopes.Free(); return(translatedStatement); } Example #44 0 Show file File: AsyncExceptionHandlerRewriter.cs Project: zouql/roslyn public override BoundNode VisitTryStatement(BoundTryStatement node) { var tryStatementSyntax = node.Syntax; // If you add a syntax kind to the assertion below, please also ensure // that the scenario has been tested with Edit-and-Continue. Debug.Assert( tryStatementSyntax.IsKind(SyntaxKind.TryStatement) || tryStatementSyntax.IsKind(SyntaxKind.UsingStatement) || tryStatementSyntax.IsKind(SyntaxKind.ForEachStatement) || tryStatementSyntax.IsKind(SyntaxKind.ForEachVariableStatement) || tryStatementSyntax.IsKind(SyntaxKind.LocalDeclarationStatement)); BoundStatement finalizedRegion; BoundBlock rewrittenFinally; var finallyContainsAwaits = _analysis.FinallyContainsAwaits(node); if (!finallyContainsAwaits) { finalizedRegion = RewriteFinalizedRegion(node); rewrittenFinally = (BoundBlock)this.Visit(node.FinallyBlockOpt); if (rewrittenFinally == null) { return(finalizedRegion); } var asTry = finalizedRegion as BoundTryStatement; if (asTry != null) { // since finalized region is a try we can just attach finally to it Debug.Assert(asTry.FinallyBlockOpt == null); return(asTry.Update(asTry.TryBlock, asTry.CatchBlocks, rewrittenFinally, asTry.FinallyLabelOpt, asTry.PreferFaultHandler)); } else { // wrap finalizedRegion into a Try with a finally. return(_F.Try((BoundBlock)finalizedRegion, ImmutableArray <BoundCatchBlock> .Empty, rewrittenFinally)); } } // rewrite finalized region (try and catches) in the current frame var frame = PushFrame(node); finalizedRegion = RewriteFinalizedRegion(node); rewrittenFinally = (BoundBlock)this.VisitBlock(node.FinallyBlockOpt); PopFrame(); var exceptionType = _F.SpecialType(SpecialType.System_Object); var pendingExceptionLocal = new SynthesizedLocal(_F.CurrentFunction, TypeWithAnnotations.Create(exceptionType), SynthesizedLocalKind.TryAwaitPendingException, tryStatementSyntax); var finallyLabel = _F.GenerateLabel("finallyLabel"); var pendingBranchVar = new SynthesizedLocal(_F.CurrentFunction, TypeWithAnnotations.Create(_F.SpecialType(SpecialType.System_Int32)), SynthesizedLocalKind.TryAwaitPendingBranch, tryStatementSyntax); var catchAll = _F.Catch(_F.Local(pendingExceptionLocal), _F.Block()); var catchAndPendException = _F.Try( _F.Block( finalizedRegion, _F.HiddenSequencePoint(), _F.Goto(finallyLabel), PendBranches(frame, pendingBranchVar, finallyLabel)), ImmutableArray.Create(catchAll), finallyLabel: finallyLabel); BoundBlock syntheticFinallyBlock = _F.Block( _F.HiddenSequencePoint(), _F.Label(finallyLabel), rewrittenFinally, _F.HiddenSequencePoint(), UnpendException(pendingExceptionLocal), UnpendBranches( frame, pendingBranchVar, pendingExceptionLocal)); BoundStatement syntheticFinally = syntheticFinallyBlock; if (_F.CurrentFunction.IsAsync && _F.CurrentFunction.IsIterator) { // We wrap this block so that it can be processed as a finally block by async-iterator rewriting syntheticFinally = _F.ExtractedFinallyBlock(syntheticFinallyBlock); } var locals = ArrayBuilder <LocalSymbol> .GetInstance(); var statements = ArrayBuilder <BoundStatement> .GetInstance(); statements.Add(_F.HiddenSequencePoint()); locals.Add(pendingExceptionLocal); statements.Add(_F.Assignment(_F.Local(pendingExceptionLocal), _F.Default(pendingExceptionLocal.Type))); locals.Add(pendingBranchVar); statements.Add(_F.Assignment(_F.Local(pendingBranchVar), _F.Default(pendingBranchVar.Type))); LocalSymbol returnLocal = frame.returnValue; if (returnLocal != null) { locals.Add(returnLocal); } statements.Add(catchAndPendException); statements.Add(syntheticFinally); var completeTry = _F.Block( locals.ToImmutableAndFree(), statements.ToImmutableAndFree()); return(completeTry); } Example #45 0 Show file /// <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); Example #46 0 Show file File: EEAssemblyBuilder.cs Project: ruo2012/peachpie public override void AddPreviousLocals(ArrayBuilder <Cci.ILocalDefinition> builder) { builder.AddRange(_locals); } Example #47 0 Show file File: AsyncExceptionHandlerRewriter.cs Project: zouql/roslyn private BoundStatement UnpendBranches( AwaitFinallyFrame frame, SynthesizedLocal pendingBranchVar, SynthesizedLocal pendingException) { var parent = frame.ParentOpt; // handle proxy labels if have any var proxiedLabels = frame.proxiedLabels; // skip 0 - it means we took no explicit branches int i = 1; var cases = ArrayBuilder <SyntheticBoundNodeFactory.SyntheticSwitchSection> .GetInstance(); if (proxiedLabels != null) { for (int cnt = proxiedLabels.Count; i <= cnt; i++) { var target = proxiedLabels[i - 1]; var parentProxy = parent.ProxyLabelIfNeeded(target); var caseStatement = _F.SwitchSection(i, _F.Goto(parentProxy)); cases.Add(caseStatement); } } if (frame.returnProxyLabel != null) { BoundLocal pendingValue = null; if (frame.returnValue != null) { pendingValue = _F.Local(frame.returnValue); } SynthesizedLocal returnValue; BoundStatement unpendReturn; var returnLabel = parent.ProxyReturnIfNeeded(_F.CurrentFunction, pendingValue, out returnValue); if (returnLabel == null) { unpendReturn = new BoundReturnStatement(_F.Syntax, RefKind.None, pendingValue); } else { if (pendingValue == null) { unpendReturn = _F.Goto(returnLabel); } else { unpendReturn = _F.Block( _F.Assignment( _F.Local(returnValue), pendingValue), _F.Goto(returnLabel)); } } var caseStatement = _F.SwitchSection(i, unpendReturn); cases.Add(caseStatement); } return(_F.Switch(_F.Local(pendingBranchVar), cases.ToImmutableAndFree())); } Example #48 0 Show file File: AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs Project: tmcmil/roslyn private void OnSymbolEnd(SymbolAnalysisContext symbolEndContext, bool hasUnsupportedOperation) { if (hasUnsupportedOperation) { return; } if (symbolEndContext.Symbol.GetAttributes().Any(a => a.AttributeClass == _structLayoutAttributeType)) { // Bail out for types with 'StructLayoutAttribute' as the ordering of the members is critical, // and removal of unused members might break semantics. return; } // Report diagnostics for unused candidate members. var first = true; PooledHashSet <ISymbol> symbolsReferencedInDocComments = null; ArrayBuilder <string> debuggerDisplayAttributeArguments = null; try { var entryPoint = symbolEndContext.Compilation.GetEntryPoint(symbolEndContext.CancellationToken); var namedType = (INamedTypeSymbol)symbolEndContext.Symbol; foreach (var member in namedType.GetMembers()) { if (SymbolEqualityComparer.Default.Equals(entryPoint, member)) { continue; } // Check if the underlying member is neither read nor a readable reference to the member is taken. // If so, we flag the member as either unused (never written) or unread (written but not read). if (TryRemove(member, out var valueUsageInfo) && !valueUsageInfo.IsReadFrom()) { Debug.Assert(IsCandidateSymbol(member)); Debug.Assert(!member.IsImplicitlyDeclared); if (first) { // Bail out if there are syntax errors in any of the declarations of the containing type. // Note that we check this only for the first time that we report an unused or unread member for the containing type. if (HasSyntaxErrors(namedType, symbolEndContext.CancellationToken)) { return; } // Compute the set of candidate symbols referenced in all the documentation comments within the named type declarations. // This set is computed once and used for all the iterations of the loop. symbolsReferencedInDocComments = GetCandidateSymbolsReferencedInDocComments(namedType, symbolEndContext.Compilation, symbolEndContext.CancellationToken); // Compute the set of string arguments to DebuggerDisplay attributes applied to any symbol within the named type declaration. // These strings may have an embedded reference to the symbol. // This set is computed once and used for all the iterations of the loop. debuggerDisplayAttributeArguments = GetDebuggerDisplayAttributeArguments(namedType); first = false; } // Simple heuristic for members referenced in DebuggerDisplayAttribute's string argument: // bail out if any of the DebuggerDisplay string arguments contains the member name. // In future, we can consider improving this heuristic to parse the embedded expression // and resolve symbol references. if (debuggerDisplayAttributeArguments.Any(arg => arg.Contains(member.Name))) { continue; } // Report IDE0051 or IDE0052 based on whether the underlying member has any Write/WritableRef/NonReadWriteRef references or not. var rule = !valueUsageInfo.IsWrittenTo() && !valueUsageInfo.IsNameOnly() && !symbolsReferencedInDocComments.Contains(member) ? s_removeUnusedMembersRule : s_removeUnreadMembersRule; // Do not flag write-only properties that are not read. // Write-only properties are assumed to have side effects // visible through other means than a property getter. if (rule == s_removeUnreadMembersRule && member is IPropertySymbol property && property.IsWriteOnly) { continue; } // Most of the members should have a single location, except for partial methods. // We report the diagnostic on the first location of the member. var diagnostic = DiagnosticHelper.CreateWithMessage( rule, member.Locations[0], rule.GetEffectiveSeverity(symbolEndContext.Compilation.Options), additionalLocations: null, properties: null, GetMessage(rule, member)); symbolEndContext.ReportDiagnostic(diagnostic); } } } finally { symbolsReferencedInDocComments?.Free(); debuggerDisplayAttributeArguments?.Free(); } return; } Example #49 0 Show file internal static bool TryGetTupleFieldValues(this DkmClrValue tuple, int cardinality, ArrayBuilder <string> values, DkmInspectionContext inspectionContext) { while (true) { var type = tuple.Type.GetLmrType(); int n = Math.Min(cardinality, TupleFieldRestPosition - 1); for (int index = 0; index < n; index++) { var fieldName = GetTupleFieldName(index); var fieldInfo = type.GetTupleField(fieldName); if (fieldInfo == null) { return(false); } var value = tuple.GetFieldValue(fieldName, inspectionContext); var str = value.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers); values.Add(str); } cardinality -= n; if (cardinality == 0) { return(true); } var restInfo = type.GetTupleField(TypeHelpers.TupleFieldRestName); if (restInfo == null) { return(false); } tuple = tuple.GetFieldValue(TupleFieldRestName, inspectionContext); } } Example #50 0 Show file File: SourceEventSymbol.cs Project: xlabsoft/roslyn internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); var type = this.Type; if (type.TypeSymbol.ContainsDynamic()) { var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.TypeSymbol, type.CustomModifiers.Length)); } if (type.TypeSymbol.ContainsTupleNames()) { AddSynthesizedAttribute(ref attributes, DeclaringCompilation.SynthesizeTupleNamesAttribute(type.TypeSymbol)); } AddSynthesizedNonNullTypesAttributeForMember(ref attributes); if (type.ContainsNullableReferenceTypes()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, type)); } } Example #51 0 Show file internal static void AppendTypeMembers( this Type type, ArrayBuilder <MemberAndDeclarationInfo> includedMembers, Predicate <MemberInfo> predicate, Type declaredType, DkmClrAppDomain appDomain, bool includeInherited, bool hideNonPublic) { Debug.Assert(!type.IsInterface); var memberLocation = DeclarationInfo.FromSubTypeOfDeclaredType; var previousDeclarationMap = includeInherited ? new Dictionary <string, DeclarationInfo>() : null; int inheritanceLevel = 0; while (!type.IsObject()) { if (type.Equals(declaredType)) { Debug.Assert(memberLocation == DeclarationInfo.FromSubTypeOfDeclaredType); memberLocation = DeclarationInfo.FromDeclaredTypeOrBase; } // Get the state from DebuggerBrowsableAttributes for the members of the current type. var browsableState = DkmClrType.Create(appDomain, type).GetDebuggerBrowsableAttributeState(); // Hide non-public members if hideNonPublic is specified (intended to reflect the // DkmInspectionContext's DkmEvaluationFlags), and the type is from an assembly // with no symbols. var hideNonPublicBehavior = DeclarationInfo.None; if (hideNonPublic) { var moduleInstance = appDomain.FindClrModuleInstance(type.Module.ModuleVersionId); if (moduleInstance == null || moduleInstance.Module == null) { // Synthetic module or no symbols loaded. hideNonPublicBehavior = DeclarationInfo.HideNonPublic; } } foreach (var member in type.GetMembers(MemberBindingFlags)) { if (!predicate(member)) { continue; } var memberName = member.Name; // This represents information about the immediately preceding (more derived) // declaration with the same name as the current member. var previousDeclaration = DeclarationInfo.None; var memberNameAlreadySeen = false; if (includeInherited) { memberNameAlreadySeen = previousDeclarationMap.TryGetValue(memberName, out previousDeclaration); if (memberNameAlreadySeen) { // There was a name conflict, so we'll need to include the declaring // type of the member to disambiguate. previousDeclaration |= DeclarationInfo.IncludeTypeInMemberName; } // Update previous member with name hiding (casting) and declared location information for next time. previousDeclarationMap[memberName] = (previousDeclaration & ~(DeclarationInfo.RequiresExplicitCast | DeclarationInfo.FromSubTypeOfDeclaredType)) | member.AccessingBaseMemberWithSameNameRequiresExplicitCast() | memberLocation; } Debug.Assert(memberNameAlreadySeen != (previousDeclaration == DeclarationInfo.None)); // Decide whether to include this member in the list of members to display. if (!memberNameAlreadySeen || previousDeclaration.IsSet(DeclarationInfo.RequiresExplicitCast)) { DkmClrDebuggerBrowsableAttributeState?browsableStateValue = null; if (browsableState != null) { DkmClrDebuggerBrowsableAttributeState value; if (browsableState.TryGetValue(memberName, out value)) { browsableStateValue = value; } } if (memberLocation.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType)) { // If the current type is a sub-type of the declared type, then // we always need to insert a cast to access the member previousDeclaration |= DeclarationInfo.RequiresExplicitCast; } else if (previousDeclaration.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType)) { // If the immediately preceding member (less derived) was // declared on a sub-type of the declared type, then we'll // ignore the casting bit. Accessing a member through the // declared type is the same as casting to that type, so // the cast would be redundant. previousDeclaration &= ~DeclarationInfo.RequiresExplicitCast; } previousDeclaration |= hideNonPublicBehavior; includedMembers.Add(new MemberAndDeclarationInfo(member, browsableStateValue, previousDeclaration, inheritanceLevel)); } } if (!includeInherited) { break; } type = type.BaseType; inheritanceLevel++; } includedMembers.Sort(MemberAndDeclarationInfo.Comparer); } Example #52 0 Show file File: AnalysisEntityMapAbstractDomain.cs Project: elinor-fung/roslyn-analyzers public override DictionaryAnalysisData <AnalysisEntity, TValue> Merge(DictionaryAnalysisData <AnalysisEntity, TValue> map1, DictionaryAnalysisData <AnalysisEntity, TValue> map2) { AssertValidAnalysisData(map1); AssertValidAnalysisData(map2); var resultMap = new DictionaryAnalysisData <AnalysisEntity, TValue>(); using var newKeys = PooledHashSet <AnalysisEntity> .GetInstance(); using var valuesToMergeBuilder = ArrayBuilder <TValue> .GetInstance(5); var map2LookupIgnoringInstanceLocation = map2.Keys.Where(IsAnalysisEntityForFieldOrProperty) .ToLookup(entity => entity.EqualsIgnoringInstanceLocationId); foreach (var entry1 in map1) { AnalysisEntity key1 = entry1.Key; TValue value1 = entry1.Value; if (map2LookupIgnoringInstanceLocation.Count > 0 && IsAnalysisEntityForFieldOrProperty(key1)) { var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId]; if (!equivalentKeys2.Any()) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(!map2.ContainsKey(key1)); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); continue; } foreach (AnalysisEntity key2 in equivalentKeys2) { // Confirm that key2 and key1 are indeed EqualsIgnoringInstanceLocation // This ensures that we handle hash code clashes of EqualsIgnoringInstanceLocationId. if (!key1.EqualsIgnoringInstanceLocation(key2)) { continue; } TValue value2 = map2[key2]; valuesToMergeBuilder.Clear(); valuesToMergeBuilder.Add(value1); valuesToMergeBuilder.Add(value2); if (key1.InstanceLocation.Equals(key2.InstanceLocation)) { var mergedValue = GetMergedValue(valuesToMergeBuilder); AddNewEntryToResultMap(key1, mergedValue); } else { if (key1.SymbolOpt == null || !Equals(key1.SymbolOpt, key2.SymbolOpt)) { // PERF: Do not add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities. continue; } AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2); var isExistingKeyInInput = false; var isExistingKeyInResult = false; if (resultMap.TryGetValue(mergedKey, out var existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInResult = true; } if (map1.TryGetValue(mergedKey, out existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInInput = true; } if (map2.TryGetValue(mergedKey, out existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInInput = true; } var isCandidateToBeSkipped = !isExistingKeyInInput && !isExistingKeyInResult; if (isCandidateToBeSkipped && CanSkipNewEntity(mergedKey)) { // PERF: Do not add a new key-value pair to the resultMap if the key is not reachable from tracked entities and PointsTo values. continue; } var mergedValue = GetMergedValue(valuesToMergeBuilder); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); if (isCandidateToBeSkipped && CanSkipNewEntry(mergedKey, mergedValue)) { // PERF: Do not add a new key-value pair to the resultMap if the value can be skipped. continue; } if (!isExistingKeyInInput) { newKeys.Add(mergedKey); } AddNewEntryToResultMap(mergedKey, mergedValue, isNewKey: !isExistingKeyInInput); } } } else if (map2.TryGetValue(key1, out var value2)) { TValue mergedValue = ValueDomain.Merge(value1, value2); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); continue; } if (!resultMap.ContainsKey(key1)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); } } foreach (var kvp in map2) { var key2 = kvp.Key; var value2 = kvp.Value; if (!resultMap.ContainsKey(key2)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); AddNewEntryToResultMap(key2, mergedValue); } } foreach (var newKey in newKeys) { Debug.Assert(!map1.ContainsKey(newKey)); Debug.Assert(!map2.ContainsKey(newKey)); var value = resultMap[newKey]; if (ReferenceEquals(value, GetDefaultValue(newKey))) { resultMap.Remove(newKey); } else { OnNewMergedValue(value); } } Debug.Assert(Compare(map1, resultMap) <= 0); Debug.Assert(Compare(map2, resultMap) <= 0); AssertValidAnalysisData(resultMap); return(resultMap); Example #53 0 Show file internal ImmutableArray <TypeParameterConstraintClause> BindTypeParameterConstraintClauses( Symbol containingSymbol, ImmutableArray <TypeParameterSymbol> typeParameters, TypeParameterListSyntax typeParameterList, SyntaxList <TypeParameterConstraintClauseSyntax> clauses, ref IReadOnlyDictionary <TypeParameterSymbol, bool> isValueTypeOverride, DiagnosticBag diagnostics, bool isForOverride = false) { Debug.Assert(this.Flags.Includes(BinderFlags.GenericConstraintsClause)); RoslynDebug.Assert((object)containingSymbol != null); Debug.Assert((containingSymbol.Kind == SymbolKind.NamedType) || (containingSymbol.Kind == SymbolKind.Method)); Debug.Assert(typeParameters.Length > 0); Debug.Assert(clauses.Count > 0); int n = typeParameters.Length; // Create a map from type parameter name to ordinal. // No need to report duplicate names since duplicates // are reported when the type parameters are bound. var names = new Dictionary <string, int>(n, StringOrdinalComparer.Instance); foreach (var typeParameter in typeParameters) { var name = typeParameter.Name; if (!names.ContainsKey(name)) { names.Add(name, names.Count); } } // An array of constraint clauses, one for each type parameter, indexed by ordinal. var results = ArrayBuilder <TypeParameterConstraintClause?> .GetInstance(n, fillWithValue : null); var syntaxNodes = ArrayBuilder <ArrayBuilder <TypeConstraintSyntax>?> .GetInstance(n, fillWithValue : null); // Bind each clause and add to the results. foreach (var clause in clauses) { var name = clause.Name.Identifier.ValueText; RoslynDebug.Assert(name is object); int ordinal; if (names.TryGetValue(name, out ordinal)) { Debug.Assert(ordinal >= 0); Debug.Assert(ordinal < n); (TypeParameterConstraintClause constraintClause, ArrayBuilder <TypeConstraintSyntax>?typeConstraintNodes) = this.BindTypeParameterConstraints(typeParameterList.Parameters[ordinal], clause, isForOverride, diagnostics); if (results[ordinal] == null) { results[ordinal] = constraintClause; syntaxNodes[ordinal] = typeConstraintNodes; } else { // "A constraint clause has already been specified for type parameter '{0}'. ..." diagnostics.Add(ErrorCode.ERR_DuplicateConstraintClause, clause.Name.Location, name); typeConstraintNodes?.Free(); } } else { // Unrecognized type parameter. Don't bother binding the constraints // (the ": I<U>" in "where U : I<U>") since that will lead to additional // errors ("type or namespace 'U' could not be found") if the type // parameter is referenced in the constraints. // "'{1}' does not define type parameter '{0}'" diagnostics.Add(ErrorCode.ERR_TyVarNotFoundInConstraint, clause.Name.Location, name, containingSymbol.ConstructedFrom()); } } // Add default values for type parameters without constraint clauses. for (int i = 0; i < n; i++) { if (results[i] == null) { results[i] = GetDefaultTypeParameterConstraintClause(typeParameterList.Parameters[i], isForOverride); } } TypeParameterConstraintClause.AdjustConstraintTypes(containingSymbol, typeParameters, results, ref isValueTypeOverride); RemoveInvalidConstraints(typeParameters, results !, syntaxNodes, diagnostics); foreach (var typeConstraintsSyntaxes in syntaxNodes) { typeConstraintsSyntaxes?.Free(); } syntaxNodes.Free(); return(results.ToImmutableAndFree() !); } Example #54 0 Show file File: UserDefinedImplicitConversions.cs Project: zyonet/roslyn /// <remarks> /// NOTE: Keep this method in sync with AnalyzeImplicitUserDefinedConversion. /// </remarks> protected UserDefinedConversionResult AnalyzeImplicitUserDefinedConversionForV6SwitchGoverningType(TypeSymbol source, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { // SPEC: The governing type of a switch statement is established by the switch expression. // SPEC: 1) If the type of the switch expression is sbyte, byte, short, ushort, int, uint, // SPEC: long, ulong, bool, char, string, or an enum-type, or if it is the nullable type // SPEC: corresponding to one of these types, then that is the governing type of the switch statement. // SPEC: 2) Otherwise, exactly one user-defined implicit conversion (ยง6.4) must exist from the // SPEC: type of the switch expression to one of the following possible governing types: // SPEC: sbyte, byte, short, ushort, int, uint, long, ulong, char, string, or, a nullable type // SPEC: corresponding to one of those types // NOTE: This method implements part (2) above, it should be called only if (1) is false for source type. Debug.Assert((object)source != null); Debug.Assert(!source.IsValidV6SwitchGoverningType()); // NOTE: For (2) we use an approach similar to native compiler's approach, but call into the common code for analyzing user defined implicit conversions. // NOTE: (a) Compute the set of types D from which user-defined conversion operators should be considered by considering only the source type. // NOTE: (b) Instead of computing applicable user defined implicit conversions U from the source type to a specific target type, // NOTE: we compute these from the source type to ANY target type. // NOTE: (c) From the conversions in U, select the most specific of them that targets a valid switch governing type // SPEC VIOLATION: Because we use the same strategy for computing the most specific conversion, as the Dev10 compiler did (in fact // SPEC VIOLATION: we share the code), we inherit any spec deviances in that analysis. Specifically, the analysis only considers // SPEC VIOLATION: which conversion has the least amount of lifting, where a conversion may be considered to be in unlifted form, // SPEC VIOLATION: half-lifted form (only the argument type or return type is lifted) or fully lifted form. The most specific computation // SPEC VIOLATION: looks for a unique conversion that is least lifted. The spec, on the other hand, requires that the conversion // SPEC VIOLATION: be *unique*, not merely most use the least amount of lifting among the applicable conversions. // SPEC VIOLATION: This introduces a SPEC VIOLATION for the following tests in the native compiler: // NOTE: // See test SwitchTests.CS0166_AggregateTypeWithMultipleImplicitConversions_07 // NOTE: struct Conv // NOTE: { // NOTE: public static implicit operator int (Conv C) { return 1; } // NOTE: public static implicit operator int (Conv? C2) { return 0; } // NOTE: public static int Main() // NOTE: { // NOTE: Conv? D = new Conv(); // NOTE: switch(D) // NOTE: { ... // SPEC VIOLATION: Native compiler allows the above code to compile // SPEC VIOLATION: even though there are two user-defined implicit conversions: // SPEC VIOLATION: 1) To int type (applicable in normal form): public static implicit operator int (Conv? C2) // SPEC VIOLATION: 2) To int? type (applicable in lifted form): public static implicit operator int (Conv C) // NOTE: // See also test SwitchTests.TODO // NOTE: struct Conv // NOTE: { // NOTE: public static implicit operator int? (Conv C) { return 1; } // NOTE: public static implicit operator string (Conv? C2) { return 0; } // NOTE: public static int Main() // NOTE: { // NOTE: Conv? D = new Conv(); // NOTE: switch(D) // NOTE: { ... // SPEC VIOLATION: Native compiler allows the above code to compile too // SPEC VIOLATION: even though there are two user-defined implicit conversions: // SPEC VIOLATION: 1) To string type (applicable in normal form): public static implicit operator string (Conv? C2) // SPEC VIOLATION: 2) To int? type (applicable in half-lifted form): public static implicit operator int? (Conv C) // SPEC VIOLATION: This occurs because the native compiler compares the applicable conversions to find one with the least amount // SPEC VIOLATION: of lifting, ignoring whether the return types are the same or not. // SPEC VIOLATION: We do the same to maintain compatibility with the native compiler. // (a) Compute the set of types D from which user-defined conversion operators should be considered by considering only the source type. var d = ArrayBuilder <NamedTypeSymbol> .GetInstance(); ComputeUserDefinedImplicitConversionTypeSet(source, t: null, d: d, useSiteDiagnostics: ref useSiteDiagnostics); // (b) Instead of computing applicable user defined implicit conversions U from the source type to a specific target type, // we compute these from the source type to ANY target type. We will filter out those that are valid switch governing // types later. var ubuild = ArrayBuilder <UserDefinedConversionAnalysis> .GetInstance(); ComputeApplicableUserDefinedImplicitConversionSet(null, source, target: null, d: d, u: ubuild, useSiteDiagnostics: ref useSiteDiagnostics, allowAnyTarget: true); d.Free(); ImmutableArray <UserDefinedConversionAnalysis> u = ubuild.ToImmutableAndFree(); // (c) Find that conversion with the least amount of lifting int?best = MostSpecificConversionOperator(conv => conv.ToType.IsValidV6SwitchGoverningType(isTargetTypeOfUserDefinedOp: true), u); if (best != null) { return(UserDefinedConversionResult.Valid(u, best.Value)); } return(UserDefinedConversionResult.NoApplicableOperators(u)); } Example #55 0 Show file private (TypeParameterConstraintClause, ArrayBuilder <TypeConstraintSyntax>?) BindTypeParameterConstraints(TypeParameterSyntax typeParameterSyntax, TypeParameterConstraintClauseSyntax constraintClauseSyntax, bool isForOverride, DiagnosticBag diagnostics) { var constraints = TypeParameterConstraintKind.None; ArrayBuilder <TypeWithAnnotations>? constraintTypes = null; ArrayBuilder <TypeConstraintSyntax>?syntaxBuilder = null; SeparatedSyntaxList <TypeParameterConstraintSyntax> constraintsSyntax = constraintClauseSyntax.Constraints; Debug.Assert(!InExecutableBinder); // Cannot eagerly report diagnostics handled by LazyMissingNonNullTypesContextDiagnosticInfo bool hasTypeLikeConstraint = false; bool reportedOverrideWithConstraints = false; for (int i = 0, n = constraintsSyntax.Count; i < n; i++) { var syntax = constraintsSyntax[i]; switch (syntax.Kind()) { case SyntaxKind.ClassConstraint: hasTypeLikeConstraint = true; if (i != 0) { if (!reportedOverrideWithConstraints) { reportTypeConstraintsMustBeUniqueAndFirst(syntax, diagnostics); } if (isForOverride && (constraints & (TypeParameterConstraintKind.ValueType | TypeParameterConstraintKind.ReferenceType)) != 0) { continue; } } var constraintSyntax = (ClassOrStructConstraintSyntax)syntax; SyntaxToken questionToken = constraintSyntax.QuestionToken; if (questionToken.IsKind(SyntaxKind.QuestionToken)) { constraints |= TypeParameterConstraintKind.NullableReferenceType; if (isForOverride) { reportOverrideWithConstraints(ref reportedOverrideWithConstraints, syntax, diagnostics); } else { LazyMissingNonNullTypesContextDiagnosticInfo.ReportNullableReferenceTypesIfNeeded(AreNullableAnnotationsEnabled(questionToken), questionToken.GetLocation(), diagnostics); } } else if (isForOverride || AreNullableAnnotationsEnabled(constraintSyntax.ClassOrStructKeyword)) { constraints |= TypeParameterConstraintKind.NotNullableReferenceType; } else { constraints |= TypeParameterConstraintKind.ReferenceType; } continue; case SyntaxKind.StructConstraint: hasTypeLikeConstraint = true; if (i != 0) { if (!reportedOverrideWithConstraints) { reportTypeConstraintsMustBeUniqueAndFirst(syntax, diagnostics); } if (isForOverride && (constraints & (TypeParameterConstraintKind.ValueType | TypeParameterConstraintKind.ReferenceType)) != 0) { continue; } } constraints |= TypeParameterConstraintKind.ValueType; continue; case SyntaxKind.ConstructorConstraint: if (isForOverride) { reportOverrideWithConstraints(ref reportedOverrideWithConstraints, syntax, diagnostics); continue; } if ((constraints & TypeParameterConstraintKind.ValueType) != 0) { diagnostics.Add(ErrorCode.ERR_NewBoundWithVal, syntax.GetFirstToken().GetLocation()); } if ((constraints & TypeParameterConstraintKind.Unmanaged) != 0) { diagnostics.Add(ErrorCode.ERR_NewBoundWithUnmanaged, syntax.GetFirstToken().GetLocation()); } if (i != n - 1) { diagnostics.Add(ErrorCode.ERR_NewBoundMustBeLast, syntax.GetFirstToken().GetLocation()); } constraints |= TypeParameterConstraintKind.Constructor; continue; case SyntaxKind.DefaultConstraint: if (!isForOverride) { diagnostics.Add(ErrorCode.ERR_DefaultConstraintOverrideOnly, syntax.GetLocation()); } if (i != 0) { if (!reportedOverrideWithConstraints) { reportTypeConstraintsMustBeUniqueAndFirst(syntax, diagnostics); } if (isForOverride && (constraints & (TypeParameterConstraintKind.ValueType | TypeParameterConstraintKind.ReferenceType)) != 0) { continue; } } constraints |= TypeParameterConstraintKind.Default; continue; case SyntaxKind.TypeConstraint: if (isForOverride) { reportOverrideWithConstraints(ref reportedOverrideWithConstraints, syntax, diagnostics); } else { hasTypeLikeConstraint = true; if (constraintTypes == null) { constraintTypes = ArrayBuilder <TypeWithAnnotations> .GetInstance(); syntaxBuilder = ArrayBuilder <TypeConstraintSyntax> .GetInstance(); } var typeConstraintSyntax = (TypeConstraintSyntax)syntax; var typeSyntax = typeConstraintSyntax.Type; var type = BindTypeOrConstraintKeyword(typeSyntax, diagnostics, out ConstraintContextualKeyword keyword); switch (keyword) { case ConstraintContextualKeyword.Unmanaged: if (i != 0) { reportTypeConstraintsMustBeUniqueAndFirst(typeSyntax, diagnostics); continue; } // This should produce diagnostics if the types are missing GetWellKnownType(WellKnownType.System_Runtime_InteropServices_UnmanagedType, diagnostics, typeSyntax); GetSpecialType(SpecialType.System_ValueType, diagnostics, typeSyntax); constraints |= TypeParameterConstraintKind.Unmanaged; continue; case ConstraintContextualKeyword.NotNull: if (i != 0) { reportTypeConstraintsMustBeUniqueAndFirst(typeSyntax, diagnostics); } constraints |= TypeParameterConstraintKind.NotNull; continue; case ConstraintContextualKeyword.None: break; default: throw ExceptionUtilities.UnexpectedValue(keyword); } constraintTypes.Add(type); syntaxBuilder !.Add(typeConstraintSyntax); } continue; default: throw ExceptionUtilities.UnexpectedValue(syntax.Kind()); } } if (!isForOverride && !hasTypeLikeConstraint && !AreNullableAnnotationsEnabled(typeParameterSyntax.Identifier)) { constraints |= TypeParameterConstraintKind.ObliviousNullabilityIfReferenceType; } Debug.Assert(!isForOverride || (constraints & (TypeParameterConstraintKind.ReferenceType | TypeParameterConstraintKind.ValueType)) != (TypeParameterConstraintKind.ReferenceType | TypeParameterConstraintKind.ValueType)); return(TypeParameterConstraintClause.Create(constraints, constraintTypes?.ToImmutableAndFree() ?? ImmutableArray <TypeWithAnnotations> .Empty), syntaxBuilder); Example #56 0 Show file private static ImmutableArray <CodeFix> GetConfigurations(Project project, IEnumerable <Diagnostic> diagnostics, CancellationToken cancellationToken) { var result = ArrayBuilder <CodeFix> .GetInstance(); foreach (var diagnostic in diagnostics) { // First get all the relevant code style options for the diagnostic. var codeStyleOptions = ConfigurationUpdater.GetCodeStyleOptionsForDiagnostic(diagnostic, project); if (codeStyleOptions.IsEmpty) { continue; } // For each code style option, create a top level code action with nested code actions for every valid option value. // For example, if the option value is CodeStyleOption<bool>, we will have two nested actions, one for 'true' setting and one // for 'false' setting. If the option value is CodeStyleOption<SomeEnum>, we will have a nested action for each enum field. using var _ = ArrayBuilder <CodeAction> .GetInstance(out var nestedActions); var optionSet = project.Solution.Workspace.Options; var hasMultipleOptions = codeStyleOptions.Length > 1; foreach (var(optionKey, codeStyleOption, editorConfigLocation, perLanguageOption) in codeStyleOptions.OrderBy(t => t.optionKey.Option.Name)) { var topLevelAction = GetCodeActionForCodeStyleOption(optionKey, codeStyleOption, editorConfigLocation, diagnostic, perLanguageOption, optionSet, hasMultipleOptions); if (topLevelAction != null) { nestedActions.Add(topLevelAction); } } if (nestedActions.Count != 0) { // Wrap actions by another level if the diagnostic ID has multiple associated code style options to reduce clutter. var resultCodeAction = nestedActions.Count > 1 ? new TopLevelConfigureCodeStyleOptionCodeAction(diagnostic, nestedActions.ToImmutable()) : nestedActions.Single(); result.Add(new CodeFix(project, resultCodeAction, diagnostic)); } } return(result.ToImmutableAndFree()); // Local functions TopLevelConfigureCodeStyleOptionCodeAction GetCodeActionForCodeStyleOption( OptionKey optionKey, ICodeStyleOption codeStyleOption, IEditorConfigStorageLocation2 editorConfigLocation, Diagnostic diagnostic, bool isPerLanguage, OptionSet optionSet, bool hasMultipleOptions) { // Add a code action for every valid value of the given code style option. // We only support light-bulb configuration of code style options with boolean or enum values. using var _ = ArrayBuilder <CodeAction> .GetInstance(out var nestedActions); var severity = codeStyleOption.Notification.ToEditorConfigString(); string optionName = null; if (codeStyleOption.Value is bool) { foreach (var boolValue in s_boolValues) { AddCodeActionWithOptionValue(codeStyleOption, boolValue); } } else if (codeStyleOption.Value?.GetType() is Type t && t.IsEnum) { foreach (var enumValue in Enum.GetValues(t)) { AddCodeActionWithOptionValue(codeStyleOption, enumValue); } } if (nestedActions.Count > 0) { // If this is not a unique code style option for the diagnostic, use the optionName as the code action title. // In that case, we will already have a containing top level action for the diagnostic. // Otherwise, use the diagnostic information in the title. return(hasMultipleOptions ? new TopLevelConfigureCodeStyleOptionCodeAction(optionName, nestedActions.ToImmutable()) : new TopLevelConfigureCodeStyleOptionCodeAction(diagnostic, nestedActions.ToImmutable())); } return(null); // Local functions void AddCodeActionWithOptionValue(ICodeStyleOption codeStyleOption, object newValue) { // Create a new code style option value with the newValue var configuredCodeStyleOption = codeStyleOption.WithValue(newValue); // Try to get the parsed editorconfig string representation of the new code style option value if (ConfigurationUpdater.TryGetEditorConfigStringParts(configuredCodeStyleOption, editorConfigLocation, optionSet, out var parts)) { // We expect all code style values for same code style option to have the same editorconfig option name. Debug.Assert(optionName == null || optionName == parts.optionName); optionName ??= parts.optionName; // Add code action to configure the optionValue. nestedActions.Add( new SolutionChangeAction( parts.optionValue, solution => ConfigurationUpdater.ConfigureCodeStyleOptionAsync(parts.optionName, parts.optionValue, diagnostic, isPerLanguage, project, cancellationToken))); } } } } Example #57 0 Show file private ImmutableArray <ParameterSymbol> MakeParameters( CSharpCompilation compilation, UnboundLambda unboundLambda, ImmutableArray <TypeWithAnnotations> parameterTypes, ImmutableArray <RefKind> parameterRefKinds ) { Debug.Assert(parameterTypes.Length == parameterRefKinds.Length); if (!unboundLambda.HasSignature || unboundLambda.ParameterCount == 0) { // The parameters may be omitted in source, but they are still present on the symbol. return(parameterTypes.SelectAsArray( (type, ordinal, arg) => SynthesizedParameterSymbol.Create( arg.owner, type, ordinal, arg.refKinds[ordinal], GeneratedNames.LambdaCopyParameterName(ordinal) ), // Make sure nothing binds to this. (owner: this, refKinds: parameterRefKinds) )); } var builder = ArrayBuilder <ParameterSymbol> .GetInstance(unboundLambda.ParameterCount); var hasExplicitlyTypedParameterList = unboundLambda.HasExplicitlyTypedParameterList; var numDelegateParameters = parameterTypes.Length; for (int p = 0; p < unboundLambda.ParameterCount; ++p) { // If there are no types given in the lambda then used the delegate type. // If the lambda is typed then the types probably match the delegate types; // if they do not, use the lambda types for binding. Either way, if we // can, then we use the lambda types. (Whatever you do, do not use the names // in the delegate parameters; they are not in scope!) TypeWithAnnotations type; RefKind refKind; if (hasExplicitlyTypedParameterList) { type = unboundLambda.ParameterTypeWithAnnotations(p); refKind = unboundLambda.RefKind(p); } else if (p < numDelegateParameters) { type = parameterTypes[p]; refKind = parameterRefKinds[p]; } else { type = TypeWithAnnotations.Create( new ExtendedErrorTypeSymbol( compilation, name: string.Empty, arity: 0, errorInfo: null ) ); refKind = RefKind.None; } var name = unboundLambda.ParameterName(p); var location = unboundLambda.ParameterLocation(p); var locations = location == null ? ImmutableArray <Location> .Empty : ImmutableArray.Create <Location>(location); var parameter = new SourceSimpleParameterSymbol( owner: this, type, ordinal: p, refKind, name, unboundLambda.ParameterIsDiscard(p), locations ); builder.Add(parameter); } var result = builder.ToImmutableAndFree(); return(result); } Example #58 0 Show file File: SynthesizedImplementationMethod.cs Project: tinaschrepfer/roslyn internal sealed override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(compilationState, ref attributes); if (_debuggerHidden) { var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); } if (this.ReturnType.ContainsDynamic()) { var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length)); } } Example #59 0 Show file File: AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs Project: tmcmil/roslyn private void AddDebuggerDisplayAttributeArguments(INamedTypeSymbol namedTypeSymbol, ArrayBuilder <string> builder) { AddDebuggerDisplayAttributeArgumentsCore(namedTypeSymbol, builder); foreach (var member in namedTypeSymbol.GetMembers()) { switch (member) { case INamedTypeSymbol nestedType: AddDebuggerDisplayAttributeArguments(nestedType, builder); break; case IPropertySymbol _: case IFieldSymbol _: AddDebuggerDisplayAttributeArgumentsCore(member, builder); break; } } } Example #60 0 Show file File: UserDefinedImplicitConversions.cs Project: zyonet/roslyn /// <remarks> /// NOTE: Keep this method in sync with <see cref="AnalyzeImplicitUserDefinedConversionForV6SwitchGoverningType"/>. /// </remarks> private UserDefinedConversionResult AnalyzeImplicitUserDefinedConversions( BoundExpression sourceExpression, TypeSymbol source, TypeSymbol target, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(sourceExpression != null || (object)source != null); Debug.Assert((object)target != null); // User-defined conversions that involve generics can be quite strange. There // are two basic problems: first, that generic user-defined conversions can be // "shadowed" by built-in conversions, and second, that generic user-defined // conversions can make conversions that would never have been legal user-defined // conversions if declared non-generically. I call this latter kind of conversion // a "suspicious" conversion. // // The shadowed conversions are easily dealt with: // // SPEC: If a predefined implicit conversion exists from a type S to type T, // SPEC: all user-defined conversions, implicit or explicit, are ignored. // SPEC: If a predefined explicit conversion exists from a type S to type T, // SPEC: any user-defined explicit conversion from S to T are ignored. // // The rule above can come into play in cases like: // // sealed class C<T> { public static implicit operator T(C<T> c) { ... } } // C<object> c = whatever; // object o = c; // // The built-in implicit conversion from C<object> to object must shadow // the user-defined implicit conversion. // // The caller of this method checks for user-defined conversions *after* // predefined implicit conversions, so we already know that if we got here, // there was no predefined implicit conversion. // // Note that a user-defined *implicit* conversion may win over a built-in // *explicit* conversion by the rule given above. That is, if we created // an implicit conversion from T to C<T>, then the user-defined implicit // conversion from object to C<object> could be valid, even though that // would be "replacing" a built-in explicit conversion with a user-defined // implicit conversion. This is one of the "suspicious" conversions, // as it would not be legal to declare a user-defined conversion from // object in a non-generic type. // // The way the native compiler handles suspicious conversions involving // interfaces is neither sensible nor in line with the rules in the // specification. It is not clear at this time whether we should be exactly // matching the native compiler, the specification, or neither, in Roslyn. // Spec (6.4.4 User-defined implicit conversions) // A user-defined implicit conversion from an expression E to type T is processed as follows: // SPEC: Find the set of types D from which user-defined conversion operators... var d = ArrayBuilder <NamedTypeSymbol> .GetInstance(); ComputeUserDefinedImplicitConversionTypeSet(source, target, d, ref useSiteDiagnostics); // SPEC: Find the set of applicable user-defined and lifted conversion operators, U... var ubuild = ArrayBuilder <UserDefinedConversionAnalysis> .GetInstance(); ComputeApplicableUserDefinedImplicitConversionSet(sourceExpression, source, target, d, ubuild, ref useSiteDiagnostics); d.Free(); ImmutableArray <UserDefinedConversionAnalysis> u = ubuild.ToImmutableAndFree(); // SPEC: If U is empty, the conversion is undefined and a compile-time error occurs. if (u.Length == 0) { return(UserDefinedConversionResult.NoApplicableOperators(u)); } // SPEC: Find the most specific source type SX of the operators in U... TypeSymbol sx = MostSpecificSourceTypeForImplicitUserDefinedConversion(u, source, ref useSiteDiagnostics); if ((object)sx == null) { return(UserDefinedConversionResult.NoBestSourceType(u)); } // SPEC: Find the most specific target type TX of the operators in U... TypeSymbol tx = MostSpecificTargetTypeForImplicitUserDefinedConversion(u, target, ref useSiteDiagnostics); if ((object)tx == null) { return(UserDefinedConversionResult.NoBestTargetType(u)); } int?best = MostSpecificConversionOperator(sx, tx, u); if (best == null) { return(UserDefinedConversionResult.Ambiguous(u)); } return(UserDefinedConversionResult.Valid(u, best.Value)); }
protected internal override object VisitPointerType(PointerTypeSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder) { VisitType(symbol.PointedAtType, builder); AddPunctuation(SyntaxKind.AsteriskToken, builder); return null; }
internal Context(ArrayBuilder<SyntaxTree> builder, Compilation compilation, string path, bool writeToDisk) { _builder = builder; _compilation = compilation; _path = path; _writeToDisk = writeToDisk; }
protected internal override object VisitArrayType(ArrayTypeSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder) { //See spec section 12.1 for the order of rank specificiers //e.g. int[][,][,,] is stored as // ArrayType // Rank = 1 // ElementType = ArrayType // Rank = 2 // ElementType = ArrayType // Rank = 3 // ElementType = int TypeSymbol underlyingNonArrayType = symbol.ElementType; while (underlyingNonArrayType.TypeKind == TypeKind.ArrayType) { underlyingNonArrayType = ((ArrayTypeSymbol)underlyingNonArrayType).ElementType; } VisitType(underlyingNonArrayType, builder); ArrayTypeSymbol arrayType = symbol; while (arrayType != null) { AddArrayRank(arrayType, builder); arrayType = arrayType.ElementType as ArrayTypeSymbol; } return null; }
internal static void AddSymbolDisplayParts(ArrayBuilder<SymbolDisplayPart> parts, string str) { PooledStringBuilder pooledBuilder = PooledStringBuilder.GetInstance(); StringBuilder sb = pooledBuilder.Builder; int lastKind = -1; foreach (int token in TokenizeString(str, quote: true, nonPrintableSubstitute: '\0', useHexadecimalNumbers: true)) { int kind = token >> 16; // merge contiguous tokens of the same kind into a single part: if (lastKind >= 0 && lastKind != kind) { parts.Add(new SymbolDisplayPart((SymbolDisplayPartKind)lastKind, null, sb.ToString())); sb.Clear(); } lastKind = kind; sb.Append(unchecked((char)token)); } if (lastKind >= 0) { parts.Add(new SymbolDisplayPart((SymbolDisplayPartKind)lastKind, null, sb.ToString())); } pooledBuilder.Free(); }
/// <summary> /// Lower the given decision tree into the given statement builder. /// </summary> public void LowerDecisionTree(BoundExpression expression, DecisionTree decisionTree, ArrayBuilder<BoundStatement> loweredDecisionTree) { var oldLoweredDecisionTree = this._loweredDecisionTree; this._loweredDecisionTree = loweredDecisionTree; LowerDecisionTree(expression, decisionTree); this._loweredDecisionTree = oldLoweredDecisionTree; }
internal override void GetRows( ResultProvider resultProvider, ArrayBuilder<EvalResult> rows, DkmInspectionContext inspectionContext, EvalResultDataItem parent, DkmClrValue value, int startIndex, int count, bool visitAll, ref int index) { var fields = GetFields(); int startIndex2; int count2; GetIntersection(startIndex, count, index, fields.Count, out startIndex2, out count2); int offset = startIndex2 - index; for (int i = 0; i < count2; i++) { var row = GetMemberRow(resultProvider, inspectionContext, value, fields[i + offset], parent); rows.Add(row); } index += fields.Count; }
/// <summary> /// Adds aliases of a specified reference to the merged set of aliases. /// Consider the following special cases: /// /// o {} + {} = {} /// If neither reference has any aliases then the result has no aliases. /// /// o {A} + {} = {A, global} /// {} + {A} = {A, global} /// /// If one and only one of the references has aliases we add the global alias since the /// referenced declarations should now be accessible both via existing aliases /// as well as unqualified. /// /// o {A, A} + {A, B, B} = {A, A, B, B} /// We preserve dups in each alias array, but avoid making more dups when merging. /// </summary> internal void Merge(MetadataReference reference) { if (reference.Properties.HasRecursiveAliases) { if (RecursiveAliasesOpt == null) { RecursiveAliasesOpt = ArrayBuilder<string>.GetInstance(); RecursiveAliasesOpt.AddRange(reference.Properties.Aliases); return; } } else { if (AliasesOpt == null) { AliasesOpt = ArrayBuilder<string>.GetInstance(); AliasesOpt.AddRange(reference.Properties.Aliases); return; } } Merge( aliases: reference.Properties.HasRecursiveAliases ? RecursiveAliasesOpt : AliasesOpt, newAliases: reference.Properties.Aliases); }
private void AccessTupleFields(BoundDeconstructionAssignmentOperator node, BoundDeconstructionDeconstructStep deconstruction, ArrayBuilder<LocalSymbol> temps, ArrayBuilder<BoundExpression> stores, ArrayBuilder<BoundValuePlaceholderBase> placeholders) { var target = PlaceholderReplacement(deconstruction.TargetPlaceholder); var tupleType = target.Type.IsTupleType ? target.Type : TupleTypeSymbol.Create((NamedTypeSymbol)target.Type); var tupleElementTypes = tupleType.TupleElementTypes; var numElements = tupleElementTypes.Length; CSharpSyntaxNode syntax = node.Syntax; // save the target as we need to access it multiple times BoundAssignmentOperator assignmentToTemp; var savedTuple = _factory.StoreToTemp(target, out assignmentToTemp); stores.Add(assignmentToTemp); temps.Add(savedTuple.LocalSymbol); // list the tuple fields accessors var fields = tupleType.TupleElementFields; for (int i = 0; i < numElements; i++) { var field = fields[i]; DiagnosticInfo useSiteInfo = field.GetUseSiteDiagnostic(); if ((object)useSiteInfo != null && useSiteInfo.Severity == DiagnosticSeverity.Error) { Symbol.ReportUseSiteDiagnostic(useSiteInfo, _diagnostics, syntax.Location); } var fieldAccess = MakeTupleFieldAccess(syntax, field, savedTuple, null, LookupResultKind.Empty); AddPlaceholderReplacement(deconstruction.OutputPlaceholders[i], fieldAccess); placeholders.Add(deconstruction.OutputPlaceholders[i]); } }
/// <summary> /// Create a SequencePointList with the raw sequence points from an ArrayBuilder. /// A linked list of instances for each syntax tree is created (almost always of length one). /// </summary> public static SequencePointList Create(ArrayBuilder<RawSequencePoint> seqPointBuilder, ILBuilder builder) { if (seqPointBuilder.Count == 0) { return SequencePointList.s_empty; } SequencePointList first = null, current = null; int totalPoints = seqPointBuilder.Count; int last = 0; for (int i = 1; i <= totalPoints; ++i) { if (i == totalPoints || seqPointBuilder[i].SyntaxTree != seqPointBuilder[i - 1].SyntaxTree) { // Create a new list SequencePointList next = new SequencePointList(seqPointBuilder[i - 1].SyntaxTree, GetSubArray(seqPointBuilder, last, i - last, builder)); last = i; // Link together with any additional. if (current == null) { first = current = next; } else { current._next = next; current = next; } } } return first; }
private static void AddNonIncluded(ArrayBuilder<string> builder, string item) { if (!builder.Contains(item)) { builder.Add(item); } }
private static void GetAllScopes( ISymUnmanagedScope root, ArrayBuilder<ISymUnmanagedScope> allScopes, ArrayBuilder<ISymUnmanagedScope> containingScopes, int offset, bool isScopeEndInclusive) { var stack = ArrayBuilder<ISymUnmanagedScope>.GetInstance(); stack.Push(root); while (stack.Any()) { var scope = stack.Pop(); allScopes.Add(scope); if (offset >= 0 && scope.IsInScope(offset, isScopeEndInclusive)) { containingScopes.Add(scope); } foreach (var nested in scope.GetScopes()) { stack.Push(nested); } } stack.Free(); }
private DynamicFlagsCustomTypeInfo(ArrayBuilder<bool> dynamicFlags, int startIndex) { Debug.Assert(dynamicFlags != null); Debug.Assert(startIndex >= 0); int numFlags = dynamicFlags.Count - startIndex; Debug.Assert(numFlags > 0); int numBytes = (numFlags + 7) / 8; byte[] bytes = new byte[numBytes]; bool seenTrue = false; for (int b = 0; b < numBytes; b++) { for (int i = 0; i < 8; i++) { var f = b * 8 + i; if (f >= numFlags) { Debug.Assert(f == numFlags); goto ALL_FLAGS_READ; } if (dynamicFlags[startIndex + f]) { seenTrue = true; bytes[b] |= (byte)(1 << i); } } } ALL_FLAGS_READ: _bytes = seenTrue ? new ReadOnlyCollection<byte>(bytes) : null; }
/// <summary> /// Applies the conversions. /// Adds any new locals to the temps and any new expressions to be evaluated to the stores. /// </summary> private void ApplyConversions(BoundDeconstructionAssignmentOperator node, ArrayBuilder<LocalSymbol> temps, ArrayBuilder<BoundExpression> stores, ArrayBuilder<BoundValuePlaceholderBase> placeholders) { int numConversions = node.ConversionSteps.Length; var conversionLocals = ArrayBuilder<BoundExpression>.GetInstance(); foreach (var conversionInfo in node.ConversionSteps) { // lower the conversions and assignments to locals var localSymbol = new SynthesizedLocal(_factory.CurrentMethod, conversionInfo.OutputPlaceholder.Type, SynthesizedLocalKind.LoweringTemp); var localBound = new BoundLocal(node.Syntax, localSymbol, null, conversionInfo.OutputPlaceholder.Type) { WasCompilerGenerated = true }; temps.Add(localSymbol); conversionLocals.Add(localBound); AddPlaceholderReplacement(conversionInfo.OutputPlaceholder, localBound); placeholders.Add(conversionInfo.OutputPlaceholder); var conversion = VisitExpression(conversionInfo.Assignment); stores.Add(conversion); } }
internal override void AddSynthesizedAttributes(ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(ref attributes); var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); }
internal override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(compilationState, ref attributes); CSharpCompilation compilation = this.DeclaringCompilation; // do not emit CompilerGenerated attributes for fields inside compiler generated types: if (!_containingType.IsImplicitlyDeclared) { AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); } if (!this.SuppressDynamicAttribute && this.Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes() && compilation.CanEmitBoolean()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length)); } if (Type.ContainsTuple() && compilation.HasTupleNamesAttributes && compilation.CanEmitSpecialType(SpecialType.System_String)) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttributeOpt(Type)); } }
internal SpillBuilder() { locals = ArrayBuilder<LocalSymbol>.GetInstance(); temps = ArrayBuilder<BoundSpillTemp>.GetInstance(); statements = ArrayBuilder<BoundStatement>.GetInstance(); fields = ArrayBuilder<FieldSymbol>.GetInstance(); }
public LargeTextWriter(Encoding encoding, SourceHashAlgorithm checksumAlgorithm, int length) { _encoding = encoding; _checksumAlgorithm = checksumAlgorithm; _chunks = ArrayBuilder<char[]>.GetInstance(1 + length / LargeText.ChunkSize); _bufferSize = Math.Min(LargeText.ChunkSize, length); }
internal override void AddSynthesizedAttributes(ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(ref attributes); var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); }
internal abstract ReadOnlyCollection<byte> CompileGetLocals( ArrayBuilder<LocalAndMethod> locals, bool argumentsOnly, ImmutableArray<Alias> aliases, DiagnosticBag diagnostics, out string typeName, CompilationTestData testData);
// Rewrite collection initializer add method calls: // 2) new List<int> { 1 }; // ~ private void AddCollectionInitializers(ref ArrayBuilder<BoundExpression> dynamicSiteInitializers, ArrayBuilder<BoundExpression> result, BoundExpression rewrittenReceiver, ImmutableArray<BoundExpression> initializers) { Debug.Assert(rewrittenReceiver != null || _inExpressionLambda); foreach (var initializer in initializers) { // In general bound initializers may contain bad expressions or element initializers. // We don't lower them if they contain errors, so it's safe to assume an element initializer. BoundExpression rewrittenInitializer; if (initializer.Kind == BoundKind.CollectionElementInitializer) { rewrittenInitializer = MakeCollectionInitializer(rewrittenReceiver, (BoundCollectionElementInitializer)initializer); } else { Debug.Assert(!_inExpressionLambda); Debug.Assert(initializer.Kind == BoundKind.DynamicCollectionElementInitializer); rewrittenInitializer = MakeDynamicCollectionInitializer(rewrittenReceiver, (BoundDynamicCollectionElementInitializer)initializer); } // the call to Add may be omitted if (rewrittenInitializer != null) { result.Add(rewrittenInitializer); } } }
internal void CollectLocalsFromDeconstruction( ExpressionSyntax declaration, LocalDeclarationKind kind, ArrayBuilder<LocalSymbol> locals, SyntaxNode deconstructionStatement, Binder enclosingBinderOpt = null) { switch (declaration.Kind()) { case SyntaxKind.TupleExpression: { var tuple = (TupleExpressionSyntax)declaration; foreach (var arg in tuple.Arguments) { CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt); } break; } case SyntaxKind.DeclarationExpression: { var declarationExpression = (DeclarationExpressionSyntax)declaration; CollectLocalsFromDeconstruction( declarationExpression.Designation, declarationExpression.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); break; } case SyntaxKind.IdentifierName: break; default: throw ExceptionUtilities.UnexpectedValue(declaration.Kind()); } }
private LookupResult(ObjectPool<LookupResult> pool) { this.pool = pool; this.kind = LookupResultKind.Empty; this.symbolList = new ArrayBuilder<Symbol>(); this.error = null; }
DispatchMapEntry[] BuildDispatchMap(NodeFactory factory) { ArrayBuilder<DispatchMapEntry> dispatchMapEntries = new ArrayBuilder<DispatchMapEntry>(); for (int i = 0; i < _type.RuntimeInterfaces.Length; i++) { var interfaceType = _type.RuntimeInterfaces[i]; Debug.Assert(interfaceType.IsInterface); List<MethodDesc> virtualSlots; factory.VirtualSlots.TryGetValue(interfaceType, out virtualSlots); if (virtualSlots != null) { for (int j = 0; j < virtualSlots.Count; j++) { MethodDesc declMethod = virtualSlots[j]; var implMethod = VirtualFunctionResolution.ResolveInterfaceMethodToVirtualMethodOnType(declMethod, _type.GetClosestMetadataType()); // Interface methods first implemented by a base type in the hierarchy will return null for the implMethod (runtime interface // dispatch will walk the inheritance chain). if (implMethod != null) { var entry = new DispatchMapEntry(); entry.InterfaceIndex = checked((short)i); entry.InterfaceMethodSlot = checked((short)j); entry.ImplementationMethodSlot = checked((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, implMethod)); dispatchMapEntries.Add(entry); } } } } return dispatchMapEntries.ToArray(); }
internal void CollectLocalsFromDeconstruction( ExpressionSyntax declaration, LocalDeclarationKind kind, ArrayBuilder<LocalSymbol> locals, SyntaxNode deconstructionStatement, Binder enclosingBinderOpt = null) { switch (declaration.Kind()) { case SyntaxKind.TupleExpression: { var tuple = (TupleExpressionSyntax)declaration; foreach (var arg in tuple.Arguments) { CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt); } break; } case SyntaxKind.DeclarationExpression: { var declarationExpression = (DeclarationExpressionSyntax)declaration; CollectLocalsFromDeconstruction( declarationExpression.Designation, declarationExpression.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); break; } case SyntaxKind.IdentifierName: break; default: // In broken code, we can have an arbitrary expression here. Collect its expression variables. ExpressionVariableFinder.FindExpressionVariables(this, locals, declaration); break; } }
/// <summary> /// There are two kinds of deconstruction-assignments which this binding handles: tuple and non-tuple. /// /// Returns a BoundDeconstructionAssignmentOperator with a list of deconstruction steps and assignment steps. /// Deconstruct steps for tuples have no invocation to Deconstruct, but steps for non-tuples do. /// The caller is responsible for releasing all the ArrayBuilders in checkedVariables. /// </summary> private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment( CSharpSyntaxNode node, ExpressionSyntax right, ArrayBuilder<DeconstructionVariable> checkedVariables, DiagnosticBag diagnostics, bool isDeclaration, BoundDeconstructValuePlaceholder rhsPlaceholder = null) { // receiver for first Deconstruct step var boundRHS = rhsPlaceholder ?? BindValue(right, diagnostics, BindValueKind.RValue); boundRHS = FixTupleLiteral(checkedVariables, boundRHS, node, diagnostics); if ((object)boundRHS.Type == null) { // we could still not infer a type for the RHS FailRemainingInferences(checkedVariables, diagnostics); return new BoundDeconstructionAssignmentOperator( node, isDeclaration, FlattenDeconstructVariables(checkedVariables), boundRHS, ImmutableArray<BoundDeconstructionDeconstructStep>.Empty, ImmutableArray<BoundDeconstructionAssignmentStep>.Empty, ImmutableArray<BoundDeconstructionAssignmentStep>.Empty, ImmutableArray<BoundDeconstructionConstructionStep>.Empty, GetSpecialType(SpecialType.System_Void, diagnostics, node), hasErrors: true); } var deconstructionSteps = ArrayBuilder<BoundDeconstructionDeconstructStep>.GetInstance(1); var conversionSteps = ArrayBuilder<BoundDeconstructionAssignmentStep>.GetInstance(1); var assignmentSteps = ArrayBuilder<BoundDeconstructionAssignmentStep>.GetInstance(1); var constructionStepsOpt = isDeclaration ? null : ArrayBuilder<BoundDeconstructionConstructionStep>.GetInstance(1); bool hasErrors = !DeconstructIntoSteps( new BoundDeconstructValuePlaceholder(boundRHS.Syntax, boundRHS.Type), node, diagnostics, checkedVariables, deconstructionSteps, conversionSteps, assignmentSteps, constructionStepsOpt); TypeSymbol returnType = isDeclaration ? GetSpecialType(SpecialType.System_Void, diagnostics, node) : hasErrors ? CreateErrorType() : constructionStepsOpt.Last().OutputPlaceholder.Type; var deconstructions = deconstructionSteps.ToImmutableAndFree(); var conversions = conversionSteps.ToImmutableAndFree(); var assignments = assignmentSteps.ToImmutableAndFree(); var constructions = isDeclaration ? default(ImmutableArray<BoundDeconstructionConstructionStep>) : constructionStepsOpt.ToImmutableAndFree(); FailRemainingInferences(checkedVariables, diagnostics); return new BoundDeconstructionAssignmentOperator( node, isDeclaration, FlattenDeconstructVariables(checkedVariables), boundRHS, deconstructions, conversions, assignments, constructions, returnType, hasErrors: hasErrors); }
private LookupResult(ObjectPool<LookupResult> pool) { _pool = pool; _kind = LookupResultKind.Empty; _symbolList = new ArrayBuilder<Symbol>(); _error = null; }
internal sealed override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder<SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(compilationState, ref attributes); var compilation = this.DeclaringCompilation; if (this.IsParams) { AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_ParamArrayAttribute__ctor)); } // Synthesize DecimalConstantAttribute if we don't have an explicit custom attribute already: var defaultValue = this.ExplicitDefaultConstantValue; if (defaultValue != ConstantValue.NotAvailable && defaultValue.SpecialType == SpecialType.System_Decimal && DefaultValueFromAttributes == ConstantValue.NotAvailable) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDecimalConstantAttribute(defaultValue.DecimalValue)); } if (this.Type.ContainsDynamic()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.Type, this.CustomModifiers.Length, this.RefKind)); } if (Type.ContainsTupleNames()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(Type)); } }
/// <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<FieldInitializers> initializers, ArrayBuilder<BoundInitializer> boundInitializers, DiagnosticBag diagnostics, bool generateDebugInfo, out ConsList<Imports> firstDebugImports) { firstDebugImports = null; foreach (FieldInitializers siblingInitializers in initializers) { var infos = ArrayBuilder<FieldInitializerInfo>.GetInstance(); // Exact size is not known up front. var locals = GetFieldInitializerInfos(compilation, siblingInitializers, infos, generateDebugInfo, ref firstDebugImports); ArrayBuilder<BoundInitializer> initializersBuilder = locals.IsDefaultOrEmpty ? boundInitializers : ArrayBuilder<BoundInitializer>.GetInstance(infos.Count); foreach (var info in infos) { BoundFieldInitializer boundInitializer = BindFieldInitializer(info.Binder, info.Initializer.Field, info.EqualsValue, diagnostics); initializersBuilder.Add(boundInitializer); } Debug.Assert(locals.IsDefaultOrEmpty == (initializersBuilder == boundInitializers)); if (!locals.IsDefaultOrEmpty) { boundInitializers.Add(new BoundInitializationScope((CSharpSyntaxNode)siblingInitializers.TypeDeclarationSyntax.GetSyntax(), locals, initializersBuilder.ToImmutableAndFree())); } infos.Free(); } }
public SourceAssemblySymbol( PhpCompilation compilation, string assemblySimpleName, string moduleName) { Debug.Assert(compilation != null); Debug.Assert(!String.IsNullOrWhiteSpace(assemblySimpleName)); Debug.Assert(!String.IsNullOrWhiteSpace(moduleName)); _compilation = compilation; _simpleName = assemblySimpleName; var moduleBuilder = new ArrayBuilder<ModuleSymbol>(1); moduleBuilder.Add(new SourceModuleSymbol(this, compilation.SourceSymbolTables, moduleName)); //var importOptions = (compilation.Options.MetadataImportOptions == MetadataImportOptions.All) ? // MetadataImportOptions.All : MetadataImportOptions.Internal; //foreach (PEModule netModule in netModules) //{ // moduleBuilder.Add(new PEModuleSymbol(this, netModule, importOptions, moduleBuilder.Count)); // // SetReferences will be called later by the ReferenceManager (in CreateSourceAssemblyFullBind for // // a fresh manager, in CreateSourceAssemblyReuseData for a reused one). //} _modules = moduleBuilder.ToImmutableAndFree(); }
// Virtual function related functionality public override MethodImplRecord[] FindMethodsImplWithMatchingDeclName(string declName) { MetadataReader metadataReader = _module.MetadataReader; var stringComparer = metadataReader.StringComparer; ArrayBuilder<MethodImplRecord> foundRecords = new ArrayBuilder<MethodImplRecord>(); foreach (var methodImplHandle in _typeDefinition.GetMethodImplementations()) { MethodImplementation methodImpl = metadataReader.GetMethodImplementation(methodImplHandle); EntityHandle methodDeclCheckHandle = methodImpl.MethodDeclaration; HandleKind methodDeclHandleKind = methodDeclCheckHandle.Kind; // We want to check that the method name matches before actually getting the MethodDesc. For MethodSpecifications // we need to dereference that handle to the underlying member reference to look at name matching. if (methodDeclHandleKind == HandleKind.MethodSpecification) { methodDeclCheckHandle = metadataReader.GetMethodSpecification((MethodSpecificationHandle)methodDeclCheckHandle).Method; methodDeclHandleKind = methodDeclCheckHandle.Kind; } bool foundRecord = false; switch (methodDeclHandleKind) { case HandleKind.MethodDefinition: if (stringComparer.Equals(metadataReader.GetMethodDefinition((MethodDefinitionHandle)methodDeclCheckHandle).Name, declName)) { foundRecord = true; } break; case HandleKind.MemberReference: if (stringComparer.Equals(metadataReader.GetMemberReference((MemberReferenceHandle)methodDeclCheckHandle).Name, declName)) { foundRecord = true; } break; default: Debug.Assert(false, "unexpected methodDeclHandleKind"); break; } if (foundRecord) { MethodImplRecord newRecord = new MethodImplRecord(); newRecord.Decl = (MethodDesc)_module.GetObject(methodImpl.MethodDeclaration); newRecord.Body = (MethodDesc)_module.GetObject(methodImpl.MethodBody); foundRecords.Add(newRecord); } } if (foundRecords.Count != 0) return foundRecords.ToArray(); return null; }
private BoundExpression VisitInitializer(BoundExpression node, out InitializerKind kind) { switch (node.Kind) { case BoundKind.ObjectInitializerExpression: { var oi = (BoundObjectInitializerExpression)node; var builder = ArrayBuilder <BoundExpression> .GetInstance(); foreach (BoundAssignmentOperator a in oi.Initializers) { var sym = ((BoundObjectInitializerMember)a.Left).MemberSymbol; // An error is reported in diagnostics pass when a dynamic object initializer is encountered in an ET: Debug.Assert((object)sym != null); InitializerKind elementKind; var value = VisitInitializer(a.Right, out elementKind); switch (elementKind) { case InitializerKind.CollectionInitializer: { var left = InitializerMemberGetter(sym); builder.Add(ExprFactory("ListBind", left, value)); break; } case InitializerKind.Expression: { var left = InitializerMemberSetter(sym); builder.Add(ExprFactory("Bind", left, value)); break; } case InitializerKind.MemberInitializer: { var left = InitializerMemberGetter(sym); builder.Add(ExprFactory("MemberBind", left, value)); break; } default: throw ExceptionUtilities.UnexpectedValue(elementKind); } } kind = InitializerKind.MemberInitializer; return(_bound.Array(MemberBindingType, builder.ToImmutableAndFree())); } case BoundKind.CollectionInitializerExpression: { var ci = (BoundCollectionInitializerExpression)node; Debug.Assert(ci.Initializers.Length != 0); kind = InitializerKind.CollectionInitializer; var builder = ArrayBuilder <BoundExpression> .GetInstance(); // The method invocation must be a static call. // Dynamic calls are not allowed in ETs, an error is reported in diagnostics pass. foreach (BoundCollectionElementInitializer i in ci.Initializers) { BoundExpression elementInit = ExprFactory("ElementInit", _bound.MethodInfo(i.AddMethod), Expressions(i.Arguments)); builder.Add(elementInit); } return(_bound.Array(ElementInitType, builder.ToImmutableAndFree())); } default: { kind = InitializerKind.Expression; return(Visit(node)); } } }
// Returns true if there were any applicable candidates. private bool CandidateOperators(ArrayBuilder <UnaryOperatorSignature> operators, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { bool anyApplicable = false; foreach (var op in operators) { var conversion = Conversions.ClassifyConversionFromExpression(operand, op.OperandType, ref useSiteDiagnostics); if (conversion.IsImplicit) { anyApplicable = true; results.Add(UnaryOperatorAnalysisResult.Applicable(op, conversion)); } else { results.Add(UnaryOperatorAnalysisResult.Inapplicable(op, conversion)); } } return(anyApplicable); }
private void GetAllBuiltInOperators(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { // The spec states that overload resolution is performed upon the infinite set of // operators defined on enumerated types, pointers and delegates. Clearly we cannot // construct the infinite set; we have to pare it down. Previous implementations of C# // implement a much stricter rule; they only add the special operators to the candidate // set if one of the operands is of the relevant type. This means that operands // involving user-defined implicit conversions from class or struct types to enum, // pointer and delegate types do not cause the right candidates to participate in // overload resolution. It also presents numerous problems involving delegate variance // and conversions from lambdas to delegate types. // // It is onerous to require the actually specified behavior. We should change the // specification to match the previous implementation. var operators = ArrayBuilder <UnaryOperatorSignature> .GetInstance(); this.Compilation.builtInOperators.GetSimpleBuiltInOperators(kind, operators); GetEnumOperations(kind, operand, operators); var pointerOperator = GetPointerOperation(kind, operand); if (pointerOperator != null) { operators.Add(pointerOperator.Value); } CandidateOperators(operators, operand, results, ref useSiteDiagnostics); operators.Free(); }
// Returns true if there were any applicable candidates. private bool GetUserDefinedOperators(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(operand != null); if ((object)operand.Type == null) { // If the operand has no type -- because it is a null reference or a lambda or a method group -- // there is no way we can determine what type to search for user-defined operators. return(false); } // Spec 7.3.5 Candidate user-defined operators // SPEC: Given a type T and an operation op(A) ... the set of candidate user-defined // SPEC: operators provided by T for op(A) is determined as follows: // SPEC: If T is a nullable type then T0 is its underlying type; otherwise T0 is T. // SPEC: For all operator declarations in T0 and all lifted forms of such operators, if // SPEC: at least one operator is applicable with respect to A then the set of candidate // SPEC: operators consists of all such applicable operators. Otherwise, if T0 is object // SPEC: then the set of candidate operators is empty. Otherwise, the set of candidate // SPEC: operators is the set provided by the direct base class of T0, or the effective // SPEC: base class of T0 if T0 is a type parameter. TypeSymbol type0 = operand.Type.StrippedType(); // Searching for user-defined operators is expensive; let's take an early out if we can. if (OperatorFacts.DefinitelyHasNoUserDefinedOperators(type0)) { return(false); } string name = OperatorFacts.UnaryOperatorNameFromOperatorKind(kind); var operators = ArrayBuilder <UnaryOperatorSignature> .GetInstance(); bool hadApplicableCandidates = false; NamedTypeSymbol current = type0 as NamedTypeSymbol; if ((object)current == null) { current = type0.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics); } if ((object)current == null && type0.IsTypeParameter()) { current = ((TypeParameterSymbol)type0).EffectiveBaseClass(ref useSiteDiagnostics); } for (; (object)current != null; current = current.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics)) { operators.Clear(); GetUserDefinedUnaryOperatorsFromType(current, kind, name, operators); results.Clear(); if (CandidateOperators(operators, operand, results, ref useSiteDiagnostics)) { hadApplicableCandidates = true; break; } } operators.Free(); return(hadApplicableCandidates); }
private void GetEnumOperations(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorSignature> operators) { Debug.Assert(operand != null); var enumType = operand.Type; if ((object)enumType == null) { return; } enumType = enumType.StrippedType(); if (!enumType.IsValidEnumType()) { return; } var nullableEnum = MakeNullable(enumType); switch (kind) { case UnaryOperatorKind.PostfixIncrement: case UnaryOperatorKind.PostfixDecrement: case UnaryOperatorKind.PrefixIncrement: case UnaryOperatorKind.PrefixDecrement: case UnaryOperatorKind.BitwiseComplement: operators.Add(new UnaryOperatorSignature(kind | UnaryOperatorKind.Enum, enumType, enumType)); operators.Add(new UnaryOperatorSignature(kind | UnaryOperatorKind.Lifted | UnaryOperatorKind.Enum, nullableEnum, nullableEnum)); break; } }
public override BoundNode VisitCatchBlock(BoundCatchBlock node) { if (!_analysis.CatchContainsAwait(node)) { var origCurrentAwaitCatchFrame = _currentAwaitCatchFrame; _currentAwaitCatchFrame = null; var result = base.VisitCatchBlock(node); _currentAwaitCatchFrame = origCurrentAwaitCatchFrame; return(result); } var currentAwaitCatchFrame = _currentAwaitCatchFrame; if (currentAwaitCatchFrame == null) { Debug.Assert(node.Syntax.IsKind(SyntaxKind.CatchClause)); var tryStatementSyntax = (TryStatementSyntax)node.Syntax.Parent; currentAwaitCatchFrame = _currentAwaitCatchFrame = new AwaitCatchFrame(_F, tryStatementSyntax); } var catchType = node.ExceptionTypeOpt ?? _F.SpecialType(SpecialType.System_Object); var catchTemp = _F.SynthesizedLocal(catchType); var storePending = _F.AssignmentExpression( _F.Local(currentAwaitCatchFrame.pendingCaughtException), _F.Convert(currentAwaitCatchFrame.pendingCaughtException.Type, _F.Local(catchTemp))); var setPendingCatchNum = _F.Assignment( _F.Local(currentAwaitCatchFrame.pendingCatch), _F.Literal(currentAwaitCatchFrame.handlers.Count + 1)); // catch (ExType exTemp) // { // pendingCaughtException = exTemp; // catchNo = X; // } BoundCatchBlock catchAndPend; ImmutableArray <LocalSymbol> handlerLocals; var filterPrologueOpt = node.ExceptionFilterPrologueOpt; var filterOpt = node.ExceptionFilterOpt; if (filterOpt == null) { Debug.Assert(filterPrologueOpt is null); // store pending exception // as the first statement in a catch catchAndPend = node.Update( ImmutableArray.Create(catchTemp), _F.Local(catchTemp), catchType, exceptionFilterPrologueOpt: filterPrologueOpt, exceptionFilterOpt: null, body: _F.Block( _F.HiddenSequencePoint(), _F.ExpressionStatement(storePending), setPendingCatchNum), isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll); // catch locals live on the synthetic catch handler block handlerLocals = node.Locals; } else { handlerLocals = ImmutableArray <LocalSymbol> .Empty; // catch locals move up into hoisted locals // since we might need to access them from both the filter and the catch foreach (var local in node.Locals) { currentAwaitCatchFrame.HoistLocal(local, _F); } // store pending exception // as the first expression in a filter var sourceOpt = node.ExceptionSourceOpt; var rewrittenPrologue = (BoundStatementList)this.Visit(filterPrologueOpt); var rewrittenFilter = (BoundExpression)this.Visit(filterOpt); var newFilter = sourceOpt == null? _F.MakeSequence( storePending, rewrittenFilter) : _F.MakeSequence( storePending, AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame), rewrittenFilter); catchAndPend = node.Update( ImmutableArray.Create(catchTemp), _F.Local(catchTemp), catchType, exceptionFilterPrologueOpt: rewrittenPrologue, exceptionFilterOpt: newFilter, body: _F.Block( _F.HiddenSequencePoint(), setPendingCatchNum), isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll); } var handlerStatements = ArrayBuilder <BoundStatement> .GetInstance(); handlerStatements.Add(_F.HiddenSequencePoint()); if (filterOpt == null) { var sourceOpt = node.ExceptionSourceOpt; if (sourceOpt != null) { BoundExpression assignSource = AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame); handlerStatements.Add(_F.ExpressionStatement(assignSource)); } } handlerStatements.Add((BoundStatement)this.Visit(node.Body)); var handler = _F.Block( handlerLocals, handlerStatements.ToImmutableAndFree() ); currentAwaitCatchFrame.handlers.Add(handler); return(catchAndPend); }
/// <summary> /// Populates a list of unary operator results with those from any /// witness in scope at the operator site. /// </summary> /// <param name="kind"> /// The unary operator kind of the expression. /// </param> /// <param name="operand"> /// The operand expression. /// </param> /// <param name="results"> /// The results list to populate. /// </param> /// <param name="useSiteDiagnostics"> /// The set of diagnostics to populate with any errors. /// </param> /// <returns> /// True if we managed to find candidate operators from the concept /// witnesses in scope; false otherwise. /// </returns> private bool GetUnaryWitnessOperators(UnaryOperatorKind kind, BoundExpression operand, ArrayBuilder <UnaryOperatorAnalysisResult> results, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(operand != null); string name = OperatorFacts.UnaryOperatorNameFromOperatorKind(kind); var operators = ArrayBuilder <UnaryOperatorSignature> .GetInstance(); foreach (var method in GetWitnessOperators(name, 1, ref useSiteDiagnostics)) { // TODO: nullability operators.Add(new UnaryOperatorSignature(UnaryOperatorKind.UserDefined | kind, method.ParameterTypes[0], method.ReturnType, method)); } bool hasCandidates = CandidateOperators(operators, operand, results, ref useSiteDiagnostics); operators.Free(); return(hasCandidates); }
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); AddSynthesizedAttribute(ref attributes, this.DeclaringCompilation.TrySynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); }
public override BoundNode VisitTryStatement(BoundTryStatement node) { // if node contains no yields, do regular rewrite in the current frame. if (!ContainsYields(node)) { _tryNestingLevel++; var result = node.Update( (BoundBlock)Visit(node.TryBlock), VisitList(node.CatchBlocks), (BoundBlock)Visit(node.FinallyBlockOpt), node.PreferFaultHandler); _tryNestingLevel--; return(result); } Debug.Assert(node.CatchBlocks.IsEmpty, "try with yields must have no catches"); Debug.Assert(node.FinallyBlockOpt != null, "try with yields must have finally"); // rewrite TryBlock in a new frame. var frame = PushFrame(node); _tryNestingLevel++; var rewrittenBody = (BoundStatement)this.Visit(node.TryBlock); Debug.Assert(!frame.IsRoot()); Debug.Assert(frame.parent.knownStates.ContainsValue(frame), "parent must be aware about states in the child frame"); var finallyMethod = frame.handler; var origMethod = F.CurrentFunction; // rewrite finally block into a Finally method. F.CurrentFunction = finallyMethod; var rewrittenHandler = (BoundStatement)this.Visit(node.FinallyBlockOpt); _tryNestingLevel--; PopFrame(); // { // this.state = parentFinalizeState; // body; // return; // } Debug.Assert(frame.parent.finalizeState == _currentFinallyFrame.finalizeState); rewrittenHandler = F.Block((object)this.cachedThis != null ? ImmutableArray.Create(this.cachedThis) : ImmutableArray <LocalSymbol> .Empty, F.Assignment(F.Field(F.This(), stateField), F.Literal(frame.parent.finalizeState)), CacheThisIfNeeded(), rewrittenHandler, F.Return() ); F.CloseMethod(rewrittenHandler); F.CurrentFunction = origMethod; var bodyStatements = ArrayBuilder <BoundStatement> .GetInstance(); // add a call to the handler after the try body. // // { // this.state = finalizeState; // body; // this.Finally(); // will reset the state to the finally state of the parent. // } bodyStatements.Add(F.Assignment(F.Field(F.This(), stateField), F.Literal(frame.finalizeState))); bodyStatements.Add(rewrittenBody); bodyStatements.Add(F.ExpressionStatement(F.Call(F.This(), finallyMethod))); // handle proxy labels if have any if (frame.proxyLabels != null) { var dropThrough = F.GenerateLabel("dropThrough"); bodyStatements.Add(F.Goto(dropThrough)); var parent = frame.parent; foreach (var p in frame.proxyLabels) { var proxy = p.Value; var destination = p.Key; // branch lands here bodyStatements.Add(F.Label(proxy)); // finalize current state, proceed to destination. bodyStatements.Add(F.ExpressionStatement(F.Call(F.This(), finallyMethod))); // let the parent forward the branch appropriately var parentProxy = parent.ProxyLabelIfNeeded(destination); bodyStatements.Add(F.Goto(parentProxy)); } bodyStatements.Add(F.Label(dropThrough)); } return(F.Block(bodyStatements.ToImmutableAndFree())); }
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData>?attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); var compilation = this.DeclaringCompilation; var type = this.TypeWithAnnotations; if (type.Type.ContainsDynamic()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length)); } if (type.Type.ContainsTupleNames()) { AddSynthesizedAttribute(ref attributes, DeclaringCompilation.SynthesizeTupleNamesAttribute(type.Type)); } if (compilation.ShouldEmitNullableAttributes(this)) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttributeIfNecessary(this, containingType.GetNullableContextValue(), type)); } }
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { // Emit [Dynamic] on synthesized parameter symbols when the original parameter was dynamic // in order to facilitate debugging. In the case the necessary attributes are missing // this is a no-op. Emitting an error here, or when the original parameter was bound, would // adversely effect the compilation or potentially change overload resolution. var compilation = this.DeclaringCompilation; var type = this.TypeWithAnnotations; if (type.Type.ContainsDynamic() && compilation.HasDynamicEmitAttributes(BindingDiagnosticBag.Discarded, Location.None) && compilation.CanEmitBoolean()) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.Type, type.CustomModifiers.Length + this.RefCustomModifiers.Length, this.RefKind)); } if (type.Type.ContainsNativeInteger()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNativeIntegerAttribute(this, type.Type)); } if (type.Type.ContainsTupleNames() && compilation.HasTupleNamesAttributes(BindingDiagnosticBag.Discarded, Location.None) && compilation.CanEmitSpecialType(SpecialType.System_String)) { AddSynthesizedAttribute(ref attributes, compilation.SynthesizeTupleNamesAttribute(type.Type)); } if (compilation.ShouldEmitNullableAttributes(this)) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttributeIfNecessary(this, GetNullableContextValue(), type)); } if (this.RefKind == RefKind.RefReadOnly) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsReadOnlyAttribute(this)); } }
private BoundExpression HoistExpression( BoundExpression expr, AwaitExpressionSyntax awaitSyntaxOpt, int syntaxOffset, RefKind refKind, ArrayBuilder <BoundExpression> sideEffects, ArrayBuilder <StateMachineFieldSymbol> hoistedFields, ref bool needsSacrificialEvaluation) { switch (expr.Kind) { case BoundKind.ArrayAccess: { var array = (BoundArrayAccess)expr; BoundExpression expression = HoistExpression(array.Expression, awaitSyntaxOpt, syntaxOffset, RefKind.None, sideEffects, hoistedFields, ref needsSacrificialEvaluation); var indices = ArrayBuilder <BoundExpression> .GetInstance(); foreach (var index in array.Indices) { indices.Add(HoistExpression(index, awaitSyntaxOpt, syntaxOffset, RefKind.None, sideEffects, hoistedFields, ref needsSacrificialEvaluation)); } needsSacrificialEvaluation = true; // need to force array index out of bounds exceptions return(array.Update(expression, indices.ToImmutableAndFree(), array.Type)); } case BoundKind.FieldAccess: { var field = (BoundFieldAccess)expr; if (field.FieldSymbol.IsStatic) { // the address of a static field, and the value of a readonly static field, is stable if (refKind != RefKind.None || field.FieldSymbol.IsLet) { return(expr); } goto default; } if (refKind == RefKind.None) { goto default; } var isFieldOfStruct = !field.FieldSymbol.ContainingType.IsReferenceType; var receiver = HoistExpression(field.ReceiverOpt, awaitSyntaxOpt, syntaxOffset, isFieldOfStruct ? refKind : RefKind.None, sideEffects, hoistedFields, ref needsSacrificialEvaluation); if (receiver.Kind != BoundKind.ThisReference && !isFieldOfStruct) { needsSacrificialEvaluation = true; // need the null check in field receiver } return(F.Field(receiver, field.FieldSymbol)); } case BoundKind.ThisReference: case BoundKind.BaseReference: case BoundKind.DefaultExpression: return(expr); case BoundKind.Call: var call = (BoundCall)expr; // NOTE: There are two kinds of 'In' arguments that we may see at this point: // - `RefKindExtensions.StrictIn` (originally specified with 'In' modifier) // - `RefKind.In` (specified with no modifiers and matched an 'In' parameter) // // It is allowed to spill ordinary `In` arguments by value if reference-preserving spilling is not possible. // The "strict" ones do not permit implicit copying, so the same situation should result in an error. if (refKind != RefKind.None && refKind != RefKind.In) { Debug.Assert(call.Method.RefKind != RefKind.None); F.Diagnostics.Add(ErrorCode.ERR_RefReturningCallAndAwait, F.Syntax.Location, call.Method); } // method call is not referentially transparent, we can only spill the result value. refKind = RefKind.None; goto default; case BoundKind.ConditionalOperator: var conditional = (BoundConditionalOperator)expr; // NOTE: There are two kinds of 'In' arguments that we may see at this point: // - `RefKindExtensions.StrictIn` (originally specified with 'In' modifier) // - `RefKind.In` (specified with no modifiers and matched an 'In' parameter) // // It is allowed to spill ordinary `In` arguments by value if reference-preserving spilling is not possible. // The "strict" ones do not permit implicit copying, so the same situation should result in an error. if (refKind != RefKind.None && refKind != RefKind.RefReadOnly) { Debug.Assert(conditional.IsRef); F.Diagnostics.Add(ErrorCode.ERR_RefConditionalAndAwait, F.Syntax.Location); } // conditional expr is not referentially transparent, we can only spill the result value. refKind = RefKind.None; goto default; default: if (expr.ConstantValue != null) { return(expr); } if (refKind != RefKind.None) { throw ExceptionUtilities.UnexpectedValue(expr.Kind); } TypeSymbol fieldType = expr.Type; StateMachineFieldSymbol hoistedField; if (F.Compilation.Options.OptimizationLevel == OptimizationLevel.Debug) { const SynthesizedLocalKind kind = SynthesizedLocalKind.AwaitByRefSpill; Debug.Assert(awaitSyntaxOpt != null); int ordinal = _synthesizedLocalOrdinals.AssignLocalOrdinal(kind, syntaxOffset); var id = new LocalDebugId(syntaxOffset, ordinal); // Editing await expression is not allowed. Thus all spilled fields will be present in the previous state machine. // However, it may happen that the type changes, in which case we need to allocate a new slot. int slotIndex; if (slotAllocatorOpt == null || !slotAllocatorOpt.TryGetPreviousHoistedLocalSlotIndex( awaitSyntaxOpt, F.ModuleBuilderOpt.Translate(fieldType, awaitSyntaxOpt, Diagnostics), kind, id, Diagnostics, out slotIndex)) { slotIndex = _nextFreeHoistedLocalSlot++; } string fieldName = GeneratedNames.MakeHoistedLocalFieldName(kind, slotIndex); hoistedField = F.StateMachineField(expr.Type, fieldName, new LocalSlotDebugInfo(kind, id), slotIndex); } else { hoistedField = GetOrAllocateReusableHoistedField(fieldType, reused: out _); } hoistedFields.Add(hoistedField); var replacement = F.Field(F.This(), hoistedField); sideEffects.Add(F.AssignmentExpression(replacement, expr)); return(replacement); } }
/// <summary> /// Translate a statement that declares a given set of locals. Also allocates and frees hoisted temps as /// required for the translation. /// </summary> /// <param name="locals">The set of locals declared in the original version of this statement</param> /// <param name="wrapped">A delegate to return the translation of the body of this statement</param> private BoundStatement PossibleIteratorScope(ImmutableArray <LocalSymbol> locals, Func <BoundStatement> wrapped) { if (locals.IsDefaultOrEmpty) { return(wrapped()); } var hoistedLocalsWithDebugScopes = ArrayBuilder <StateMachineFieldSymbol> .GetInstance(); foreach (var local in locals) { if (!NeedsProxy(local)) { continue; } // Ref synthesized variables have proxies that are allocated in VisitAssignmentOperator. if (local.RefKind != RefKind.None) { Debug.Assert(local.SynthesizedKind == SynthesizedLocalKind.Spill); continue; } Debug.Assert(local.SynthesizedKind.IsLongLived()); CapturedSymbolReplacement proxy; bool reused = false; if (!proxies.TryGetValue(local, out proxy)) { proxy = new CapturedToStateMachineFieldReplacement(GetOrAllocateReusableHoistedField(TypeMap.SubstituteType(local.Type.TypeSymbol).TypeSymbol, out reused, local), isReusable: true); proxies.Add(local, proxy); } // We need to produce hoisted local scope debug information for user locals as well as // lambda display classes, since Dev12 EE uses them to determine which variables are displayed // in Locals window. if ((local.SynthesizedKind == SynthesizedLocalKind.UserDefined && local.ScopeDesignatorOpt?.Kind() != SyntaxKind.SwitchSection) || local.SynthesizedKind == SynthesizedLocalKind.LambdaDisplayClass) { // NB: This is the case when the local backed by recycled field will not be visible in debugger. // It may be possible in the future, but for now a backing field can be mapped only to a single local. if (!reused) { hoistedLocalsWithDebugScopes.Add(((CapturedToStateMachineFieldReplacement)proxy).HoistedField); } } } var translatedStatement = wrapped(); var variableCleanup = ArrayBuilder <BoundAssignmentOperator> .GetInstance(); // produce cleanup code for all fields of locals defined by this block // as well as all proxies allocated by VisitAssignmentOperator within this block: foreach (var local in locals) { CapturedSymbolReplacement proxy; if (!proxies.TryGetValue(local, out proxy)) { continue; } var simpleProxy = proxy as CapturedToStateMachineFieldReplacement; if (simpleProxy != null) { AddVariableCleanup(variableCleanup, simpleProxy.HoistedField); if (proxy.IsReusable) { FreeReusableHoistedField(simpleProxy.HoistedField); } } else { foreach (var field in ((CapturedToExpressionSymbolReplacement)proxy).HoistedFields) { AddVariableCleanup(variableCleanup, field); if (proxy.IsReusable) { FreeReusableHoistedField(field); } } } } if (variableCleanup.Count != 0) { translatedStatement = F.Block( translatedStatement, F.Block(variableCleanup.SelectAsArray((e, f) => (BoundStatement)f.ExpressionStatement(e), F))); } variableCleanup.Free(); // wrap the node in an iterator scope for debugging if (hoistedLocalsWithDebugScopes.Count != 0) { translatedStatement = MakeStateMachineScope(hoistedLocalsWithDebugScopes.ToImmutable(), translatedStatement); } hoistedLocalsWithDebugScopes.Free(); return(translatedStatement); }
public override BoundNode VisitTryStatement(BoundTryStatement node) { var tryStatementSyntax = node.Syntax; // If you add a syntax kind to the assertion below, please also ensure // that the scenario has been tested with Edit-and-Continue. Debug.Assert( tryStatementSyntax.IsKind(SyntaxKind.TryStatement) || tryStatementSyntax.IsKind(SyntaxKind.UsingStatement) || tryStatementSyntax.IsKind(SyntaxKind.ForEachStatement) || tryStatementSyntax.IsKind(SyntaxKind.ForEachVariableStatement) || tryStatementSyntax.IsKind(SyntaxKind.LocalDeclarationStatement)); BoundStatement finalizedRegion; BoundBlock rewrittenFinally; var finallyContainsAwaits = _analysis.FinallyContainsAwaits(node); if (!finallyContainsAwaits) { finalizedRegion = RewriteFinalizedRegion(node); rewrittenFinally = (BoundBlock)this.Visit(node.FinallyBlockOpt); if (rewrittenFinally == null) { return(finalizedRegion); } var asTry = finalizedRegion as BoundTryStatement; if (asTry != null) { // since finalized region is a try we can just attach finally to it Debug.Assert(asTry.FinallyBlockOpt == null); return(asTry.Update(asTry.TryBlock, asTry.CatchBlocks, rewrittenFinally, asTry.FinallyLabelOpt, asTry.PreferFaultHandler)); } else { // wrap finalizedRegion into a Try with a finally. return(_F.Try((BoundBlock)finalizedRegion, ImmutableArray <BoundCatchBlock> .Empty, rewrittenFinally)); } } // rewrite finalized region (try and catches) in the current frame var frame = PushFrame(node); finalizedRegion = RewriteFinalizedRegion(node); rewrittenFinally = (BoundBlock)this.VisitBlock(node.FinallyBlockOpt); PopFrame(); var exceptionType = _F.SpecialType(SpecialType.System_Object); var pendingExceptionLocal = new SynthesizedLocal(_F.CurrentFunction, TypeWithAnnotations.Create(exceptionType), SynthesizedLocalKind.TryAwaitPendingException, tryStatementSyntax); var finallyLabel = _F.GenerateLabel("finallyLabel"); var pendingBranchVar = new SynthesizedLocal(_F.CurrentFunction, TypeWithAnnotations.Create(_F.SpecialType(SpecialType.System_Int32)), SynthesizedLocalKind.TryAwaitPendingBranch, tryStatementSyntax); var catchAll = _F.Catch(_F.Local(pendingExceptionLocal), _F.Block()); var catchAndPendException = _F.Try( _F.Block( finalizedRegion, _F.HiddenSequencePoint(), _F.Goto(finallyLabel), PendBranches(frame, pendingBranchVar, finallyLabel)), ImmutableArray.Create(catchAll), finallyLabel: finallyLabel); BoundBlock syntheticFinallyBlock = _F.Block( _F.HiddenSequencePoint(), _F.Label(finallyLabel), rewrittenFinally, _F.HiddenSequencePoint(), UnpendException(pendingExceptionLocal), UnpendBranches( frame, pendingBranchVar, pendingExceptionLocal)); BoundStatement syntheticFinally = syntheticFinallyBlock; if (_F.CurrentFunction.IsAsync && _F.CurrentFunction.IsIterator) { // We wrap this block so that it can be processed as a finally block by async-iterator rewriting syntheticFinally = _F.ExtractedFinallyBlock(syntheticFinallyBlock); } var locals = ArrayBuilder <LocalSymbol> .GetInstance(); var statements = ArrayBuilder <BoundStatement> .GetInstance(); statements.Add(_F.HiddenSequencePoint()); locals.Add(pendingExceptionLocal); statements.Add(_F.Assignment(_F.Local(pendingExceptionLocal), _F.Default(pendingExceptionLocal.Type))); locals.Add(pendingBranchVar); statements.Add(_F.Assignment(_F.Local(pendingBranchVar), _F.Default(pendingBranchVar.Type))); LocalSymbol returnLocal = frame.returnValue; if (returnLocal != null) { locals.Add(returnLocal); } statements.Add(catchAndPendException); statements.Add(syntheticFinally); var completeTry = _F.Block( locals.ToImmutableAndFree(), statements.ToImmutableAndFree()); return(completeTry); }
/// <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);
public override void AddPreviousLocals(ArrayBuilder <Cci.ILocalDefinition> builder) { builder.AddRange(_locals); }
private BoundStatement UnpendBranches( AwaitFinallyFrame frame, SynthesizedLocal pendingBranchVar, SynthesizedLocal pendingException) { var parent = frame.ParentOpt; // handle proxy labels if have any var proxiedLabels = frame.proxiedLabels; // skip 0 - it means we took no explicit branches int i = 1; var cases = ArrayBuilder <SyntheticBoundNodeFactory.SyntheticSwitchSection> .GetInstance(); if (proxiedLabels != null) { for (int cnt = proxiedLabels.Count; i <= cnt; i++) { var target = proxiedLabels[i - 1]; var parentProxy = parent.ProxyLabelIfNeeded(target); var caseStatement = _F.SwitchSection(i, _F.Goto(parentProxy)); cases.Add(caseStatement); } } if (frame.returnProxyLabel != null) { BoundLocal pendingValue = null; if (frame.returnValue != null) { pendingValue = _F.Local(frame.returnValue); } SynthesizedLocal returnValue; BoundStatement unpendReturn; var returnLabel = parent.ProxyReturnIfNeeded(_F.CurrentFunction, pendingValue, out returnValue); if (returnLabel == null) { unpendReturn = new BoundReturnStatement(_F.Syntax, RefKind.None, pendingValue); } else { if (pendingValue == null) { unpendReturn = _F.Goto(returnLabel); } else { unpendReturn = _F.Block( _F.Assignment( _F.Local(returnValue), pendingValue), _F.Goto(returnLabel)); } } var caseStatement = _F.SwitchSection(i, unpendReturn); cases.Add(caseStatement); } return(_F.Switch(_F.Local(pendingBranchVar), cases.ToImmutableAndFree())); }
private void OnSymbolEnd(SymbolAnalysisContext symbolEndContext, bool hasUnsupportedOperation) { if (hasUnsupportedOperation) { return; } if (symbolEndContext.Symbol.GetAttributes().Any(a => a.AttributeClass == _structLayoutAttributeType)) { // Bail out for types with 'StructLayoutAttribute' as the ordering of the members is critical, // and removal of unused members might break semantics. return; } // Report diagnostics for unused candidate members. var first = true; PooledHashSet <ISymbol> symbolsReferencedInDocComments = null; ArrayBuilder <string> debuggerDisplayAttributeArguments = null; try { var entryPoint = symbolEndContext.Compilation.GetEntryPoint(symbolEndContext.CancellationToken); var namedType = (INamedTypeSymbol)symbolEndContext.Symbol; foreach (var member in namedType.GetMembers()) { if (SymbolEqualityComparer.Default.Equals(entryPoint, member)) { continue; } // Check if the underlying member is neither read nor a readable reference to the member is taken. // If so, we flag the member as either unused (never written) or unread (written but not read). if (TryRemove(member, out var valueUsageInfo) && !valueUsageInfo.IsReadFrom()) { Debug.Assert(IsCandidateSymbol(member)); Debug.Assert(!member.IsImplicitlyDeclared); if (first) { // Bail out if there are syntax errors in any of the declarations of the containing type. // Note that we check this only for the first time that we report an unused or unread member for the containing type. if (HasSyntaxErrors(namedType, symbolEndContext.CancellationToken)) { return; } // Compute the set of candidate symbols referenced in all the documentation comments within the named type declarations. // This set is computed once and used for all the iterations of the loop. symbolsReferencedInDocComments = GetCandidateSymbolsReferencedInDocComments(namedType, symbolEndContext.Compilation, symbolEndContext.CancellationToken); // Compute the set of string arguments to DebuggerDisplay attributes applied to any symbol within the named type declaration. // These strings may have an embedded reference to the symbol. // This set is computed once and used for all the iterations of the loop. debuggerDisplayAttributeArguments = GetDebuggerDisplayAttributeArguments(namedType); first = false; } // Simple heuristic for members referenced in DebuggerDisplayAttribute's string argument: // bail out if any of the DebuggerDisplay string arguments contains the member name. // In future, we can consider improving this heuristic to parse the embedded expression // and resolve symbol references. if (debuggerDisplayAttributeArguments.Any(arg => arg.Contains(member.Name))) { continue; } // Report IDE0051 or IDE0052 based on whether the underlying member has any Write/WritableRef/NonReadWriteRef references or not. var rule = !valueUsageInfo.IsWrittenTo() && !valueUsageInfo.IsNameOnly() && !symbolsReferencedInDocComments.Contains(member) ? s_removeUnusedMembersRule : s_removeUnreadMembersRule; // Do not flag write-only properties that are not read. // Write-only properties are assumed to have side effects // visible through other means than a property getter. if (rule == s_removeUnreadMembersRule && member is IPropertySymbol property && property.IsWriteOnly) { continue; } // Most of the members should have a single location, except for partial methods. // We report the diagnostic on the first location of the member. var diagnostic = DiagnosticHelper.CreateWithMessage( rule, member.Locations[0], rule.GetEffectiveSeverity(symbolEndContext.Compilation.Options), additionalLocations: null, properties: null, GetMessage(rule, member)); symbolEndContext.ReportDiagnostic(diagnostic); } } } finally { symbolsReferencedInDocComments?.Free(); debuggerDisplayAttributeArguments?.Free(); } return; }
internal static bool TryGetTupleFieldValues(this DkmClrValue tuple, int cardinality, ArrayBuilder <string> values, DkmInspectionContext inspectionContext) { while (true) { var type = tuple.Type.GetLmrType(); int n = Math.Min(cardinality, TupleFieldRestPosition - 1); for (int index = 0; index < n; index++) { var fieldName = GetTupleFieldName(index); var fieldInfo = type.GetTupleField(fieldName); if (fieldInfo == null) { return(false); } var value = tuple.GetFieldValue(fieldName, inspectionContext); var str = value.GetValueString(inspectionContext, Formatter.NoFormatSpecifiers); values.Add(str); } cardinality -= n; if (cardinality == 0) { return(true); } var restInfo = type.GetTupleField(TypeHelpers.TupleFieldRestName); if (restInfo == null) { return(false); } tuple = tuple.GetFieldValue(TupleFieldRestName, inspectionContext); } }
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); var type = this.Type; if (type.TypeSymbol.ContainsDynamic()) { var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(type.TypeSymbol, type.CustomModifiers.Length)); } if (type.TypeSymbol.ContainsTupleNames()) { AddSynthesizedAttribute(ref attributes, DeclaringCompilation.SynthesizeTupleNamesAttribute(type.TypeSymbol)); } AddSynthesizedNonNullTypesAttributeForMember(ref attributes); if (type.ContainsNullableReferenceTypes()) { AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeNullableAttribute(this, type)); } }
internal static void AppendTypeMembers( this Type type, ArrayBuilder <MemberAndDeclarationInfo> includedMembers, Predicate <MemberInfo> predicate, Type declaredType, DkmClrAppDomain appDomain, bool includeInherited, bool hideNonPublic) { Debug.Assert(!type.IsInterface); var memberLocation = DeclarationInfo.FromSubTypeOfDeclaredType; var previousDeclarationMap = includeInherited ? new Dictionary <string, DeclarationInfo>() : null; int inheritanceLevel = 0; while (!type.IsObject()) { if (type.Equals(declaredType)) { Debug.Assert(memberLocation == DeclarationInfo.FromSubTypeOfDeclaredType); memberLocation = DeclarationInfo.FromDeclaredTypeOrBase; } // Get the state from DebuggerBrowsableAttributes for the members of the current type. var browsableState = DkmClrType.Create(appDomain, type).GetDebuggerBrowsableAttributeState(); // Hide non-public members if hideNonPublic is specified (intended to reflect the // DkmInspectionContext's DkmEvaluationFlags), and the type is from an assembly // with no symbols. var hideNonPublicBehavior = DeclarationInfo.None; if (hideNonPublic) { var moduleInstance = appDomain.FindClrModuleInstance(type.Module.ModuleVersionId); if (moduleInstance == null || moduleInstance.Module == null) { // Synthetic module or no symbols loaded. hideNonPublicBehavior = DeclarationInfo.HideNonPublic; } } foreach (var member in type.GetMembers(MemberBindingFlags)) { if (!predicate(member)) { continue; } var memberName = member.Name; // This represents information about the immediately preceding (more derived) // declaration with the same name as the current member. var previousDeclaration = DeclarationInfo.None; var memberNameAlreadySeen = false; if (includeInherited) { memberNameAlreadySeen = previousDeclarationMap.TryGetValue(memberName, out previousDeclaration); if (memberNameAlreadySeen) { // There was a name conflict, so we'll need to include the declaring // type of the member to disambiguate. previousDeclaration |= DeclarationInfo.IncludeTypeInMemberName; } // Update previous member with name hiding (casting) and declared location information for next time. previousDeclarationMap[memberName] = (previousDeclaration & ~(DeclarationInfo.RequiresExplicitCast | DeclarationInfo.FromSubTypeOfDeclaredType)) | member.AccessingBaseMemberWithSameNameRequiresExplicitCast() | memberLocation; } Debug.Assert(memberNameAlreadySeen != (previousDeclaration == DeclarationInfo.None)); // Decide whether to include this member in the list of members to display. if (!memberNameAlreadySeen || previousDeclaration.IsSet(DeclarationInfo.RequiresExplicitCast)) { DkmClrDebuggerBrowsableAttributeState?browsableStateValue = null; if (browsableState != null) { DkmClrDebuggerBrowsableAttributeState value; if (browsableState.TryGetValue(memberName, out value)) { browsableStateValue = value; } } if (memberLocation.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType)) { // If the current type is a sub-type of the declared type, then // we always need to insert a cast to access the member previousDeclaration |= DeclarationInfo.RequiresExplicitCast; } else if (previousDeclaration.IsSet(DeclarationInfo.FromSubTypeOfDeclaredType)) { // If the immediately preceding member (less derived) was // declared on a sub-type of the declared type, then we'll // ignore the casting bit. Accessing a member through the // declared type is the same as casting to that type, so // the cast would be redundant. previousDeclaration &= ~DeclarationInfo.RequiresExplicitCast; } previousDeclaration |= hideNonPublicBehavior; includedMembers.Add(new MemberAndDeclarationInfo(member, browsableStateValue, previousDeclaration, inheritanceLevel)); } } if (!includeInherited) { break; } type = type.BaseType; inheritanceLevel++; } includedMembers.Sort(MemberAndDeclarationInfo.Comparer); }
public override DictionaryAnalysisData <AnalysisEntity, TValue> Merge(DictionaryAnalysisData <AnalysisEntity, TValue> map1, DictionaryAnalysisData <AnalysisEntity, TValue> map2) { AssertValidAnalysisData(map1); AssertValidAnalysisData(map2); var resultMap = new DictionaryAnalysisData <AnalysisEntity, TValue>(); using var newKeys = PooledHashSet <AnalysisEntity> .GetInstance(); using var valuesToMergeBuilder = ArrayBuilder <TValue> .GetInstance(5); var map2LookupIgnoringInstanceLocation = map2.Keys.Where(IsAnalysisEntityForFieldOrProperty) .ToLookup(entity => entity.EqualsIgnoringInstanceLocationId); foreach (var entry1 in map1) { AnalysisEntity key1 = entry1.Key; TValue value1 = entry1.Value; if (map2LookupIgnoringInstanceLocation.Count > 0 && IsAnalysisEntityForFieldOrProperty(key1)) { var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId]; if (!equivalentKeys2.Any()) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(!map2.ContainsKey(key1)); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); continue; } foreach (AnalysisEntity key2 in equivalentKeys2) { // Confirm that key2 and key1 are indeed EqualsIgnoringInstanceLocation // This ensures that we handle hash code clashes of EqualsIgnoringInstanceLocationId. if (!key1.EqualsIgnoringInstanceLocation(key2)) { continue; } TValue value2 = map2[key2]; valuesToMergeBuilder.Clear(); valuesToMergeBuilder.Add(value1); valuesToMergeBuilder.Add(value2); if (key1.InstanceLocation.Equals(key2.InstanceLocation)) { var mergedValue = GetMergedValue(valuesToMergeBuilder); AddNewEntryToResultMap(key1, mergedValue); } else { if (key1.SymbolOpt == null || !Equals(key1.SymbolOpt, key2.SymbolOpt)) { // PERF: Do not add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities. continue; } AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2); var isExistingKeyInInput = false; var isExistingKeyInResult = false; if (resultMap.TryGetValue(mergedKey, out var existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInResult = true; } if (map1.TryGetValue(mergedKey, out existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInInput = true; } if (map2.TryGetValue(mergedKey, out existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInInput = true; } var isCandidateToBeSkipped = !isExistingKeyInInput && !isExistingKeyInResult; if (isCandidateToBeSkipped && CanSkipNewEntity(mergedKey)) { // PERF: Do not add a new key-value pair to the resultMap if the key is not reachable from tracked entities and PointsTo values. continue; } var mergedValue = GetMergedValue(valuesToMergeBuilder); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); if (isCandidateToBeSkipped && CanSkipNewEntry(mergedKey, mergedValue)) { // PERF: Do not add a new key-value pair to the resultMap if the value can be skipped. continue; } if (!isExistingKeyInInput) { newKeys.Add(mergedKey); } AddNewEntryToResultMap(mergedKey, mergedValue, isNewKey: !isExistingKeyInInput); } } } else if (map2.TryGetValue(key1, out var value2)) { TValue mergedValue = ValueDomain.Merge(value1, value2); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); continue; } if (!resultMap.ContainsKey(key1)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); } } foreach (var kvp in map2) { var key2 = kvp.Key; var value2 = kvp.Value; if (!resultMap.ContainsKey(key2)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); AddNewEntryToResultMap(key2, mergedValue); } } foreach (var newKey in newKeys) { Debug.Assert(!map1.ContainsKey(newKey)); Debug.Assert(!map2.ContainsKey(newKey)); var value = resultMap[newKey]; if (ReferenceEquals(value, GetDefaultValue(newKey))) { resultMap.Remove(newKey); } else { OnNewMergedValue(value); } } Debug.Assert(Compare(map1, resultMap) <= 0); Debug.Assert(Compare(map2, resultMap) <= 0); AssertValidAnalysisData(resultMap); return(resultMap);
internal ImmutableArray <TypeParameterConstraintClause> BindTypeParameterConstraintClauses( Symbol containingSymbol, ImmutableArray <TypeParameterSymbol> typeParameters, TypeParameterListSyntax typeParameterList, SyntaxList <TypeParameterConstraintClauseSyntax> clauses, ref IReadOnlyDictionary <TypeParameterSymbol, bool> isValueTypeOverride, DiagnosticBag diagnostics, bool isForOverride = false) { Debug.Assert(this.Flags.Includes(BinderFlags.GenericConstraintsClause)); RoslynDebug.Assert((object)containingSymbol != null); Debug.Assert((containingSymbol.Kind == SymbolKind.NamedType) || (containingSymbol.Kind == SymbolKind.Method)); Debug.Assert(typeParameters.Length > 0); Debug.Assert(clauses.Count > 0); int n = typeParameters.Length; // Create a map from type parameter name to ordinal. // No need to report duplicate names since duplicates // are reported when the type parameters are bound. var names = new Dictionary <string, int>(n, StringOrdinalComparer.Instance); foreach (var typeParameter in typeParameters) { var name = typeParameter.Name; if (!names.ContainsKey(name)) { names.Add(name, names.Count); } } // An array of constraint clauses, one for each type parameter, indexed by ordinal. var results = ArrayBuilder <TypeParameterConstraintClause?> .GetInstance(n, fillWithValue : null); var syntaxNodes = ArrayBuilder <ArrayBuilder <TypeConstraintSyntax>?> .GetInstance(n, fillWithValue : null); // Bind each clause and add to the results. foreach (var clause in clauses) { var name = clause.Name.Identifier.ValueText; RoslynDebug.Assert(name is object); int ordinal; if (names.TryGetValue(name, out ordinal)) { Debug.Assert(ordinal >= 0); Debug.Assert(ordinal < n); (TypeParameterConstraintClause constraintClause, ArrayBuilder <TypeConstraintSyntax>?typeConstraintNodes) = this.BindTypeParameterConstraints(typeParameterList.Parameters[ordinal], clause, isForOverride, diagnostics); if (results[ordinal] == null) { results[ordinal] = constraintClause; syntaxNodes[ordinal] = typeConstraintNodes; } else { // "A constraint clause has already been specified for type parameter '{0}'. ..." diagnostics.Add(ErrorCode.ERR_DuplicateConstraintClause, clause.Name.Location, name); typeConstraintNodes?.Free(); } } else { // Unrecognized type parameter. Don't bother binding the constraints // (the ": I<U>" in "where U : I<U>") since that will lead to additional // errors ("type or namespace 'U' could not be found") if the type // parameter is referenced in the constraints. // "'{1}' does not define type parameter '{0}'" diagnostics.Add(ErrorCode.ERR_TyVarNotFoundInConstraint, clause.Name.Location, name, containingSymbol.ConstructedFrom()); } } // Add default values for type parameters without constraint clauses. for (int i = 0; i < n; i++) { if (results[i] == null) { results[i] = GetDefaultTypeParameterConstraintClause(typeParameterList.Parameters[i], isForOverride); } } TypeParameterConstraintClause.AdjustConstraintTypes(containingSymbol, typeParameters, results, ref isValueTypeOverride); RemoveInvalidConstraints(typeParameters, results !, syntaxNodes, diagnostics); foreach (var typeConstraintsSyntaxes in syntaxNodes) { typeConstraintsSyntaxes?.Free(); } syntaxNodes.Free(); return(results.ToImmutableAndFree() !); }
/// <remarks> /// NOTE: Keep this method in sync with AnalyzeImplicitUserDefinedConversion. /// </remarks> protected UserDefinedConversionResult AnalyzeImplicitUserDefinedConversionForV6SwitchGoverningType(TypeSymbol source, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { // SPEC: The governing type of a switch statement is established by the switch expression. // SPEC: 1) If the type of the switch expression is sbyte, byte, short, ushort, int, uint, // SPEC: long, ulong, bool, char, string, or an enum-type, or if it is the nullable type // SPEC: corresponding to one of these types, then that is the governing type of the switch statement. // SPEC: 2) Otherwise, exactly one user-defined implicit conversion (ยง6.4) must exist from the // SPEC: type of the switch expression to one of the following possible governing types: // SPEC: sbyte, byte, short, ushort, int, uint, long, ulong, char, string, or, a nullable type // SPEC: corresponding to one of those types // NOTE: This method implements part (2) above, it should be called only if (1) is false for source type. Debug.Assert((object)source != null); Debug.Assert(!source.IsValidV6SwitchGoverningType()); // NOTE: For (2) we use an approach similar to native compiler's approach, but call into the common code for analyzing user defined implicit conversions. // NOTE: (a) Compute the set of types D from which user-defined conversion operators should be considered by considering only the source type. // NOTE: (b) Instead of computing applicable user defined implicit conversions U from the source type to a specific target type, // NOTE: we compute these from the source type to ANY target type. // NOTE: (c) From the conversions in U, select the most specific of them that targets a valid switch governing type // SPEC VIOLATION: Because we use the same strategy for computing the most specific conversion, as the Dev10 compiler did (in fact // SPEC VIOLATION: we share the code), we inherit any spec deviances in that analysis. Specifically, the analysis only considers // SPEC VIOLATION: which conversion has the least amount of lifting, where a conversion may be considered to be in unlifted form, // SPEC VIOLATION: half-lifted form (only the argument type or return type is lifted) or fully lifted form. The most specific computation // SPEC VIOLATION: looks for a unique conversion that is least lifted. The spec, on the other hand, requires that the conversion // SPEC VIOLATION: be *unique*, not merely most use the least amount of lifting among the applicable conversions. // SPEC VIOLATION: This introduces a SPEC VIOLATION for the following tests in the native compiler: // NOTE: // See test SwitchTests.CS0166_AggregateTypeWithMultipleImplicitConversions_07 // NOTE: struct Conv // NOTE: { // NOTE: public static implicit operator int (Conv C) { return 1; } // NOTE: public static implicit operator int (Conv? C2) { return 0; } // NOTE: public static int Main() // NOTE: { // NOTE: Conv? D = new Conv(); // NOTE: switch(D) // NOTE: { ... // SPEC VIOLATION: Native compiler allows the above code to compile // SPEC VIOLATION: even though there are two user-defined implicit conversions: // SPEC VIOLATION: 1) To int type (applicable in normal form): public static implicit operator int (Conv? C2) // SPEC VIOLATION: 2) To int? type (applicable in lifted form): public static implicit operator int (Conv C) // NOTE: // See also test SwitchTests.TODO // NOTE: struct Conv // NOTE: { // NOTE: public static implicit operator int? (Conv C) { return 1; } // NOTE: public static implicit operator string (Conv? C2) { return 0; } // NOTE: public static int Main() // NOTE: { // NOTE: Conv? D = new Conv(); // NOTE: switch(D) // NOTE: { ... // SPEC VIOLATION: Native compiler allows the above code to compile too // SPEC VIOLATION: even though there are two user-defined implicit conversions: // SPEC VIOLATION: 1) To string type (applicable in normal form): public static implicit operator string (Conv? C2) // SPEC VIOLATION: 2) To int? type (applicable in half-lifted form): public static implicit operator int? (Conv C) // SPEC VIOLATION: This occurs because the native compiler compares the applicable conversions to find one with the least amount // SPEC VIOLATION: of lifting, ignoring whether the return types are the same or not. // SPEC VIOLATION: We do the same to maintain compatibility with the native compiler. // (a) Compute the set of types D from which user-defined conversion operators should be considered by considering only the source type. var d = ArrayBuilder <NamedTypeSymbol> .GetInstance(); ComputeUserDefinedImplicitConversionTypeSet(source, t: null, d: d, useSiteDiagnostics: ref useSiteDiagnostics); // (b) Instead of computing applicable user defined implicit conversions U from the source type to a specific target type, // we compute these from the source type to ANY target type. We will filter out those that are valid switch governing // types later. var ubuild = ArrayBuilder <UserDefinedConversionAnalysis> .GetInstance(); ComputeApplicableUserDefinedImplicitConversionSet(null, source, target: null, d: d, u: ubuild, useSiteDiagnostics: ref useSiteDiagnostics, allowAnyTarget: true); d.Free(); ImmutableArray <UserDefinedConversionAnalysis> u = ubuild.ToImmutableAndFree(); // (c) Find that conversion with the least amount of lifting int?best = MostSpecificConversionOperator(conv => conv.ToType.IsValidV6SwitchGoverningType(isTargetTypeOfUserDefinedOp: true), u); if (best != null) { return(UserDefinedConversionResult.Valid(u, best.Value)); } return(UserDefinedConversionResult.NoApplicableOperators(u)); }
private (TypeParameterConstraintClause, ArrayBuilder <TypeConstraintSyntax>?) BindTypeParameterConstraints(TypeParameterSyntax typeParameterSyntax, TypeParameterConstraintClauseSyntax constraintClauseSyntax, bool isForOverride, DiagnosticBag diagnostics) { var constraints = TypeParameterConstraintKind.None; ArrayBuilder <TypeWithAnnotations>? constraintTypes = null; ArrayBuilder <TypeConstraintSyntax>?syntaxBuilder = null; SeparatedSyntaxList <TypeParameterConstraintSyntax> constraintsSyntax = constraintClauseSyntax.Constraints; Debug.Assert(!InExecutableBinder); // Cannot eagerly report diagnostics handled by LazyMissingNonNullTypesContextDiagnosticInfo bool hasTypeLikeConstraint = false; bool reportedOverrideWithConstraints = false; for (int i = 0, n = constraintsSyntax.Count; i < n; i++) { var syntax = constraintsSyntax[i]; switch (syntax.Kind()) { case SyntaxKind.ClassConstraint: hasTypeLikeConstraint = true; if (i != 0) { if (!reportedOverrideWithConstraints) { reportTypeConstraintsMustBeUniqueAndFirst(syntax, diagnostics); } if (isForOverride && (constraints & (TypeParameterConstraintKind.ValueType | TypeParameterConstraintKind.ReferenceType)) != 0) { continue; } } var constraintSyntax = (ClassOrStructConstraintSyntax)syntax; SyntaxToken questionToken = constraintSyntax.QuestionToken; if (questionToken.IsKind(SyntaxKind.QuestionToken)) { constraints |= TypeParameterConstraintKind.NullableReferenceType; if (isForOverride) { reportOverrideWithConstraints(ref reportedOverrideWithConstraints, syntax, diagnostics); } else { LazyMissingNonNullTypesContextDiagnosticInfo.ReportNullableReferenceTypesIfNeeded(AreNullableAnnotationsEnabled(questionToken), questionToken.GetLocation(), diagnostics); } } else if (isForOverride || AreNullableAnnotationsEnabled(constraintSyntax.ClassOrStructKeyword)) { constraints |= TypeParameterConstraintKind.NotNullableReferenceType; } else { constraints |= TypeParameterConstraintKind.ReferenceType; } continue; case SyntaxKind.StructConstraint: hasTypeLikeConstraint = true; if (i != 0) { if (!reportedOverrideWithConstraints) { reportTypeConstraintsMustBeUniqueAndFirst(syntax, diagnostics); } if (isForOverride && (constraints & (TypeParameterConstraintKind.ValueType | TypeParameterConstraintKind.ReferenceType)) != 0) { continue; } } constraints |= TypeParameterConstraintKind.ValueType; continue; case SyntaxKind.ConstructorConstraint: if (isForOverride) { reportOverrideWithConstraints(ref reportedOverrideWithConstraints, syntax, diagnostics); continue; } if ((constraints & TypeParameterConstraintKind.ValueType) != 0) { diagnostics.Add(ErrorCode.ERR_NewBoundWithVal, syntax.GetFirstToken().GetLocation()); } if ((constraints & TypeParameterConstraintKind.Unmanaged) != 0) { diagnostics.Add(ErrorCode.ERR_NewBoundWithUnmanaged, syntax.GetFirstToken().GetLocation()); } if (i != n - 1) { diagnostics.Add(ErrorCode.ERR_NewBoundMustBeLast, syntax.GetFirstToken().GetLocation()); } constraints |= TypeParameterConstraintKind.Constructor; continue; case SyntaxKind.DefaultConstraint: if (!isForOverride) { diagnostics.Add(ErrorCode.ERR_DefaultConstraintOverrideOnly, syntax.GetLocation()); } if (i != 0) { if (!reportedOverrideWithConstraints) { reportTypeConstraintsMustBeUniqueAndFirst(syntax, diagnostics); } if (isForOverride && (constraints & (TypeParameterConstraintKind.ValueType | TypeParameterConstraintKind.ReferenceType)) != 0) { continue; } } constraints |= TypeParameterConstraintKind.Default; continue; case SyntaxKind.TypeConstraint: if (isForOverride) { reportOverrideWithConstraints(ref reportedOverrideWithConstraints, syntax, diagnostics); } else { hasTypeLikeConstraint = true; if (constraintTypes == null) { constraintTypes = ArrayBuilder <TypeWithAnnotations> .GetInstance(); syntaxBuilder = ArrayBuilder <TypeConstraintSyntax> .GetInstance(); } var typeConstraintSyntax = (TypeConstraintSyntax)syntax; var typeSyntax = typeConstraintSyntax.Type; var type = BindTypeOrConstraintKeyword(typeSyntax, diagnostics, out ConstraintContextualKeyword keyword); switch (keyword) { case ConstraintContextualKeyword.Unmanaged: if (i != 0) { reportTypeConstraintsMustBeUniqueAndFirst(typeSyntax, diagnostics); continue; } // This should produce diagnostics if the types are missing GetWellKnownType(WellKnownType.System_Runtime_InteropServices_UnmanagedType, diagnostics, typeSyntax); GetSpecialType(SpecialType.System_ValueType, diagnostics, typeSyntax); constraints |= TypeParameterConstraintKind.Unmanaged; continue; case ConstraintContextualKeyword.NotNull: if (i != 0) { reportTypeConstraintsMustBeUniqueAndFirst(typeSyntax, diagnostics); } constraints |= TypeParameterConstraintKind.NotNull; continue; case ConstraintContextualKeyword.None: break; default: throw ExceptionUtilities.UnexpectedValue(keyword); } constraintTypes.Add(type); syntaxBuilder !.Add(typeConstraintSyntax); } continue; default: throw ExceptionUtilities.UnexpectedValue(syntax.Kind()); } } if (!isForOverride && !hasTypeLikeConstraint && !AreNullableAnnotationsEnabled(typeParameterSyntax.Identifier)) { constraints |= TypeParameterConstraintKind.ObliviousNullabilityIfReferenceType; } Debug.Assert(!isForOverride || (constraints & (TypeParameterConstraintKind.ReferenceType | TypeParameterConstraintKind.ValueType)) != (TypeParameterConstraintKind.ReferenceType | TypeParameterConstraintKind.ValueType)); return(TypeParameterConstraintClause.Create(constraints, constraintTypes?.ToImmutableAndFree() ?? ImmutableArray <TypeWithAnnotations> .Empty), syntaxBuilder);
private static ImmutableArray <CodeFix> GetConfigurations(Project project, IEnumerable <Diagnostic> diagnostics, CancellationToken cancellationToken) { var result = ArrayBuilder <CodeFix> .GetInstance(); foreach (var diagnostic in diagnostics) { // First get all the relevant code style options for the diagnostic. var codeStyleOptions = ConfigurationUpdater.GetCodeStyleOptionsForDiagnostic(diagnostic, project); if (codeStyleOptions.IsEmpty) { continue; } // For each code style option, create a top level code action with nested code actions for every valid option value. // For example, if the option value is CodeStyleOption<bool>, we will have two nested actions, one for 'true' setting and one // for 'false' setting. If the option value is CodeStyleOption<SomeEnum>, we will have a nested action for each enum field. using var _ = ArrayBuilder <CodeAction> .GetInstance(out var nestedActions); var optionSet = project.Solution.Workspace.Options; var hasMultipleOptions = codeStyleOptions.Length > 1; foreach (var(optionKey, codeStyleOption, editorConfigLocation, perLanguageOption) in codeStyleOptions.OrderBy(t => t.optionKey.Option.Name)) { var topLevelAction = GetCodeActionForCodeStyleOption(optionKey, codeStyleOption, editorConfigLocation, diagnostic, perLanguageOption, optionSet, hasMultipleOptions); if (topLevelAction != null) { nestedActions.Add(topLevelAction); } } if (nestedActions.Count != 0) { // Wrap actions by another level if the diagnostic ID has multiple associated code style options to reduce clutter. var resultCodeAction = nestedActions.Count > 1 ? new TopLevelConfigureCodeStyleOptionCodeAction(diagnostic, nestedActions.ToImmutable()) : nestedActions.Single(); result.Add(new CodeFix(project, resultCodeAction, diagnostic)); } } return(result.ToImmutableAndFree()); // Local functions TopLevelConfigureCodeStyleOptionCodeAction GetCodeActionForCodeStyleOption( OptionKey optionKey, ICodeStyleOption codeStyleOption, IEditorConfigStorageLocation2 editorConfigLocation, Diagnostic diagnostic, bool isPerLanguage, OptionSet optionSet, bool hasMultipleOptions) { // Add a code action for every valid value of the given code style option. // We only support light-bulb configuration of code style options with boolean or enum values. using var _ = ArrayBuilder <CodeAction> .GetInstance(out var nestedActions); var severity = codeStyleOption.Notification.ToEditorConfigString(); string optionName = null; if (codeStyleOption.Value is bool) { foreach (var boolValue in s_boolValues) { AddCodeActionWithOptionValue(codeStyleOption, boolValue); } } else if (codeStyleOption.Value?.GetType() is Type t && t.IsEnum) { foreach (var enumValue in Enum.GetValues(t)) { AddCodeActionWithOptionValue(codeStyleOption, enumValue); } } if (nestedActions.Count > 0) { // If this is not a unique code style option for the diagnostic, use the optionName as the code action title. // In that case, we will already have a containing top level action for the diagnostic. // Otherwise, use the diagnostic information in the title. return(hasMultipleOptions ? new TopLevelConfigureCodeStyleOptionCodeAction(optionName, nestedActions.ToImmutable()) : new TopLevelConfigureCodeStyleOptionCodeAction(diagnostic, nestedActions.ToImmutable())); } return(null); // Local functions void AddCodeActionWithOptionValue(ICodeStyleOption codeStyleOption, object newValue) { // Create a new code style option value with the newValue var configuredCodeStyleOption = codeStyleOption.WithValue(newValue); // Try to get the parsed editorconfig string representation of the new code style option value if (ConfigurationUpdater.TryGetEditorConfigStringParts(configuredCodeStyleOption, editorConfigLocation, optionSet, out var parts)) { // We expect all code style values for same code style option to have the same editorconfig option name. Debug.Assert(optionName == null || optionName == parts.optionName); optionName ??= parts.optionName; // Add code action to configure the optionValue. nestedActions.Add( new SolutionChangeAction( parts.optionValue, solution => ConfigurationUpdater.ConfigureCodeStyleOptionAsync(parts.optionName, parts.optionValue, diagnostic, isPerLanguage, project, cancellationToken))); } } } }
private ImmutableArray <ParameterSymbol> MakeParameters( CSharpCompilation compilation, UnboundLambda unboundLambda, ImmutableArray <TypeWithAnnotations> parameterTypes, ImmutableArray <RefKind> parameterRefKinds ) { Debug.Assert(parameterTypes.Length == parameterRefKinds.Length); if (!unboundLambda.HasSignature || unboundLambda.ParameterCount == 0) { // The parameters may be omitted in source, but they are still present on the symbol. return(parameterTypes.SelectAsArray( (type, ordinal, arg) => SynthesizedParameterSymbol.Create( arg.owner, type, ordinal, arg.refKinds[ordinal], GeneratedNames.LambdaCopyParameterName(ordinal) ), // Make sure nothing binds to this. (owner: this, refKinds: parameterRefKinds) )); } var builder = ArrayBuilder <ParameterSymbol> .GetInstance(unboundLambda.ParameterCount); var hasExplicitlyTypedParameterList = unboundLambda.HasExplicitlyTypedParameterList; var numDelegateParameters = parameterTypes.Length; for (int p = 0; p < unboundLambda.ParameterCount; ++p) { // If there are no types given in the lambda then used the delegate type. // If the lambda is typed then the types probably match the delegate types; // if they do not, use the lambda types for binding. Either way, if we // can, then we use the lambda types. (Whatever you do, do not use the names // in the delegate parameters; they are not in scope!) TypeWithAnnotations type; RefKind refKind; if (hasExplicitlyTypedParameterList) { type = unboundLambda.ParameterTypeWithAnnotations(p); refKind = unboundLambda.RefKind(p); } else if (p < numDelegateParameters) { type = parameterTypes[p]; refKind = parameterRefKinds[p]; } else { type = TypeWithAnnotations.Create( new ExtendedErrorTypeSymbol( compilation, name: string.Empty, arity: 0, errorInfo: null ) ); refKind = RefKind.None; } var name = unboundLambda.ParameterName(p); var location = unboundLambda.ParameterLocation(p); var locations = location == null ? ImmutableArray <Location> .Empty : ImmutableArray.Create <Location>(location); var parameter = new SourceSimpleParameterSymbol( owner: this, type, ordinal: p, refKind, name, unboundLambda.ParameterIsDiscard(p), locations ); builder.Add(parameter); } var result = builder.ToImmutableAndFree(); return(result); }
internal sealed override void AddSynthesizedAttributes(ModuleCompilationState compilationState, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(compilationState, ref attributes); if (_debuggerHidden) { var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); } if (this.ReturnType.ContainsDynamic()) { var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.SynthesizeDynamicAttribute(this.ReturnType, this.ReturnTypeCustomModifiers.Length)); } }
private void AddDebuggerDisplayAttributeArguments(INamedTypeSymbol namedTypeSymbol, ArrayBuilder <string> builder) { AddDebuggerDisplayAttributeArgumentsCore(namedTypeSymbol, builder); foreach (var member in namedTypeSymbol.GetMembers()) { switch (member) { case INamedTypeSymbol nestedType: AddDebuggerDisplayAttributeArguments(nestedType, builder); break; case IPropertySymbol _: case IFieldSymbol _: AddDebuggerDisplayAttributeArgumentsCore(member, builder); break; } } }
/// <remarks> /// NOTE: Keep this method in sync with <see cref="AnalyzeImplicitUserDefinedConversionForV6SwitchGoverningType"/>. /// </remarks> private UserDefinedConversionResult AnalyzeImplicitUserDefinedConversions( BoundExpression sourceExpression, TypeSymbol source, TypeSymbol target, ref HashSet <DiagnosticInfo> useSiteDiagnostics) { Debug.Assert(sourceExpression != null || (object)source != null); Debug.Assert((object)target != null); // User-defined conversions that involve generics can be quite strange. There // are two basic problems: first, that generic user-defined conversions can be // "shadowed" by built-in conversions, and second, that generic user-defined // conversions can make conversions that would never have been legal user-defined // conversions if declared non-generically. I call this latter kind of conversion // a "suspicious" conversion. // // The shadowed conversions are easily dealt with: // // SPEC: If a predefined implicit conversion exists from a type S to type T, // SPEC: all user-defined conversions, implicit or explicit, are ignored. // SPEC: If a predefined explicit conversion exists from a type S to type T, // SPEC: any user-defined explicit conversion from S to T are ignored. // // The rule above can come into play in cases like: // // sealed class C<T> { public static implicit operator T(C<T> c) { ... } } // C<object> c = whatever; // object o = c; // // The built-in implicit conversion from C<object> to object must shadow // the user-defined implicit conversion. // // The caller of this method checks for user-defined conversions *after* // predefined implicit conversions, so we already know that if we got here, // there was no predefined implicit conversion. // // Note that a user-defined *implicit* conversion may win over a built-in // *explicit* conversion by the rule given above. That is, if we created // an implicit conversion from T to C<T>, then the user-defined implicit // conversion from object to C<object> could be valid, even though that // would be "replacing" a built-in explicit conversion with a user-defined // implicit conversion. This is one of the "suspicious" conversions, // as it would not be legal to declare a user-defined conversion from // object in a non-generic type. // // The way the native compiler handles suspicious conversions involving // interfaces is neither sensible nor in line with the rules in the // specification. It is not clear at this time whether we should be exactly // matching the native compiler, the specification, or neither, in Roslyn. // Spec (6.4.4 User-defined implicit conversions) // A user-defined implicit conversion from an expression E to type T is processed as follows: // SPEC: Find the set of types D from which user-defined conversion operators... var d = ArrayBuilder <NamedTypeSymbol> .GetInstance(); ComputeUserDefinedImplicitConversionTypeSet(source, target, d, ref useSiteDiagnostics); // SPEC: Find the set of applicable user-defined and lifted conversion operators, U... var ubuild = ArrayBuilder <UserDefinedConversionAnalysis> .GetInstance(); ComputeApplicableUserDefinedImplicitConversionSet(sourceExpression, source, target, d, ubuild, ref useSiteDiagnostics); d.Free(); ImmutableArray <UserDefinedConversionAnalysis> u = ubuild.ToImmutableAndFree(); // SPEC: If U is empty, the conversion is undefined and a compile-time error occurs. if (u.Length == 0) { return(UserDefinedConversionResult.NoApplicableOperators(u)); } // SPEC: Find the most specific source type SX of the operators in U... TypeSymbol sx = MostSpecificSourceTypeForImplicitUserDefinedConversion(u, source, ref useSiteDiagnostics); if ((object)sx == null) { return(UserDefinedConversionResult.NoBestSourceType(u)); } // SPEC: Find the most specific target type TX of the operators in U... TypeSymbol tx = MostSpecificTargetTypeForImplicitUserDefinedConversion(u, target, ref useSiteDiagnostics); if ((object)tx == null) { return(UserDefinedConversionResult.NoBestTargetType(u)); } int?best = MostSpecificConversionOperator(sx, tx, u); if (best == null) { return(UserDefinedConversionResult.Ambiguous(u)); } return(UserDefinedConversionResult.Valid(u, best.Value)); }