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(); }
internal void SerializeCustomDebugInformation(ArrayBuilder<Cci.MemoryStream> customDebugInfo) { if (!this.LocalSlots.IsDefaultOrEmpty) { customDebugInfo.Add(SerializeRecord(Cci.CustomDebugInfoConstants.CdiKindEditAndContinueLocalSlotMap, SerializeLocalSlots)); } if (!this.Lambdas.IsDefaultOrEmpty) { customDebugInfo.Add(SerializeRecord(Cci.CustomDebugInfoConstants.CdiKindEditAndContinueLambdaMap, SerializeLambdaMap)); } }
/// <summary> /// Updates the currently stored 'best result' if the current result is better. /// Returns 'true' if no further work is required and we can break early, or /// 'false' if we need to keep on going. /// /// If 'weight' is better than 'bestWeight' and matchSpanToAdd is not null, then /// matchSpanToAdd will be added to matchedSpansInReverse. /// </summary> private bool UpdateBestResultIfBetter( int?weight, ArrayBuilder <TextSpan> matchedSpansInReverse, ref int?bestWeight, ref ArrayBuilder <TextSpan> bestMatchedSpansInReverse, TextSpan?matchSpanToAdd) { if (!IsBetter(weight, bestWeight)) { // Even though we matched this current candidate hump we failed to match // the remainder of the pattern. Continue to the next candidate hump // to see if our pattern character will match it and potentially succeed. matchedSpansInReverse?.Free(); // We need to keep going. return(false); } if (matchSpanToAdd != null) { matchedSpansInReverse?.Add(matchSpanToAdd.Value); } // This was result was better than whatever previous best result we had was. // Free and overwrite the existing best results, and keep going. bestWeight = weight; bestMatchedSpansInReverse?.Free(); bestMatchedSpansInReverse = matchedSpansInReverse; // We found a path that allowed us to match everything contiguously // from the beginning. This is the best match possible. So we can // just break out now and return this result. return(weight == CamelCaseMaxWeight); }
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(); }
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(); }
/// <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); } }
private static void AddNonIncluded(ArrayBuilder<string> builder, string item) { if (!builder.Contains(item)) { builder.Add(item); } }
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; }
// 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 void AddDelegateMembers( ArrayBuilder<Symbol> symbols, DelegateDeclarationSyntax syntax, BinderFactory binderFactory, DiagnosticBag diagnostics) { var bodyBinder = binderFactory.GetBinder(syntax.ParameterList); // A delegate has the following members: (see CLI spec 13.6) // (1) a method named Invoke with the specified signature var invoke = new DelegateInvokeMethodImplementation(this, syntax, bodyBinder, diagnostics); invoke.CheckMethodVarianceSafety(diagnostics); symbols.Add(invoke); // (2) a constructor with argument types (object, System.IntPtr) symbols.Add(new DelegateConstructor(this, syntax, bodyBinder)); var delegateBinder = new DelegateBinder(bodyBinder, this, invoke); // (3) BeginInvoke symbols.Add(new DelegateBeginInvokeMethod(this, syntax, delegateBinder, diagnostics)); // and (4) EndInvoke methods symbols.Add(new DelegateEndInvokeMethod(this, syntax, delegateBinder, diagnostics)); if (this.DeclaredAccessibility <= Accessibility.Private) { return; } if (!this.IsNoMoreVisibleThan(invoke.ReturnType)) { // Inconsistent accessibility: return type '{1}' is less accessible than delegate '{0}' diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, Locations[0], this, invoke.ReturnType); } foreach (var parameter in invoke.Parameters) { if (!parameter.Type.IsAtLeastAsVisibleAs(this)) { // Inconsistent accessibility: parameter type '{1}' is less accessible than delegate '{0}' diagnostics.Add(ErrorCode.ERR_BadVisDelegateParam, Locations[0], this, parameter.Type); } } }
// methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them. // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it. // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned. // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them) public static SmallDictionary<CSharpSyntaxNode, Binder> BuildMap(MethodSymbol method, CSharpSyntaxNode syntax, Binder enclosing, ArrayBuilder<CSharpSyntaxNode> methodsWithYields) { var builder = new LocalBinderFactory(method, enclosing, methodsWithYields); builder.Visit(syntax); // the other place this is possible is in a local function if (builder._sawYield) methodsWithYields.Add(syntax); return builder._map; }
public static void AddTypesParticipatingInUserDefinedConversion(ArrayBuilder<NamedTypeSymbol> result, TypeSymbol type, bool includeBaseTypes, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { if ((object)type == null) { return; } // CONSIDER: These sets are usually small; if they are large then this is an O(n^2) // CONSIDER: algorithm. We could use a hash table instead to build up the set. Debug.Assert(!type.IsTypeParameter()); // optimization: bool excludeExisting = result.Count > 0; // The decimal type does not contribute its user-defined conversions to the mix; though its // conversions are actually implemented via user-defined operators, we logically treat it as // though those conversions were built-in. if (type.IsClassType() || type.IsStructType() && type.SpecialType != SpecialType.System_Decimal) { var namedType = (NamedTypeSymbol)type; if (!excludeExisting || !HasIdentityConversionToAny(namedType, result)) { result.Add(namedType); } } if (!includeBaseTypes) { return; } NamedTypeSymbol t = type.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics); while ((object)t != null) { if (!excludeExisting || !HasIdentityConversionToAny(t, result)) { result.Add(t); } t = t.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics); } }
private static void RewriteLocalDeclaration( CSharpCompilation compilation, EENamedTypeSymbol container, HashSet<LocalSymbol> declaredLocals, ArrayBuilder<BoundStatement> statements, BoundLocalDeclaration node) { Debug.Assert(node.ArgumentsOpt.IsDefault); var local = node.LocalSymbol; var syntax = node.Syntax; declaredLocals.Add(local); var typeType = compilation.GetWellKnownType(WellKnownType.System_Type); var stringType = compilation.GetSpecialType(SpecialType.System_String); // CreateVariable(Type type, string name) var method = PlaceholderLocalSymbol.GetIntrinsicMethod(compilation, ExpressionCompilerConstants.CreateVariableMethodName); var type = new BoundTypeOfOperator(syntax, new BoundTypeExpression(syntax, aliasOpt: null, type: local.Type), null, typeType); var name = new BoundLiteral(syntax, ConstantValue.Create(local.Name), stringType); var call = BoundCall.Synthesized( syntax, receiverOpt: null, method: method, arguments: ImmutableArray.Create<BoundExpression>(type, name)); statements.Add(new BoundExpressionStatement(syntax, call)); var initializer = node.InitializerOpt; if (initializer != null) { // Generate assignment to local. The assignment will // be rewritten in PlaceholderLocalRewriter. var assignment = new BoundAssignmentOperator( syntax, new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type), initializer, RefKind.None, local.Type); statements.Add(new BoundExpressionStatement(syntax, assignment)); } }
protected void RewriteLocals(ImmutableArray<LocalSymbol> locals, ArrayBuilder<LocalSymbol> newLocals) { foreach (var local in locals) { LocalSymbol newLocal; if (TryRewriteLocal(local, out newLocal)) { newLocals.Add(newLocal); } } }
private static void AddIfMissing <T>( ImmutableDictionary <T, TextSpan> .Builder mapping, ArrayBuilder <T> list, T val, TextSpan span) { if (!mapping.ContainsKey(val)) { mapping.Add(val, span); list?.Add(val); } }
public static void AddTypesParticipatingInUserDefinedConversion(ArrayBuilder<NamedTypeSymbol> result, TypeSymbol type, bool includeBaseTypes, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { if ((object)type == null) { return; } // CONSIDER: These sets are usually small; if they are large then this is an O(n^2) // CONSIDER: algorithm. We could use a hash table instead to build up the set. Debug.Assert(!type.IsTypeParameter()); // optimization: bool excludeExisting = result.Count > 0; if (type.IsClassType() || type.IsStructType()) { var namedType = (NamedTypeSymbol)type; if (!excludeExisting || !HasIdentityConversionToAny(namedType, result)) { result.Add(namedType); } } if (!includeBaseTypes) { return; } NamedTypeSymbol t = type.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics); while ((object)t != null) { if (!excludeExisting || !HasIdentityConversionToAny(t, result)) { result.Add(t); } t = t.BaseTypeWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics); } }
private static void GetRebuiltNodes(SyntaxNodeOrToken newNode, HashSet<GreenNode> hashSet, ArrayBuilder<SyntaxNodeOrToken> nodes) { if (hashSet.Contains(newNode.UnderlyingNode)) { return; } nodes.Add(newNode); foreach (var child in newNode.ChildNodesAndTokens()) { GetRebuiltNodes(child, hashSet, nodes); } }
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(); var defaultView = fields.DefaultView; int startIndex2; int count2; GetIntersection(startIndex, count, index, defaultView.Count, out startIndex2, out count2); int offset = startIndex2 - index; for (int i = 0; i < count2; i++) { var row = GetMemberRow(resultProvider, inspectionContext, value, defaultView[i + offset], parent, _cardinality); rows.Add(row); } index += defaultView.Count; if (fields.IncludeRawView) { if (InRange(startIndex, count, index)) { rows.Add(this.CreateRawViewRow(resultProvider, inspectionContext, parent, value)); } index++; } }
private static void GetAllScopes(ISymUnmanagedScope scope, ArrayBuilder<ISymUnmanagedScope> builder, int offset, bool isScopeEndInclusive) { builder.Add(scope); foreach (var nested in scope.GetScopes()) { if ((offset < 0) || nested.IsInScope(offset, isScopeEndInclusive)) { GetAllScopes(nested, builder, offset, isScopeEndInclusive); if (offset >= 0) { return; } } } }
/// <remarks> /// Not guaranteed to add the same number of flags as would /// appear in a System.Runtime.CompilerServices.DynamicAttribute. /// It may have more (for padding) or fewer (for compactness) falses. /// It is, however, guaranteed to include the last true. /// </remarks> internal static void CopyTo(ReadOnlyCollection<byte> bytes, ArrayBuilder<bool> builder) { if (bytes == null) { return; } foreach (byte b in bytes) { for (int i = 0; i < 8; i++) { builder.Add((b & (1 << i)) != 0); } } }
// Add all active #pragma warn directives under trivia into the list, in source code order. private static void GetAllPragmaWarningDirectives(SyntaxTree syntaxTree, ArrayBuilder<PragmaWarningDirectiveTriviaSyntax> directiveList) { foreach (var d in syntaxTree.GetRoot().GetDirectives()) { if (d.Kind() == SyntaxKind.PragmaWarningDirectiveTrivia) { var w = d as PragmaWarningDirectiveTriviaSyntax; // Ignore directives with errors (i.e., Unrecognized #pragma directive) and // directives inside disabled code (by #if and #endif) if (!w.DisableOrRestoreKeyword.IsMissing && !w.WarningKeyword.IsMissing && w.IsActive) directiveList.Add(w); } } }
/// <remarks> /// Not guaranteed to add the same number of flags as would /// appear in a <see cref="System.Runtime.CompilerServices.DynamicAttribute"/>. /// It may have more (for padding) or fewer (for compactness) falses. /// It is, however, guaranteed to include the last true. /// </remarks> internal void CopyTo(ArrayBuilder<bool> builder) { if (_bytes == null) { return; } foreach (byte b in _bytes) { for (int i = 0; i < 8; i++) { builder.Add((b & (1 << i)) != 0); } } }
override protected ImmutableArray<LocalSymbol> BuildLocals() { if (syntax.Declaration != null) { var locals = new ArrayBuilder<LocalSymbol>(syntax.Declaration.Variables.Count); foreach (VariableDeclaratorSyntax declarator in syntax.Declaration.Variables) { locals.Add(SourceLocalSymbol.MakeLocal(this.Owner, this, syntax.Declaration.Type, declarator.Identifier, declarator.Initializer, LocalDeclarationKind.Fixed)); } return locals.ToImmutable(); } return ImmutableArray<LocalSymbol>.Empty; }
override protected ImmutableArray<LocalSymbol> BuildLocals() { if (_syntax.Declaration != null) { var locals = new ArrayBuilder<LocalSymbol>(_syntax.Declaration.Variables.Count); foreach (VariableDeclaratorSyntax declarator in _syntax.Declaration.Variables) { locals.Add(MakeLocal(_syntax.Declaration, declarator, LocalDeclarationKind.FixedVariable)); } return locals.ToImmutable(); } return ImmutableArray<LocalSymbol>.Empty; }
protected void AddLocals(ImmutableArray<LocalSymbol> locals, ArrayBuilder<LocalSymbol> newLocals) { if (locals.IsDefault) { return; } foreach (var local in locals) { LocalSymbol newLocal; if (TryRewriteLocal(local, out newLocal)) { newLocals.Add(newLocal); } } }
private void AddDelegateOperation(BinaryOperatorKind kind, TypeSymbol delegateType, ArrayBuilder<BinaryOperatorSignature> operators) { switch (kind) { case BinaryOperatorKind.Equal: case BinaryOperatorKind.NotEqual: operators.Add(new BinaryOperatorSignature(kind | BinaryOperatorKind.Delegate, delegateType, delegateType, Compilation.GetSpecialType(SpecialType.System_Boolean))); break; case BinaryOperatorKind.Addition: case BinaryOperatorKind.Subtraction: default: operators.Add(new BinaryOperatorSignature(kind | BinaryOperatorKind.Delegate, delegateType, delegateType, delegateType)); break; } }
internal override void GetRows( ResultProvider resultProvider, ArrayBuilder<EvalResult> rows, DkmInspectionContext inspectionContext, EvalResultDataItem parent, DkmClrValue value, int startIndex, int count, bool visitAll, ref int index) { if (InRange(startIndex, count, index)) { rows.Add(CreateDynamicViewRow(inspectionContext, Resources.DynamicView, parent, resultProvider.FullNameProvider)); } index++; }
internal override void GetRows( ResultProvider resultProvider, ArrayBuilder<EvalResultDataItem> rows, DkmInspectionContext inspectionContext, EvalResultDataItem parent, DkmClrValue value, int startIndex, int count, bool visitAll, ref int index) { if (InRange(startIndex, count, index)) { rows.Add(GetRow(resultProvider, inspectionContext, value, _elementTypeAndInfo, parent: parent)); } index++; }
override protected ImmutableArray<LocalSymbol> BuildLocals() { if (_syntax.Declaration != null) { var locals = new ArrayBuilder<LocalSymbol>(_syntax.Declaration.Variables.Count); foreach (VariableDeclaratorSyntax declarator in _syntax.Declaration.Variables) { locals.Add(MakeLocal(_syntax.Declaration, declarator, LocalDeclarationKind.FixedVariable)); // also gather expression-declared variables from the bracketed argument lists and the initializers ExpressionVariableFinder.FindExpressionVariables(this, locals, declarator); } return locals.ToImmutable(); } return ImmutableArray<LocalSymbol>.Empty; }
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 memberValue = value.GetMemberValue(_member, inspectionContext); var isDynamicDebugViewEmptyException = memberValue.Type.GetLmrType().IsDynamicDebugViewEmptyException(); if (isDynamicDebugViewEmptyException || memberValue.IsError()) { if (InRange(startIndex, count, index)) { if (isDynamicDebugViewEmptyException) { var emptyMember = memberValue.Type.GetMemberByName("Empty"); memberValue = memberValue.GetMemberValue(emptyMember, inspectionContext); } var row = new EvalResult(Resources.ErrorName, (string)memberValue.HostObjectValue, inspectionContext); rows.Add(row); } index++; } else { var other = MemberExpansion.CreateMemberDataItem( resultProvider, inspectionContext, _member, memberValue, parent, _dynamicFlagsMap, ExpansionFlags.IncludeBaseMembers | ExpansionFlags.IncludeResultsView); var expansion = other.Expansion; if (expansion != null) { expansion.GetRows(resultProvider, rows, inspectionContext, other.ToDataItem(), other.Value, startIndex, count, visitAll, ref index); } } }
/// <summary> /// Applies the deconstructions. /// Adds any new locals to the temps and any new expressions to be evaluated to the stores. /// </summary> private void ApplyDeconstructions(BoundDeconstructionAssignmentOperator node, ArrayBuilder<LocalSymbol> temps, ArrayBuilder<BoundExpression> stores, ArrayBuilder<BoundValuePlaceholderBase> placeholders, BoundExpression loweredRight) { var firstDeconstructStep = node.DeconstructSteps[0]; AddPlaceholderReplacement(firstDeconstructStep.InputPlaceholder, loweredRight); placeholders.Add(firstDeconstructStep.InputPlaceholder); foreach (BoundDeconstructionDeconstructStep deconstruction in node.DeconstructSteps) { if (deconstruction.DeconstructInvocationOpt == null) { // tuple case AccessTupleFields(node, deconstruction, temps, stores, placeholders); } else { CallDeconstruct(node, deconstruction, temps, stores, placeholders); } } }
// methodsWithYields will contain all function-declaration-like CSharpSyntaxNodes with yield statements contained within them. // Currently the types of these are restricted to only be whatever the syntax parameter is, plus any LocalFunctionStatementSyntax contained within it. // This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned. // (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them) public static SmallDictionary<CSharpSyntaxNode, Binder> BuildMap(Symbol containingMemberOrLambda, CSharpSyntaxNode syntax, Binder enclosing, ArrayBuilder<CSharpSyntaxNode> methodsWithYields) { var builder = new LocalBinderFactory(containingMemberOrLambda, syntax, enclosing, methodsWithYields); if (syntax is ExpressionSyntax) { var binder = new PatternVariableBinder(syntax, enclosing); builder.AddToMap(syntax, binder); builder.Visit(syntax, binder); } else { builder.Visit(syntax); } // the other place this is possible is in a local function if (builder._sawYield) methodsWithYields.Add(syntax); return builder._map; }
private static void SerializeDynamicLocalInfo(IMethodBody methodBody, ArrayBuilder <BlobBuilder> customDebugInfo) { if (!methodBody.HasDynamicLocalVariables) { return; //There are no dynamic locals } var dynamicLocals = ArrayBuilder <ILocalDefinition> .GetInstance(); foreach (ILocalDefinition local in methodBody.LocalVariables) { Debug.Assert(local.SlotIndex >= 0); if (local.IsDynamic) { dynamicLocals.Add(local); } } foreach (var currentScope in methodBody.LocalScopes) { foreach (var localConstant in currentScope.Constants) { Debug.Assert(localConstant.SlotIndex < 0); if (localConstant.IsDynamic) { dynamicLocals.Add(localConstant); } } } Debug.Assert(dynamicLocals.Any()); // There must be at least one dynamic local if this point is reached const int dynamicAttributeSize = 64; const int identifierSize = 64; const int blobSize = dynamicAttributeSize + 4 + 4 + identifierSize * 2;//DynamicAttribute: 64, DynamicAttributeLength: 4, SlotIndex: 4, IdentifierName: 128 var cmw = new BlobBuilder(); cmw.WriteByte(CDI.CdiVersion); cmw.WriteByte(CDI.CdiKindDynamicLocals); cmw.Align(4); // size = Version,Kind + size + cBuckets + (dynamicCount * sizeOf(Local Blob)) cmw.WriteUInt32(4 + 4 + 4 + (uint)dynamicLocals.Count * blobSize);//Size of the Dynamic Block cmw.WriteUInt32((uint)dynamicLocals.Count); foreach (ILocalDefinition local in dynamicLocals) { if (local.Name.Length >= identifierSize)//Ignore and push empty information { cmw.WriteBytes(0, blobSize); continue; } var dynamicTransformFlags = local.DynamicTransformFlags; if (!dynamicTransformFlags.IsDefault && dynamicTransformFlags.Length <= dynamicAttributeSize) { byte[] flag = new byte[dynamicAttributeSize]; for (int k = 0; k < dynamicTransformFlags.Length; k++) { if ((bool)dynamicTransformFlags[k].Value) { flag[k] = 1; } } cmw.WriteBytes(flag); //Written Flag cmw.WriteUInt32((uint)dynamicTransformFlags.Length); //Written Length } else { cmw.WriteBytes(0, dynamicAttributeSize + 4); //Empty flag array and size. } var localIndex = local.SlotIndex; cmw.WriteUInt32((localIndex < 0) ? 0u : (uint)localIndex); char[] localName = new char[identifierSize]; local.Name.CopyTo(0, localName, 0, local.Name.Length); cmw.WriteUTF16(localName); } dynamicLocals.Free(); customDebugInfo.Add(cmw); }
private async Task AddUnwrapCodeActionAsync(ArrayBuilder <WrapItemsAction> actions) => actions.Add(await TryCreateCodeActionAsync(GetUnwrapEdits(), FeaturesResources.Wrapping, FeaturesResources.Unwrap_call_chain).ConfigureAwait(false));
private static void GenerateWritableProperty(ArrayBuilder <CodeAction> result, SemanticDocument document, State state) { result.Add(new GenerateVariableCodeAction( document, state, generateProperty: true, isReadonly: false, isConstant: false, refKind: GetRefKindFromContext(state))); }
private static void GenerateWriteableField(ArrayBuilder <CodeAction> result, SemanticDocument document, State state) { result.Add(new GenerateVariableCodeAction( document, state, generateProperty: false, isReadonly: false, isConstant: false, refKind: RefKind.None)); }
/// <summary> /// digs into known concat operators and unwraps their arguments /// otherwise returns the expression as-is /// /// Generally we only need to recognize same node patterns that we create as a result of concatenation rewrite. /// </summary> private void FlattenConcatArg(BoundExpression lowered, ArrayBuilder <BoundExpression> flattened) { switch (lowered.Kind) { case BoundKind.Call: var boundCall = (BoundCall)lowered; var method = boundCall.Method; if (method.IsStatic && method.ContainingType.SpecialType == SpecialType.System_String) { if ((object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatStringString) || (object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatStringStringString) || (object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatStringStringStringString) || (object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatObject) || (object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatObjectObject) || (object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatObjectObjectObject)) { flattened.AddRange(boundCall.Arguments); return; } if ((object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatStringArray) || (object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_String__ConcatObjectArray)) { var args = boundCall.Arguments[0] as BoundArrayCreation; if (args != null) { var initializer = args.InitializerOpt; if (initializer != null) { flattened.AddRange(initializer.Initializers); return; } } } } break; case BoundKind.NullCoalescingOperator: var boundCoalesce = (BoundNullCoalescingOperator)lowered; if (boundCoalesce.LeftConversion.IsIdentity) { // The RHS may be a constant value with an identity conversion to string even // if it is not a string: in particular, the null literal behaves this way. // To be safe, check that the constant value is actually a string before // attempting to access its value as a string. var rightConstant = boundCoalesce.RightOperand.ConstantValue; if (rightConstant != null && rightConstant.IsString && rightConstant.StringValue.Length == 0) { flattened.Add(boundCoalesce.LeftOperand); return; } } break; } // fallback - if nothing above worked, leave arg as-is flattened.Add(lowered); return; }
private SyntaxTriviaList RewriteTrivia( SyntaxTriviaList triviaList, int depth, bool isTrailing, bool indentAfterLineBreak, bool mustHaveSeparator, int lineBreaksAfter) { ArrayBuilder <SyntaxTrivia> currentTriviaList = ArrayBuilder <SyntaxTrivia> .GetInstance(triviaList.Count); try { foreach (var trivia in triviaList) { if (trivia.IsKind(SyntaxKind.WhitespaceTrivia) || trivia.IsKind(SyntaxKind.EndOfLineTrivia) || trivia.FullWidth == 0) { continue; } var needsSeparator = (currentTriviaList.Count > 0 && NeedsSeparatorBetween(currentTriviaList.Last())) || (currentTriviaList.Count == 0 && isTrailing); var needsLineBreak = NeedsLineBreakBefore(trivia, isTrailing) || (currentTriviaList.Count > 0 && NeedsLineBreakBetween(currentTriviaList.Last(), trivia, isTrailing)); if (needsLineBreak && !_afterLineBreak) { currentTriviaList.Add(GetEndOfLine()); _afterLineBreak = true; _afterIndentation = false; } if (_afterLineBreak) { if (!_afterIndentation && NeedsIndentAfterLineBreak(trivia)) { currentTriviaList.Add(this.GetIndentation(GetDeclarationDepth(trivia))); _afterIndentation = true; } } else if (needsSeparator) { currentTriviaList.Add(GetSpace()); _afterLineBreak = false; _afterIndentation = false; } if (trivia.HasStructure) { var tr = this.VisitStructuredTrivia(trivia); currentTriviaList.Add(tr); } else if (trivia.IsKind(SyntaxKind.DocumentationCommentExteriorTrivia)) { // recreate exterior to remove any leading whitespace currentTriviaList.Add(s_trimmedDocCommentExterior); } else { currentTriviaList.Add(trivia); } if (NeedsLineBreakAfter(trivia, isTrailing) && (currentTriviaList.Count == 0 || !EndsInLineBreak(currentTriviaList.Last()))) { currentTriviaList.Add(GetEndOfLine()); _afterLineBreak = true; _afterIndentation = false; } } if (lineBreaksAfter > 0) { if (currentTriviaList.Count > 0 && EndsInLineBreak(currentTriviaList.Last())) { lineBreaksAfter--; } for (int i = 0; i < lineBreaksAfter; i++) { currentTriviaList.Add(GetEndOfLine()); _afterLineBreak = true; _afterIndentation = false; } } else if (indentAfterLineBreak && _afterLineBreak && !_afterIndentation) { currentTriviaList.Add(this.GetIndentation(depth)); _afterIndentation = true; } else if (mustHaveSeparator) { currentTriviaList.Add(GetSpace()); _afterLineBreak = false; _afterIndentation = false; } if (currentTriviaList.Count == 0) { return(default(SyntaxTriviaList)); } else if (currentTriviaList.Count == 1) { return(SyntaxFactory.TriviaList(currentTriviaList.First())); } else { return(SyntaxFactory.TriviaList(currentTriviaList)); } } finally { currentTriviaList.Free(); } }
public void AddSymbol(ISymbolNode node) { _definedSymbols.Add(node); }
internal void AddHoistedField(LambdaCapturedVariable captured) => _membersBuilder.Add(captured);
/// <summary> /// Bind and return a single type parameter constraint clause along with syntax nodes corresponding to type constraints. /// </summary> private (TypeParameterConstraintClause, ArrayBuilder <TypeConstraintSyntax>?) BindTypeParameterConstraints(TypeParameterSyntax typeParameterSyntax, TypeParameterConstraintClauseSyntax constraintClauseSyntax, bool isForOverride, BindingDiagnosticBag 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 if (diagnostics.DiagnosticBag is DiagnosticBag diagnosticBag) { LazyMissingNonNullTypesContextDiagnosticInfo.AddAll(this, questionToken, type: null, diagnosticBag); } } 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);
protected ImmutableArray <BoundStatement> LowerDecisionDagCore(BoundDecisionDag decisionDag) { _loweredDecisionDag = ArrayBuilder <BoundStatement> .GetInstance(); ComputeLabelSet(decisionDag); ImmutableArray <BoundDecisionDagNode> sortedNodes = decisionDag.TopologicallySortedNodes; var firstNode = sortedNodes[0]; switch (firstNode) { case BoundWhenDecisionDagNode _: case BoundLeafDecisionDagNode _: // If the first node is a leaf or when clause rather than the code for the // lowered decision dag, jump there to start. _loweredDecisionDag.Add(_factory.Goto(GetDagNodeLabel(firstNode))); break; } // Code for each when clause goes in the separate code section for its switch section. foreach (BoundDecisionDagNode node in sortedNodes) { if (node is BoundWhenDecisionDagNode w) { LowerWhenClause(w); } } ImmutableArray <BoundDecisionDagNode> nodesToLower = sortedNodes.WhereAsArray(n => n.Kind != BoundKind.WhenDecisionDagNode && n.Kind != BoundKind.LeafDecisionDagNode); var loweredNodes = PooledHashSet <BoundDecisionDagNode> .GetInstance(); for (int i = 0, length = nodesToLower.Length; i < length; i++) { BoundDecisionDagNode node = nodesToLower[i]; if (loweredNodes.Contains(node)) { Debug.Assert(!_dagNodeLabels.TryGetValue(node, out _)); continue; } if (_dagNodeLabels.TryGetValue(node, out LabelSymbol label)) { _loweredDecisionDag.Add(_factory.Label(label)); } // If we can generate an IL switch instruction, do so if (GenerateSwitchDispatch(node, loweredNodes)) { continue; } // If we can generate a type test and cast more efficiently as an `is` followed by a null check, do so if (GenerateTypeTestAndCast(node, loweredNodes, nodesToLower, i)) { continue; } // We pass the node that will follow so we can permit a test to fall through if appropriate BoundDecisionDagNode nextNode = ((i + 1) < length) ? nodesToLower[i + 1] : null; if (nextNode != null && loweredNodes.Contains(nextNode)) { nextNode = null; } LowerDecisionDagNode(node, nextNode); } loweredNodes.Free(); var result = _loweredDecisionDag.ToImmutableAndFree(); _loweredDecisionDag = null; return(result); }
private void ScanInterpolatedStringLiteralContents(ArrayBuilder <Interpolation> interpolations) { while (true) { if (IsAtEnd()) { // error: end of line before end of string return; } switch (lexer.TextWindow.PeekChar()) { case '"': if (isVerbatim && lexer.TextWindow.PeekChar(1) == '"') { lexer.TextWindow.AdvanceChar(); // " lexer.TextWindow.AdvanceChar(); // " continue; } // found the end of the string return; case '}': var pos = lexer.TextWindow.Position; lexer.TextWindow.AdvanceChar(); // } // ensure any } characters are doubled up if (lexer.TextWindow.PeekChar() == '}') { lexer.TextWindow.AdvanceChar(); // } } else if (error == null) { error = lexer.MakeError(pos, 1, ErrorCode.ERR_UnescapedCurly, "}"); } continue; case '{': if (lexer.TextWindow.PeekChar(1) == '{') { lexer.TextWindow.AdvanceChar(); lexer.TextWindow.AdvanceChar(); } else { int openBracePosition = lexer.TextWindow.Position; lexer.TextWindow.AdvanceChar(); int colonPosition = 0; ScanInterpolatedStringLiteralHoleBalancedText('}', true, ref colonPosition); int closeBracePosition = lexer.TextWindow.Position; bool closeBraceMissing = false; if (lexer.TextWindow.PeekChar() == '}') { lexer.TextWindow.AdvanceChar(); } else { closeBraceMissing = true; if (error == null) { error = lexer.MakeError(openBracePosition - 1, 2, ErrorCode.ERR_UnclosedExpressionHole); } } interpolations?.Add(new Interpolation(openBracePosition, colonPosition, closeBracePosition, closeBraceMissing)); } continue; case '\\': if (isVerbatim) { goto default; } var escapeStart = lexer.TextWindow.Position; char c2; char ch = lexer.ScanEscapeSequence(out c2); if ((ch == '{' || ch == '}') && error == null) { error = lexer.MakeError(escapeStart, lexer.TextWindow.Position - escapeStart, ErrorCode.ERR_EscapedCurly, ch); } continue; default: // found some other character in the string portion lexer.TextWindow.AdvanceChar(); continue; } } }
public void DefineSequencePoint(string document, int lineNumber) { Debug.Assert(_sequencePoints.Count == 0 || _sequencePoints[_sequencePoints.Count - 1].Offset < _length); _sequencePoints.Add(new ILSequencePoint(_length, document, lineNumber)); }
public CamelCaseResult WithAddedMatchedSpan(TextSpan value) { MatchedSpansInReverse?.Add(value); return new CamelCaseResult(FromStart, Contiguous, MatchCount + 1, MatchedSpansInReverse); }
private static void SerializeDynamicLocalInfo(IMethodBody methodBody, ArrayBuilder <MemoryStream> customDebugInfo) { if (!methodBody.HasDynamicLocalVariables) { return; //There are no dynamic locals } var dynamicLocals = ArrayBuilder <ILocalDefinition> .GetInstance(); foreach (ILocalDefinition local in methodBody.LocalVariables) { if (local.IsDynamic) { dynamicLocals.Add(local); } } int dynamicVariableCount = dynamicLocals.Count; foreach (var currentScope in methodBody.LocalScopes) { foreach (var localConstant in currentScope.Constants) { if (localConstant.IsDynamic) { dynamicLocals.Add(localConstant); } } } Debug.Assert(dynamicLocals.Any()); // There must be atleast one dynamic local if this point is reached const int blobSize = 200; //DynamicAttribute - 64, DynamicAttributeLength - 4, SlotIndex -4, IdentifierName - 128 MemoryStream customMetadata = new MemoryStream(); BinaryWriter cmw = new BinaryWriter(customMetadata, true); cmw.WriteByte(CDI.CdiVersion); cmw.WriteByte(CDI.CdiKindDynamicLocals); cmw.Align(4); // size = Version,Kind + size + cBuckets + (dynamicCount * sizeOf(Local Blob)) cmw.WriteUint(4 + 4 + 4 + (uint)dynamicLocals.Count * blobSize);//Size of the Dynamic Block cmw.WriteUint((uint)dynamicLocals.Count); int localIndex = 0; foreach (ILocalDefinition local in dynamicLocals) { if (local.Name.Length > 63)//Ignore and push empty information { cmw.WriteBytes(0, blobSize); continue; } var dynamicTransformFlags = local.DynamicTransformFlags; if (!dynamicTransformFlags.IsDefault && dynamicTransformFlags.Length <= 64) { byte[] flag = new byte[64]; for (int k = 0; k < dynamicTransformFlags.Length; k++) { if ((bool)dynamicTransformFlags[k].Value) { flag[k] = 1; } } cmw.WriteBytes(flag); //Written Flag cmw.WriteUint((uint)dynamicTransformFlags.Length); //Written Length } else { cmw.WriteBytes(0, 68); //Empty flag array and size. } if (localIndex < dynamicVariableCount) { // Dynamic variable cmw.WriteUint((uint)local.SlotIndex); } else { // Dynamic constant cmw.WriteUint(0); } char[] localName = new char[64]; local.Name.CopyTo(0, localName, 0, local.Name.Length); cmw.WriteChars(localName); localIndex++; } dynamicLocals.Free(); customDebugInfo.Add(customMetadata); }
private async Task SetSeverityHandlerAsync(VisualStudioWorkspaceImpl workspace, MenuCommand selectedItem, ArrayBuilder <string> notificationMessages) { var componentModel = (IComponentModel)_serviceProvider.GetService(typeof(SComponentModel)); var uiThreadOperationExecutor = componentModel.GetService <VSUtilities.IUIThreadOperationExecutor>(); using var context = uiThreadOperationExecutor.BeginExecute( title: ServicesVSResources.Updating_severity, defaultDescription: "", allowCancellation: true, showProgress: true); var selectedAction = MapSelectedItemToReportDiagnostic(selectedItem); if (!selectedAction.HasValue) { return; } foreach (var selectedDiagnostic in _tracker.SelectedDiagnosticItems) { var projectId = selectedDiagnostic.ProjectId; var pathToRuleSet = workspace.TryGetRuleSetPathForProject(projectId); var project = workspace.CurrentSolution.GetProject(projectId); var pathToAnalyzerConfigDoc = project?.TryGetAnalyzerConfigPathForProjectConfiguration(); if (pathToRuleSet == null && pathToAnalyzerConfigDoc == null) { notificationMessages.Add(SolutionExplorerShim.No_rule_set_file_is_specified_or_the_file_does_not_exist); continue; } var editHandlerService = componentModel.GetService <ICodeActionEditHandlerService>(); try { var envDteProject = workspace.TryGetDTEProject(projectId); if (pathToRuleSet == null || SdkUiUtilities.IsBuiltInRuleSet(pathToRuleSet, _serviceProvider)) { // If project is using the default built-in ruleset or no ruleset, then prefer .editorconfig for severity configuration. if (pathToAnalyzerConfigDoc != null) { using var scope1 = context.AddScope(allowCancellation: true, description: ""); var newSolution = await selectedDiagnostic.GetSolutionWithUpdatedAnalyzerConfigSeverityAsync(selectedAction.Value, project, context.UserCancellationToken).ConfigureAwait(false); var operations = ImmutableArray.Create <CodeActionOperation>(new ApplyChangesOperation(newSolution)); await editHandlerService.ApplyAsync( _workspace, fromDocument : null, operations : operations, title : ServicesVSResources.Updating_severity, progressTracker : new UIThreadOperationContextProgressTracker(scope1), cancellationToken : context.UserCancellationToken).ConfigureAwait(true); continue; } // Otherwise, fall back to using ruleset. if (pathToRuleSet == null) { notificationMessages.Add(SolutionExplorerShim.No_rule_set_file_is_specified_or_the_file_does_not_exist); continue; } pathToRuleSet = CreateCopyOfRuleSetForProject(pathToRuleSet, envDteProject); if (pathToRuleSet == null) { notificationMessages.Add(string.Format(SolutionExplorerShim.Could_not_create_a_rule_set_for_project_0, envDteProject.Name)); continue; } var fileInfo = new FileInfo(pathToRuleSet); fileInfo.IsReadOnly = false; } using var scope2 = context.AddScope( allowCancellation: false, string.Format(SolutionExplorerShim.Checking_out_0_for_editing, Path.GetFileName(pathToRuleSet))); if (envDteProject.DTE.SourceControl.IsItemUnderSCC(pathToRuleSet)) { envDteProject.DTE.SourceControl.CheckOutItem(pathToRuleSet); } selectedDiagnostic.SetRuleSetSeverity(selectedAction.Value, pathToRuleSet); } catch (Exception e) { notificationMessages.Add(e.Message); } } }
internal override void ValidateOptions(ArrayBuilder <Diagnostic> builder) { // /main & /target:{library|netmodule|winmdobj} if (this.MainTypeName != null) { if (this.OutputKind.IsValid() && !this.OutputKind.IsApplication()) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_NoMainOnDLL)); } if (!MainTypeName.IsValidClrTypeName()) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(MainTypeName), MainTypeName)); } } if (!Platform.IsValid()) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPlatformType, Platform.ToString())); } if (ModuleName != null) { Exception e = MetadataHelpers.CheckAssemblyOrModuleName(ModuleName, nameof(ModuleName)); if (e != null) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOption, e.Message)); } } if (!OutputKind.IsValid()) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OutputKind), OutputKind.ToString())); } if (!OptimizationLevel.IsValid()) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(OptimizationLevel), OptimizationLevel.ToString())); } if (ScriptClassName == null || !ScriptClassName.IsValidClrTypeName()) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(ScriptClassName), ScriptClassName ?? "null")); } if (WarningLevel < 0 || WarningLevel > 4) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(WarningLevel), WarningLevel)); } if (Usings != null && Usings.Any(u => !u.IsValidClrNamespaceName())) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadCompilationOptionValue, nameof(Usings), Usings.Where(u => !u.IsValidClrNamespaceName()).First() ?? "null")); } if (Platform == Platform.AnyCpu32BitPreferred && OutputKind.IsValid() && !(OutputKind == OutputKind.ConsoleApplication || OutputKind == OutputKind.WindowsApplication || OutputKind == OutputKind.WindowsRuntimeApplication)) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_BadPrefer32OnLib)); } // TODO: add check for // (kind == 'arm' || kind == 'appcontainer' || kind == 'winmdobj') && // (version >= "6.2") if (!CryptoPublicKey.IsEmpty) { if (CryptoKeyFile != null) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_MutuallyExclusiveOptions, nameof(CryptoPublicKey), nameof(CryptoKeyFile))); } if (CryptoKeyContainer != null) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_MutuallyExclusiveOptions, nameof(CryptoPublicKey), nameof(CryptoKeyContainer))); } } if (PublicSign && DelaySign == true) { builder.Add(Diagnostic.Create(MessageProvider.Instance, (int)ErrorCode.ERR_MutuallyExclusiveOptions, nameof(PublicSign), nameof(DelaySign))); } }
private ImmutableArray <MergedNamespaceOrTypeDeclaration> MakeChildren() { ArrayBuilder <SingleNamespaceDeclaration> namespaces = null; ArrayBuilder <SingleTypeDeclaration> types = null; bool allNamespacesHaveSameName = true; bool allTypesHaveSameIdentity = true; foreach (var decl in _declarations) { foreach (var child in decl.Children) { // it is either a type (more likely) var asType = child as SingleTypeDeclaration; if (asType != null) { // handle types if (types == null) { types = ArrayBuilder <SingleTypeDeclaration> .GetInstance(); } else if (allTypesHaveSameIdentity && !asType.Identity.Equals(types[0].Identity)) { allTypesHaveSameIdentity = false; } types.Add(asType); continue; } // or it is a namespace var asNamespace = child as SingleNamespaceDeclaration; if (asNamespace != null) { // handle namespace if (namespaces == null) { namespaces = ArrayBuilder <SingleNamespaceDeclaration> .GetInstance(); } #if XSHARP else if (allNamespacesHaveSameName && !XSharpString.Equals(asNamespace.Name, namespaces[0].Name)) #else else if (allNamespacesHaveSameName && !asNamespace.Name.Equals(namespaces[0].Name)) #endif { allNamespacesHaveSameName = false; } namespaces.Add(asNamespace); continue; } // Not sure if we can get here, perhaps, if we have errors, // but we care only about types and namespaces anyways. } } var children = ArrayBuilder <MergedNamespaceOrTypeDeclaration> .GetInstance(); if (namespaces != null) { if (allNamespacesHaveSameName) { children.Add(MergedNamespaceDeclaration.Create(namespaces.ToImmutableAndFree())); } else { #if XSHARP var namespaceGroups = namespaces.ToDictionary(n => n.Name, XSharpString.Comparer); #else var namespaceGroups = namespaces.ToDictionary(n => n.Name, StringOrdinalComparer.Instance); #endif namespaces.Free(); foreach (var namespaceGroup in namespaceGroups.Values) { children.Add(MergedNamespaceDeclaration.Create(namespaceGroup)); } } } if (types != null) { if (allTypesHaveSameIdentity) { children.Add(new MergedTypeDeclaration(types.ToImmutableAndFree())); } else { var typeGroups = types.ToDictionary(t => t.Identity); types.Free(); foreach (var typeGroup in typeGroups.Values) { children.Add(new MergedTypeDeclaration(typeGroup)); } } } return(children.ToImmutableAndFree()); }
private async Task AddWrapLongCodeActionAsync(ArrayBuilder <WrapItemsAction> actions) { actions.Add(await TryCreateCodeActionAsync(GetWrapEdits(Options.WrappingColumn, align: false), FeaturesResources.Wrapping, FeaturesResources.Wrap_long_call_chain).ConfigureAwait(false)); actions.Add(await TryCreateCodeActionAsync(GetWrapEdits(Options.WrappingColumn, align: true), FeaturesResources.Wrapping, FeaturesResources.Wrap_and_align_long_call_chain).ConfigureAwait(false)); }
private void AddBlockComment(SnapshotSpan span, ArrayBuilder <TextChange> textChanges, ArrayBuilder <CommentTrackingSpan> trackingSpans, CommentSelectionInfo commentInfo) { trackingSpans.Add(new CommentTrackingSpan(TextSpan.FromBounds(span.Start, span.End))); InsertText(textChanges, span.Start, commentInfo.BlockCommentStartString); InsertText(textChanges, span.End, commentInfo.BlockCommentEndString); }
/// <summary> /// Gets the set of template types needed to support loading comparers for the give canonical type at runtime. /// </summary> private static TypeDesc[] GetPotentialComparersForTypeCommon(TypeDesc type, string flavor, string interfaceName) { Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any)); TypeDesc exactComparer = GetComparerForType(type, flavor, interfaceName); if (exactComparer != null) { // If we have a comparer that is exactly known at runtime, we're done. // This will typically be if type is a generic struct, generic enum, or a nullable. return(new TypeDesc[] { exactComparer }); } TypeSystemContext context = type.Context; if (context.IsCanonicalDefinitionType(type, CanonicalFormKind.Universal)) { // This can be any of the comparers we have. ArrayBuilder <TypeDesc> universalComparers = new ArrayBuilder <TypeDesc>(); universalComparers.Add(context.SystemModule.GetKnownType("System.Collections.Generic", $"Nullable{flavor}`1") .MakeInstantiatedType(type)); if (flavor == "EqualityComparer") { universalComparers.Add(context.SystemModule.GetKnownType("System.Collections.Generic", $"Enum{flavor}`1") .MakeInstantiatedType(type)); } universalComparers.Add(context.SystemModule.GetKnownType("System.Collections.Generic", $"Generic{flavor}`1") .MakeInstantiatedType(type)); universalComparers.Add(context.SystemModule.GetKnownType("System.Collections.Generic", $"Object{flavor}`1") .MakeInstantiatedType(type)); return(universalComparers.ToArray()); } // This mirrors exactly what GetUnknownEquatableComparer and GetUnknownComparer (in the class library) // will need at runtime. This is the general purpose code path that can be used to compare // anything. if (type.IsNullable) { TypeDesc nullableType = type.Instantiation[0]; // This should only be reachabe for universal canon code. // For specific canon, this should have been an exact match above. Debug.Assert(context.IsCanonicalDefinitionType(nullableType, CanonicalFormKind.Universal)); return(new TypeDesc[] { context.SystemModule.GetKnownType("System.Collections.Generic", $"Nullable{flavor}`1") .MakeInstantiatedType(nullableType), context.SystemModule.GetKnownType("System.Collections.Generic", $"Object{flavor}`1") .MakeInstantiatedType(type), }); } return(new TypeDesc[] { context.SystemModule.GetKnownType("System.Collections.Generic", $"Generic{flavor}`1") .MakeInstantiatedType(type), context.SystemModule.GetKnownType("System.Collections.Generic", $"Object{flavor}`1") .MakeInstantiatedType(type), }); }
public sealed override void VisitForEachStatement(ForEachStatementSyntax node) { _builder.Add(node); base.VisitForEachStatement(node); }
private void AddUserDefinedConversionsToExplicitCandidateSet( BoundExpression sourceExpression, TypeSymbol source, TypeSymbol target, ArrayBuilder <UserDefinedConversionAnalysis> u, NamedTypeSymbol declaringType, string operatorName, ref CompoundUseSiteInfo <AssemblySymbol> useSiteInfo) { Debug.Assert(sourceExpression != null || (object)source != null); Debug.Assert((object)target != null); Debug.Assert(u != null); Debug.Assert((object)declaringType != null); Debug.Assert(operatorName != null); // SPEC: Find the set of applicable user-defined and lifted conversion operators, U. // SPEC: The set consists of the user-defined and lifted implicit or explicit // SPEC: conversion operators declared by the classes and structs in D that convert // SPEC: from a type encompassing E or encompassed by S (if it exists) to a type // SPEC: encompassing or encompassed by T. // DELIBERATE SPEC VIOLATION: // // The spec here essentially says that we add an applicable "regular" conversion and // an applicable lifted conversion, if there is one, to the candidate set, and then // let them duke it out to determine which one is "best". // // This is not at all what the native compiler does, and attempting to implement // the specification, or slight variations on it, produces too many backwards-compatibility // breaking changes. // // The native compiler deviates from the specification in two major ways here. // First, it does not add *both* the regular and lifted forms to the candidate set. // Second, the way it characterizes a "lifted" form is very, very different from // how the specification characterizes a lifted form. // // An operation, in this case, X-->Y, is properly said to be "lifted" to X?-->Y? via // the rule that X?-->Y? matches the behavior of X-->Y for non-null X, and converts // null X to null Y otherwise. // // The native compiler, by contrast, takes the existing operator and "lifts" either // the operator's parameter type or the operator's return type to nullable. For // example, a conversion from X?-->Y would be "lifted" to X?-->Y? by making the // conversion from X? to Y, and then from Y to Y?. No "lifting" semantics // are imposed; we do not check to see if the X? is null. This operator is not // actually "lifted" at all; rather, an implicit conversion is applied to the // output. **The native compiler considers the result type Y? of that standard implicit // conversion to be the result type of the "lifted" conversion**, rather than // properly considering Y to be the result type of the conversion for the purposes // of computing the best output type. // // Moreover: the native compiler actually *does* implement nullable lifting semantics // in the case where the input type of the user-defined conversion is a non-nullable // value type and the output type is a nullable value type **or pointer type, or // reference type**. This is an enormous departure from the specification; the // native compiler will take a user-defined conversion from X-->Y? or X-->C and "lift" // it to a conversion from X?-->Y? or X?-->C that has nullable semantics. // // This is quite confusing. In this code we will classify the conversion as either // "normal" or "lifted" on the basis of *whether or not special lifting semantics // are to be applied*. That is, whether or not a later rewriting pass is going to // need to insert a check to see if the source expression is null, and decide // whether or not to call the underlying unlifted conversion or produce a null // value without calling the unlifted conversion. // DELIBERATE SPEC VIOLATION: See the comment regarding bug 17021 in // UserDefinedImplicitConversions.cs. if ((object)source != null && source.IsInterfaceType() || target.IsInterfaceType()) { return; } foreach (MethodSymbol op in declaringType.GetOperators(operatorName)) { // We might have a bad operator and be in an error recovery situation. Ignore it. if (op.ReturnsVoid || op.ParameterCount != 1 || op.ReturnType.TypeKind == TypeKind.Error) { continue; } TypeSymbol convertsFrom = op.GetParameterType(0); TypeSymbol convertsTo = op.ReturnType; Conversion fromConversion = EncompassingExplicitConversion(sourceExpression, source, convertsFrom, ref useSiteInfo); Conversion toConversion = EncompassingExplicitConversion(null, convertsTo, target, ref useSiteInfo); // We accept candidates for which the parameter type encompasses the *underlying* source type. if (!fromConversion.Exists && (object)source != null && source.IsNullableType() && EncompassingExplicitConversion(null, source.GetNullableUnderlyingType(), convertsFrom, ref useSiteInfo).Exists) { fromConversion = ClassifyBuiltInConversion(source, convertsFrom, ref useSiteInfo); } // As in dev11 (and the revised spec), we also accept candidates for which the return type is encompassed by the *stripped* target type. if (!toConversion.Exists && (object)target != null && target.IsNullableType() && EncompassingExplicitConversion(null, convertsTo, target.GetNullableUnderlyingType(), ref useSiteInfo).Exists) { toConversion = ClassifyBuiltInConversion(convertsTo, target, ref useSiteInfo); } // In the corresponding implicit conversion code we can get away with first // checking to see if standard implicit conversions exist from the source type // to the parameter type, and from the return type to the target type. If not, // then we can check for a lifted operator. // // That's not going to cut it in the explicit conversion code. Suppose we have // a conversion X-->Y and have source type X? and target type Y?. There *are* // standard explicit conversions from X?-->X and Y?-->Y, but we do not want // to bind this as an *unlifted* conversion from X? to Y?; we want such a thing // to be a *lifted* conversion from X? to Y?, that checks for null on the source // and decides to not call the underlying user-defined conversion if it is null. // // We therefore cannot do what we do in the implicit conversions, where we check // to see if the unlifted conversion works, and if it does, then don't add the lifted // conversion at all. Rather, we have to see if what we're building here is a // lifted conversion or not. // // Under what circumstances is this conversion a lifted conversion? (In the // "spec" sense of a lifted conversion; that is, that we check for null // and skip the user-defined conversion if necessary). // // * The source type must be a nullable value type. // * The parameter type must be a non-nullable value type. // * The target type must be able to take on a null value. if (fromConversion.Exists && toConversion.Exists) { if ((object)source != null && source.IsNullableType() && convertsFrom.IsNonNullableValueType() && target.CanBeAssignedNull()) { TypeSymbol nullableFrom = MakeNullableType(convertsFrom); TypeSymbol nullableTo = convertsTo.IsNonNullableValueType() ? MakeNullableType(convertsTo) : convertsTo; Conversion liftedFromConversion = EncompassingExplicitConversion(sourceExpression, source, nullableFrom, ref useSiteInfo); Conversion liftedToConversion = EncompassingExplicitConversion(null, nullableTo, target, ref useSiteInfo); Debug.Assert(liftedFromConversion.Exists); Debug.Assert(liftedToConversion.Exists); u.Add(UserDefinedConversionAnalysis.Lifted(op, liftedFromConversion, liftedToConversion, nullableFrom, nullableTo)); } else { // There is an additional spec violation in the native compiler. Suppose // we have a conversion from X-->Y and are asked to do "Y? y = new X();" Clearly // the intention is to convert from X-->Y via the implicit conversion, and then // stick a standard implicit conversion from Y-->Y? on the back end. **In this // situation, the native compiler treats the conversion as though it were // actually X-->Y? in source for the purposes of determining the best target // type of a set of operators. // // Similarly, if we have a conversion from X-->Y and are asked to do // an explicit conversion from X? to Y then we treat the conversion as // though it really were X?-->Y for the purposes of determining the best // source type of a set of operators. // // We perpetuate these fictions here. if (target.IsNullableType() && convertsTo.IsNonNullableValueType()) { convertsTo = MakeNullableType(convertsTo); toConversion = EncompassingExplicitConversion(null, convertsTo, target, ref useSiteInfo); } if ((object)source != null && source.IsNullableType() && convertsFrom.IsNonNullableValueType()) { convertsFrom = MakeNullableType(convertsFrom); fromConversion = EncompassingExplicitConversion(null, convertsFrom, source, ref useSiteInfo); } u.Add(UserDefinedConversionAnalysis.Normal(op, fromConversion, toConversion, convertsFrom, convertsTo)); } } } }
public static void GetExpressionSymbols(this BoundExpression node, ArrayBuilder <Symbol> symbols, BoundNode parent, Binder binder) { switch (node.Kind) { case BoundKind.MethodGroup: // Special case: if we are looking for info on "M" in "new Action(M)" in the context of a parent // then we want to get the symbol that overload resolution chose for M, not on the whole method group M. var delegateCreation = parent as BoundDelegateCreationExpression; if (delegateCreation != null && (object)delegateCreation.MethodOpt != null) { symbols.Add(delegateCreation.MethodOpt); } else { symbols.AddRange(CSharpSemanticModel.GetReducedAndFilteredMethodGroupSymbols(binder, (BoundMethodGroup)node)); } break; case BoundKind.BadExpression: symbols.AddRange(((BoundBadExpression)node).Symbols); break; case BoundKind.DelegateCreationExpression: var expr = (BoundDelegateCreationExpression)node; var ctor = expr.Type.GetMembers(WellKnownMemberNames.InstanceConstructorName).FirstOrDefault(); if ((object)ctor != null) { symbols.Add(ctor); } break; case BoundKind.Call: // Either overload resolution succeeded for this call or it did not. If it did not // succeed then we've stashed the original method symbols from the method group, // and we should use those as the symbols displayed for the call. If it did succeed // then we did not stash any symbols; just fall through to the default case. var originalMethods = ((BoundCall)node).OriginalMethodsOpt; if (originalMethods.IsDefault) { goto default; } symbols.AddRange(originalMethods); break; case BoundKind.IndexerAccess: // Same behavior as for a BoundCall: if overload resolution failed, pull out stashed candidates; // otherwise use the default behavior. var originalIndexers = ((BoundIndexerAccess)node).OriginalIndexersOpt; if (originalIndexers.IsDefault) { goto default; } symbols.AddRange(originalIndexers); break; default: var symbol = node.ExpressionSymbol; if ((object)symbol != null) { symbols.Add(symbol); } break; } }
private void ScanInterpolatedStringLiteralContents(ArrayBuilder <Interpolation>?interpolations) { while (true) { if (IsAtEnd()) { // error: end of line before end of string return; } switch (_lexer.TextWindow.PeekChar()) { case '"' when RecoveringFromRunawayLexing(): // When recovering from mismatched delimiters, we consume the next // quote character as the close quote for the interpolated string. In // practice this gets us out of trouble in scenarios we've encountered. // See, for example, https://github.com/dotnet/roslyn/issues/44789 return; case '"': if (_isVerbatim && _lexer.TextWindow.PeekChar(1) == '"') { _lexer.TextWindow.AdvanceChar(); // " _lexer.TextWindow.AdvanceChar(); // " continue; } // found the end of the string return; case '}': var pos = _lexer.TextWindow.Position; _lexer.TextWindow.AdvanceChar(); // } // ensure any } characters are doubled up if (_lexer.TextWindow.PeekChar() == '}') { _lexer.TextWindow.AdvanceChar(); // } } else { TrySetUnrecoverableError(_lexer.MakeError(pos, 1, ErrorCode.ERR_UnescapedCurly, "}")); } continue; case '{': if (_lexer.TextWindow.PeekChar(1) == '{') { _lexer.TextWindow.AdvanceChar(); _lexer.TextWindow.AdvanceChar(); } else { int openBracePosition = _lexer.TextWindow.Position; _lexer.TextWindow.AdvanceChar(); int colonPosition = 0; ScanInterpolatedStringLiteralHoleBalancedText('}', isHole: true, ref colonPosition); int closeBracePosition = _lexer.TextWindow.Position; bool closeBraceMissing = false; if (_lexer.TextWindow.PeekChar() == '}') { _lexer.TextWindow.AdvanceChar(); } else { closeBraceMissing = true; TrySetUnrecoverableError(_lexer.MakeError(openBracePosition - 1, 2, ErrorCode.ERR_UnclosedExpressionHole)); } interpolations?.Add(new Interpolation(openBracePosition, colonPosition, closeBracePosition, closeBraceMissing)); } continue; case '\\': if (_isVerbatim) { goto default; } var escapeStart = _lexer.TextWindow.Position; char ch = _lexer.ScanEscapeSequence(surrogateCharacter: out _); if (ch == '{' || ch == '}') { TrySetUnrecoverableError(_lexer.MakeError(escapeStart, _lexer.TextWindow.Position - escapeStart, ErrorCode.ERR_EscapedCurly, ch)); } continue; default: // found some other character in the string portion _lexer.TextWindow.AdvanceChar(); continue; } } }
public CamelCaseResult WithAddedMatchedSpan(TextSpan value) { MatchedSpansInReverse?.Add(value); return(new CamelCaseResult(FromStart, Contiguous, ToEnd, MatchCount + 1, MatchedSpansInReverse, ChunkOffset)); }
public void EmitByte(byte emit) { _data.Add(emit); }
protected ImmutableArray <LocalSymbol> BuildLocals(SyntaxList <StatementSyntax> statements, Binder enclosingBinder) { #if DEBUG Binder currentBinder = enclosingBinder; while (true) { if (this == currentBinder) { break; } currentBinder = currentBinder.Next; } #endif ArrayBuilder <LocalSymbol> locals = ArrayBuilder <LocalSymbol> .GetInstance(); foreach (var statement in statements) { var innerStatement = statement; // drill into any LabeledStatements -- atomic LabelStatements have been bound into // wrapped LabeledStatements by this point while (innerStatement.Kind() == SyntaxKind.LabeledStatement) { innerStatement = ((LabeledStatementSyntax)innerStatement).Statement; } switch (innerStatement.Kind()) { case SyntaxKind.LocalDeclarationStatement: { Binder localDeclarationBinder = enclosingBinder.GetBinder(innerStatement) ?? enclosingBinder; var decl = (LocalDeclarationStatementSyntax)innerStatement; LocalDeclarationKind kind = decl.IsConst ? LocalDeclarationKind.Constant : LocalDeclarationKind.RegularVariable; foreach (var vdecl in decl.Declaration.Variables) { var localSymbol = MakeLocal(decl.Declaration, vdecl, kind, localDeclarationBinder); locals.Add(localSymbol); // also gather expression-declared variables from the bracketed argument lists and the initializers ExpressionVariableFinder.FindExpressionVariables(this, locals, vdecl, localDeclarationBinder); } } break; case SyntaxKind.ExpressionStatement: case SyntaxKind.IfStatement: case SyntaxKind.YieldReturnStatement: case SyntaxKind.ReturnStatement: case SyntaxKind.ThrowStatement: ExpressionVariableFinder.FindExpressionVariables(this, locals, innerStatement, enclosingBinder.GetBinder(innerStatement) ?? enclosingBinder); break; case SyntaxKind.SwitchStatement: var switchStatement = (SwitchStatementSyntax)innerStatement; ExpressionVariableFinder.FindExpressionVariables(this, locals, innerStatement, enclosingBinder.GetBinder(switchStatement.Expression) ?? enclosingBinder); break; case SyntaxKind.WhileStatement: case SyntaxKind.DoStatement: case SyntaxKind.LockStatement: Binder statementBinder = enclosingBinder.GetBinder(innerStatement); Debug.Assert(statementBinder != null); // Lock, Do and while loops always have binders. ExpressionVariableFinder.FindExpressionVariables(this, locals, innerStatement, statementBinder); break; default: // no other statement introduces local variables into the enclosing scope break; } } return(locals.ToImmutableAndFree()); }
public override ICompilation ToCompilation() { ArrayBuilder <CorJitFlag> jitFlagBuilder = new ArrayBuilder <CorJitFlag>(); switch (_optimizationMode) { case OptimizationMode.None: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_CODE); break; case OptimizationMode.PreferSize: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SIZE_OPT); break; case OptimizationMode.PreferSpeed: jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_SPEED_OPT); break; default: // Not setting a flag results in BLENDED_CODE. break; } if (_optimizationMode != OptimizationMode.None && _profileDataManager != null) { jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_BBOPT); } // Do not bother with debug information if the debug info provider never gives anything. if (!(_debugInformationProvider is NullDebugInformationProvider)) { jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_DEBUG_INFO); } RyuJitCompilationOptions options = 0; if (_methodBodyFolding) { options |= RyuJitCompilationOptions.MethodBodyFolding; } if ((_mitigationOptions & SecurityMitigationOptions.ControlFlowGuardAnnotations) != 0) { options |= RyuJitCompilationOptions.ControlFlowGuardAnnotations; } if (_useDwarf5) { options |= RyuJitCompilationOptions.UseDwarf5; } if (_resilient) { options |= RyuJitCompilationOptions.UseResilience; } var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider, GetPreinitializationManager()); JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions); DependencyAnalyzerBase <NodeFactory> graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(new CompilerComparer())); return(new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _devirtualizationManager, _inliningPolicy ?? _compilationGroup, _instructionSetSupport, _profileDataManager, _methodImportationErrorProvider, options, _parallelism)); }