Exemple #1
0
        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));
            }
        }
Exemple #3
0
            /// <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);
     }
 }
Exemple #8
0
        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);
         }
     }
 }
Exemple #15
0
 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);
            }
        }
Exemple #17
0
        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);
            }
        }
Exemple #18
0
        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++;
            }
        }
Exemple #19
0
 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;
        }
Exemple #30
0
 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);
                }
            }
        }
Exemple #32
0
        // 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;
        }
Exemple #33
0
        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));
Exemple #35
0
 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)));
 }
Exemple #36
0
 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));
 }
Exemple #37
0
        /// <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();
            }
        }
Exemple #39
0
 public void AddSymbol(ISymbolNode node)
 {
     _definedSymbols.Add(node);
 }
 internal void AddHoistedField(LambdaCapturedVariable captured) =>
 _membersBuilder.Add(captured);
Exemple #41
0
        /// <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);
Exemple #42
0
            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);
            }
Exemple #43
0
            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;
                    }
                }
            }
Exemple #44
0
 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));
 }
Exemple #45
0
 public CamelCaseResult WithAddedMatchedSpan(TextSpan value)
 {
     MatchedSpansInReverse?.Add(value);
     return new CamelCaseResult(FromStart, Contiguous, MatchCount + 1, MatchedSpansInReverse);
 }
Exemple #46
0
        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);
        }
Exemple #47
0
        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)));
            }
        }
Exemple #49
0
        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));
 }
Exemple #51
0
 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);
 }
Exemple #54
0
        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;
            }
        }
Exemple #56
0
            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;
                    }
                }
            }
Exemple #57
0
 public CamelCaseResult WithAddedMatchedSpan(TextSpan value)
 {
     MatchedSpansInReverse?.Add(value);
     return(new CamelCaseResult(FromStart, Contiguous, ToEnd, MatchCount + 1, MatchedSpansInReverse, ChunkOffset));
 }
Exemple #58
0
 public void EmitByte(byte emit)
 {
     _data.Add(emit);
 }
Exemple #59
0
        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));
        }