Beispiel #1
0
        private void GenerateImpl()
        {
            SetInitialDebugDocument();

            // Synthesized methods should have a sequence point
            // at offset 0 to ensure correct stepping behavior.
            if (_emitPdbSequencePoints && _method.IsImplicitlyDeclared)
            {
                _builder.DefineInitialHiddenSequencePoint();
            }

            try
            {
                EmitStatement(_boundBody);

                if (_indirectReturnState == IndirectReturnState.Needed)
                {
                    // it is unfortunate that return was not handled while we were in scope of the method
                    // it can happen in rare cases involving exception handling (for example all returns were from a try)
                    // in such case we can still handle return here.
                    HandleReturn();
                }

                if (!_diagnostics.HasAnyErrors())
                {
                    _builder.Realize();
                }
            }
            catch (EmitCancelledException)
            {
                Debug.Assert(_diagnostics.HasAnyErrors());
            }

            _synthesizedLocalOrdinals.Free();
        }
        internal override CommonCompilation CreateCompilation(IText code, string path, bool isInteractive, Session session, Type returnType, DiagnosticBag diagnostics)
        {
            Compilation previousSubmission = (Compilation)session.LastSubmission;
            IEnumerable <MetadataReference> referencesForCompilation = session.GetReferencesForCompilation();
            ReadOnlyArray <string>          namespacesForCompilation = session.GetNamespacesForCompilation();
            ParseOptions options    = isInteractive ? ScriptEngine.DefaultInteractive : ScriptEngine.DefaultScript;
            SyntaxTree   syntaxTree = SyntaxTree.ParseText(code, path, options, new CancellationToken());

            diagnostics.Add((IEnumerable <CommonDiagnostic>)syntaxTree.GetDiagnostics(new CancellationToken()));
            if (diagnostics.HasAnyErrors())
            {
                return((CommonCompilation)null);
            }
            string assemblyName;
            string typeName;

            this.GenerateSubmissionId(out assemblyName, out typeName);
            Compilation submission = Compilation.CreateSubmission(assemblyName, new CompilationOptions(OutputKind.DynamicallyLinkedLibrary, (string)null, typeName, (IEnumerable <string>)namespacesForCompilation.ToList(), DebugInformationKind.None, false, true, false, true, (string)null, (string)null, new bool?(), 0, 0UL, Platform.AnyCPU, ReportWarning.Default, 4, (IReadOnlyDictionary <int, ReportWarning>)null, false, new SubsystemVersion()), syntaxTree, previousSubmission, referencesForCompilation, session.FileResolver, this.metadataFileProvider, returnType, session.HostObjectType);

            this.ValidateReferences((CommonCompilation)submission, diagnostics);
            if (diagnostics.HasAnyErrors())
            {
                return((CommonCompilation)null);
            }
            else
            {
                return((CommonCompilation)submission);
            }
        }
Beispiel #3
0
        public void Generate()
        {
            this.GenerateImpl();

            Debug.Assert(this.asyncCatchHandlerOffset < 0);
            Debug.Assert(this.asyncYieldPoints == null);
            Debug.Assert(this.asyncResumePoints == null);

            if (!diagnostics.HasAnyErrors())
            {
                builder.Realize();
            }
        }
Beispiel #4
0
        /// <summary>
        /// Parse statement. Returns null if there are any errors.
        /// </summary>
        internal static StatementSyntax?ParseStatement(this string expr, DiagnosticBag diagnostics)
        {
            var syntax = ParseDebuggerStatement(expr);

            diagnostics.AddRange(syntax.GetDiagnostics());
            return(diagnostics.HasAnyErrors() ? null : syntax);
        }
Beispiel #5
0
        /// <summary>
        /// Parse expression. Returns null if there are any errors.
        /// </summary>
        internal static ExpressionSyntax ParseExpression(
            this string expr,
            DiagnosticBag diagnostics,
            bool allowFormatSpecifiers,
            out ReadOnlyCollection<string> formatSpecifiers)
        {
            // Remove trailing semi-colon if any. This is to support copy/paste
            // of (simple cases of) RHS of assignment in Watch window, not to
            // allow arbitrary syntax after the semi-colon, not even comments.
            if (RemoveSemicolonIfAny(ref expr))
            {
                // Format specifiers are not expected before a semi-colon.
                allowFormatSpecifiers = false;
            }

            var syntax = ParseDebuggerExpression(expr, consumeFullText: !allowFormatSpecifiers);
            diagnostics.AddRange(syntax.GetDiagnostics());
            formatSpecifiers = null;
            if (allowFormatSpecifiers)
            {
                var builder = ArrayBuilder<string>.GetInstance();
                if (ParseFormatSpecifiers(builder, expr, syntax.FullWidth, diagnostics) &&
                    (builder.Count > 0))
                {
                    formatSpecifiers = new ReadOnlyCollection<string>(builder.ToArray());
                }
                builder.Free();
            }
            return diagnostics.HasAnyErrors() ? null : syntax;
        }
Beispiel #6
0
 private static CSharpSyntaxNode Parse(
     string expr,
     bool treatAsExpression,
     DiagnosticBag diagnostics,
     out ReadOnlyCollection <string> formatSpecifiers)
 {
     if (treatAsExpression)
     {
         return(expr.ParseExpression(diagnostics, allowFormatSpecifiers: true, formatSpecifiers: out formatSpecifiers));
     }
     else
     {
         // Try to parse as an expression. If that fails, parse as a statement.
         var exprDiagnostics = DiagnosticBag.GetInstance();
         ReadOnlyCollection <string> exprFormatSpecifiers;
         CSharpSyntaxNode            syntax = expr.ParseExpression(exprDiagnostics, allowFormatSpecifiers: true, formatSpecifiers: out exprFormatSpecifiers);
         Debug.Assert((syntax == null) || !exprDiagnostics.HasAnyErrors());
         exprDiagnostics.Free();
         if (syntax != null)
         {
             Debug.Assert(!diagnostics.HasAnyErrors());
             formatSpecifiers = exprFormatSpecifiers;
             return(syntax);
         }
         formatSpecifiers = null;
         syntax           = expr.ParseStatement(diagnostics);
         if ((syntax != null) && (syntax.Kind() != SyntaxKind.LocalDeclarationStatement))
         {
             diagnostics.Add(ErrorCode.ERR_ExpressionOrDeclarationExpected, Location.None);
             return(null);
         }
         return(syntax);
     }
 }
Beispiel #7
0
        /// <summary>
        /// Parse expression. Returns null if there are any errors.
        /// </summary>
        internal static ExpressionSyntax ParseExpression(
            this string expr,
            DiagnosticBag diagnostics,
            bool allowFormatSpecifiers,
            out ReadOnlyCollection <string> formatSpecifiers)
        {
            // Remove trailing semi-colon if any. This is to support copy/paste
            // of (simple cases of) RHS of assignment in Watch window, not to
            // allow arbitrary syntax after the semi-colon, not even comments.
            if (RemoveSemicolonIfAny(ref expr))
            {
                // Format specifiers are not expected before a semi-colon.
                allowFormatSpecifiers = false;
            }

            var syntax = ParseDebuggerExpression(expr, consumeFullText: !allowFormatSpecifiers);

            diagnostics.AddRange(syntax.GetDiagnostics());
            formatSpecifiers = null;
            if (allowFormatSpecifiers)
            {
                var builder = ArrayBuilder <string> .GetInstance();

                if (ParseFormatSpecifiers(builder, expr, syntax.FullWidth, diagnostics) &&
                    (builder.Count > 0))
                {
                    formatSpecifiers = new ReadOnlyCollection <string>(builder.ToArray());
                }
                builder.Free();
            }
            return(diagnostics.HasAnyErrors() ? null : syntax);
        }
Beispiel #8
0
        internal static ExpressionSyntax ParseAssignment(
            this string target,
            string expr,
            DiagnosticBag diagnostics)
        {
            var text = SourceText.From(expr);
            var expression = SyntaxHelpers.ParseDebuggerExpressionInternal(text, consumeFullText: true);
            // We're creating a SyntaxTree for just the RHS so that the Diagnostic spans for parse errors
            // will be correct (with respect to the original input text).  If we ever expose a SemanticModel
            // for debugger expressions, we should use this SyntaxTree.
            var syntaxTree = expression.CreateSyntaxTree(text);
            diagnostics.AddRange(syntaxTree.GetDiagnostics());
            if (diagnostics.HasAnyErrors())
            {
                return null;
            }

            // Any Diagnostic spans produced in binding will be offset by the length of the "target" expression text.
            // If we want to support live squiggles in debugger windows, SemanticModel, etc, we'll want to address this.
            var targetSyntax = SyntaxHelpers.ParseDebuggerExpressionInternal(SourceText.From(target), consumeFullText: true);
            Debug.Assert(!targetSyntax.GetDiagnostics().Any(), "The target of an assignment should never contain Diagnostics if we're being allowed to assign to it in the debugger.");

            var assignment = InternalSyntax.SyntaxFactory.AssignmentExpression(
                SyntaxKind.SimpleAssignmentExpression,
                targetSyntax,
                InternalSyntax.SyntaxFactory.Token(SyntaxKind.EqualsToken),
                expression);
            return assignment.MakeDebuggerExpression(SourceText.From(assignment.ToString()));
        }
Beispiel #9
0
        private bool Test(int index)
        {
            bool           result            = false;
            string         inputFileName     = string.Format(@"..\..\InputFiles\xsd\Xsd{0:00}.Hello.xsd", index);
            string         expectedFileName  = string.Format(@"..\..\ExpectedFiles\soal\Xsd{0:00}.soal", index);
            string         outputFileName    = string.Format(@"..\..\OutputFiles\soal\Xsd{0:00}.Hello.soal", index);
            string         outputLogFileName = string.Format(@"..\..\OutputFiles\soal\Xsd{0:00}.Hello.log", index);
            string         outputDirectory   = string.Format(@"..\..\OutputFiles\soal", index);
            DiagnosticBag  diagnostics       = new DiagnosticBag();
            ImmutableModel model             = SoalImporter.Import(inputFileName, diagnostics);

            using (StreamWriter writer = new StreamWriter(outputLogFileName))
            {
                foreach (var msg in diagnostics.AsEnumerable())
                {
                    writer.WriteLine(msg);
                }
            }
            Assert.IsFalse(diagnostics.HasAnyErrors());
            Directory.CreateDirectory(outputDirectory);
            SoalPrinter printer    = new SoalPrinter(model.Symbols);
            string      outputSoal = printer.Generate();

            File.WriteAllText(outputFileName, outputSoal);
            string expectedSoal = null;

            using (StreamReader reader = new StreamReader(expectedFileName))
            {
                expectedSoal = reader.ReadToEnd();
            }
            Assert.AreEqual(expectedSoal, outputSoal);
            return(result);
        }
Beispiel #10
0
        internal static void BindFieldInitializers(
            SourceMemberContainerTypeSymbol typeSymbol,
            MethodSymbol scriptCtor,
            ImmutableArray <ImmutableArray <FieldInitializer> > fieldInitializers,
            bool generateDebugInfo,
            DiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers) //by ref so that we can store the results of lowering
        {
            DiagnosticBag diagsForInstanceInitializers = DiagnosticBag.GetInstance();

            try
            {
                ConsList <Imports> firstDebugImports;

                processedInitializers.BoundInitializers = BindFieldInitializers(typeSymbol, scriptCtor, fieldInitializers,
                                                                                diagsForInstanceInitializers, generateDebugInfo, out firstDebugImports);

                processedInitializers.HasErrors         = diagsForInstanceInitializers.HasAnyErrors();
                processedInitializers.FirstDebugImports = firstDebugImports;
            }
            finally
            {
                diagnostics.AddRange(diagsForInstanceInitializers);
                diagsForInstanceInitializers.Free();
            }
        }
Beispiel #11
0
        internal static ExpressionSyntax ParseAssignment(
            this string target,
            string expr,
            DiagnosticBag diagnostics)
        {
            var text       = SourceText.From(expr);
            var expression = SyntaxHelpers.ParseDebuggerExpressionInternal(text, consumeFullText: true);
            // We're creating a SyntaxTree for just the RHS so that the Diagnostic spans for parse errors
            // will be correct (with respect to the original input text).  If we ever expose a SemanticModel
            // for debugger expressions, we should use this SyntaxTree.
            var syntaxTree = expression.CreateSyntaxTree(text);

            diagnostics.AddRange(syntaxTree.GetDiagnostics());
            if (diagnostics.HasAnyErrors())
            {
                return(null);
            }

            // Any Diagnostic spans produced in binding will be offset by the length of the "target" expression text.
            // If we want to support live squiggles in debugger windows, SemanticModel, etc, we'll want to address this.
            var targetSyntax = SyntaxHelpers.ParseDebuggerExpressionInternal(SourceText.From(target), consumeFullText: true);

            Debug.Assert(!targetSyntax.GetDiagnostics().Any(), "The target of an assignment should never contain Diagnostics if we're being allowed to assign to it in the debugger.");

            var assignment = InternalSyntax.SyntaxFactory.AssignmentExpression(
                SyntaxKind.SimpleAssignmentExpression,
                targetSyntax,
                InternalSyntax.SyntaxFactory.Token(SyntaxKind.EqualsToken),
                expression);

            return(assignment.MakeDebuggerExpression(SourceText.From(assignment.ToString())));
        }
Beispiel #12
0
        internal static void BindFieldInitializers(
            SourceMemberContainerTypeSymbol typeSymbol,
            MethodSymbol scriptCtor,
            ImmutableArray <ImmutableArray <FieldOrPropertyInitializer> > fieldInitializers,
            DiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers) //by ref so that we can store the results of lowering
        {
            DiagnosticBag diagsForInstanceInitializers = DiagnosticBag.GetInstance();

            try
            {
                ImportChain firstImportChain;

                processedInitializers.BoundInitializers = BindFieldInitializers(typeSymbol, scriptCtor, fieldInitializers,
                                                                                diagsForInstanceInitializers, out firstImportChain);

                processedInitializers.HasErrors        = diagsForInstanceInitializers.HasAnyErrors();
                processedInitializers.FirstImportChain = firstImportChain;
            }
            finally
            {
                diagnostics.AddRange(diagsForInstanceInitializers);
                diagsForInstanceInitializers.Free();
            }
        }
Beispiel #13
0
        /// <returns>
        /// Returns true if all types and members we need are present and good
        /// </returns>
        protected bool VerifyPresenceOfRequiredAPIs()
        {
            DiagnosticBag bag = DiagnosticBag.GetInstance();

            EnsureSpecialType(SpecialType.System_Int32, bag);
            EnsureSpecialType(SpecialType.System_IDisposable, bag);
            EnsureSpecialMember(SpecialMember.System_IDisposable__Dispose, bag);

            // Iterator<T, TIterator>
            EnsureSpecialType(SpecialType.core_Iterable_T_TIterator, bag);
            EnsureSpecialMember(SpecialMember.core_Iterable_T_TIterator__iterate_begin, bag);
            EnsureSpecialMember(SpecialMember.core_Iterable_T_TIterator__iterate_has_current, bag);
            EnsureSpecialMember(SpecialMember.core_Iterable_T_TIterator__iterate_current, bag);
            EnsureSpecialMember(SpecialMember.core_Iterable_T_TIterator__iterate_next, bag);
            EnsureSpecialMember(SpecialMember.core_Iterable_T_TIterator__iterate_end, bag);

            // MutableIterator<T, TIterator>
            EnsureSpecialType(SpecialType.core_MutableIterable_T_TIterator, bag);
            EnsureSpecialMember(SpecialMember.core_MutableIterable_T_TIterator__iterate_current, bag);

            bool hasErrors = bag.HasAnyErrors();

            if (hasErrors)
            {
                diagnostics.AddRange(bag);
            }

            bag.Free();
            return(!hasErrors);
        }
Beispiel #14
0
        /// <summary>
        /// If the member is generic, construct it with the CrefTypeParameterSymbols that should be in scope.
        /// </summary>
        private Symbol ConstructWithCrefTypeParameters(int arity, TypeArgumentListSyntax typeArgumentListSyntax, Symbol symbol)
        {
            if (arity > 0)
            {
                SeparatedSyntaxList <TypeSyntax> typeArgumentSyntaxes = typeArgumentListSyntax.Arguments;
                TypeSymbol[] typeArgumentSymbols = new TypeSymbol[arity];

                DiagnosticBag unusedDiagnostics = DiagnosticBag.GetInstance();
                for (int i = 0; i < arity; i++)
                {
                    TypeSyntax typeArgumentSyntax = typeArgumentSyntaxes[i];

                    typeArgumentSymbols[i] = BindType(typeArgumentSyntax, unusedDiagnostics);

                    // Should be in a WithCrefTypeParametersBinder.
                    Debug.Assert(typeArgumentSyntax.ContainsDiagnostics || !typeArgumentSyntax.SyntaxTree.ReportDocumentationCommentDiagnostics() ||
                                 (!unusedDiagnostics.HasAnyErrors() && typeArgumentSymbols[i] is CrefTypeParameterSymbol));

                    unusedDiagnostics.Clear();
                }
                unusedDiagnostics.Free();

                if (symbol.Kind == SymbolKind.Method)
                {
                    symbol = ((MethodSymbol)symbol).Construct(typeArgumentSymbols);
                }
                else
                {
                    Debug.Assert(symbol is NamedTypeSymbol);
                    symbol = ((NamedTypeSymbol)symbol).Construct(typeArgumentSymbols);
                }
            }

            return(symbol);
        }
Beispiel #15
0
        internal override CompileResult CompileExpression(
            string expr,
            DkmEvaluationFlags compilationFlags,
            ImmutableArray <Alias> aliases,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            ReadOnlyCollection <string> formatSpecifiers;
            var syntax = Parse(expr, (compilationFlags & DkmEvaluationFlags.TreatAsExpression) != 0, diagnostics, out formatSpecifiers);

            if (syntax == null)
            {
                resultProperties = default(ResultProperties);
                return(null);
            }

            var context       = this.CreateCompilationContext();
            var moduleBuilder = context.CompileExpression(syntax, TypeName, MethodName, aliases, testData, diagnostics, out var synthesizedMethod);

            if (moduleBuilder == null)
            {
                resultProperties = default(ResultProperties);
                return(null);
            }

            using (var stream = new MemoryStream())
            {
                Cci.PeWriter.WritePeToStream(
                    new EmitContext(moduleBuilder, null, diagnostics, metadataOnly: false, includePrivateMembers: true),
                    context.MessageProvider,
                    () => stream,
                    getPortablePdbStreamOpt: null,
                    nativePdbWriterOpt: null,
                    pdbPathOpt: null,
                    metadataOnly: false,
                    isDeterministic: false,
                    emitTestCoverageData: false,
                    privateKeyOpt: null,
                    cancellationToken: default(CancellationToken));

                if (diagnostics.HasAnyErrors())
                {
                    resultProperties = default(ResultProperties);
                    return(null);
                }

                Debug.Assert(synthesizedMethod.ContainingType.MetadataName == TypeName);
                Debug.Assert(synthesizedMethod.MetadataName == MethodName);

                resultProperties = synthesizedMethod.ResultProperties;
                return(new CSharpCompileResult(
                           stream.ToArray(),
                           synthesizedMethod,
                           formatSpecifiers: formatSpecifiers));
            }
        }
Beispiel #16
0
        /// <summary>
        /// Builds a delegate that will execute just this scripts code.
        /// </summary>
        public Func <object[], object> Build(
            Script script,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            var compilation = script.GetCompilation();
            var options     = script.Options;

            DiagnosticBag emitDiagnostics = DiagnosticBag.GetInstance();

            byte[]     compiledAssemblyImage;
            MethodInfo entryPoint;

            bool success = compilation.Emit(
                GetOrCreateDynamicModule(options.IsCollectible),
                assemblyLoader: GetAssemblyLoader(options.IsCollectible),
                assemblySymbolMapper: symbol => MapAssemblySymbol(symbol, options.IsCollectible),
                recoverOnError: true,
                diagnostics: emitDiagnostics,
                cancellationToken: cancellationToken,
                entryPoint: out entryPoint,
                compiledAssemblyImage: out compiledAssemblyImage
                );

            if (diagnostics != null)
            {
                diagnostics.AddRange(emitDiagnostics);
            }

            bool hadEmitErrors = emitDiagnostics.HasAnyErrors();

            emitDiagnostics.Free();

            // emit can fail due to compilation errors or because there is nothing to emit:
            if (!success)
            {
                return(null);
            }

            Debug.Assert(entryPoint != null);

            if (compiledAssemblyImage != null)
            {
                // Ref.Emit wasn't able to emit the assembly
                _uncollectibleCodeManager.AddFallBackAssembly(entryPoint.DeclaringType.Assembly);
            }
#if DEBUG
            if (SaveCompiledAssemblies)
            {
                _uncollectibleCodeManager.Save(UncollectibleModuleFileName);
                _collectibleCodeManager.Save(CollectibleModuleFileName);
            }
#endif

            return((Func <object[], object>)Delegate.CreateDelegate(typeof(Func <object[], object>), entryPoint));
        }
Beispiel #17
0
        /// <summary>
        /// Builds a delegate that will execute just this scripts code.
        /// </summary>
        public Func <object[], object> Build(
            Script script,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            var compilation = script.GetCompilation();
            var options     = script.Options;

            DiagnosticBag emitDiagnostics = DiagnosticBag.GetInstance();

            byte[] compiledAssemblyImage;

            string entryPointTypeName;
            string entryPointMethodName;

            bool success = compilation.Emit(
                emitDiagnostics,
                out entryPointTypeName,
                out entryPointMethodName,
                out compiledAssemblyImage,
                cancellationToken);

            if (diagnostics != null)
            {
                diagnostics.AddRange(emitDiagnostics);
            }

            bool hadEmitErrors = emitDiagnostics.HasAnyErrors();

            emitDiagnostics.Free();

            // emit can fail due to compilation errors or because there is nothing to emit:
            if (!success)
            {
                return(null);
            }

            Debug.Assert(compiledAssemblyImage != null);

            // TODO: do not actually load the assemblies, only notify the loader of mapping from AssemblyIdentity to location.
            foreach (var referencedAssembly in compilation.GetBoundReferenceManager().GetReferencedAssemblies())
            {
                _uncollectibleCodeManager.Load(
                    identity: referencedAssembly.Value.Identity,
                    location: (referencedAssembly.Key as PortableExecutableReference)?.FilePath);
            }

            var assembly = Assembly.Load(compiledAssemblyImage);

            _uncollectibleCodeManager.AddFallBackAssembly(assembly);

            var entryPointType   = assembly.GetType(entryPointTypeName, throwOnError: true, ignoreCase: false).GetTypeInfo();
            var entryPointMethod = entryPointType.GetDeclaredMethod(entryPointMethodName);

            return(entryPointMethod.CreateDelegate <Func <object[], object> >());
        }
Beispiel #18
0
        private bool Test(int index)
        {
            bool   result            = false;
            string inputFileName     = string.Format(@"..\..\InputFiles\wsdl\Wsdl{0:00}.Hello.wsdl", index);
            string expectedFileName  = string.Format(@"..\..\ExpectedFiles\soal\Wsdl{0:00}.soal", index);
            string outputFileName    = string.Format(@"..\..\OutputFiles\soal\Wsdl{0:00}.Hello.soal", index);
            string outputLogFileName = string.Format(@"..\..\OutputFiles\soal\Wsdl{0:00}.Hello.log", index);
            string outputDirectory   = string.Format(@"..\..\OutputFiles\soal", index);

            Directory.CreateDirectory(outputDirectory);

            DiagnosticBag  diagnostics = new DiagnosticBag();
            ImmutableModel model       = SoalImporter.Import(inputFileName, diagnostics);

            using (StreamWriter writer = new StreamWriter(outputLogFileName))
            {
                foreach (var msg in diagnostics.AsEnumerable())
                {
                    writer.WriteLine(msg);
                }
            }
            Assert.IsFalse(diagnostics.HasAnyErrors());
            Directory.CreateDirectory(outputDirectory);
            SoalPrinter printer    = new SoalPrinter(model.Symbols);
            string      outputSoal = printer.Generate();

            File.WriteAllText(outputFileName, outputSoal);
            string expectedSoal = null;

            using (StreamReader reader = new StreamReader(expectedFileName))
            {
                expectedSoal = reader.ReadToEnd();
            }
            int firstDiff = -1;
            int line      = 1;
            int column    = 1;
            int max       = Math.Max(expectedSoal.Length, outputSoal.Length);

            for (int i = 0; i < max; i++)
            {
                if (expectedSoal[i] != outputSoal[i])
                {
                    firstDiff = i;
                    break;
                }
                ++column;
                if (expectedSoal[i] == '\n')
                {
                    ++line;
                    column = 1;
                }
            }
            Assert.AreEqual(expectedSoal, outputSoal);
            return(result);
        }
 internal override CommonCompilation CreateCompilation(IText code, string path, bool isInteractive, Session session, Type returnType, DiagnosticBag diagnostics)
 {
     Compilation previousSubmission = (Compilation) session.LastSubmission;
       IEnumerable<MetadataReference> referencesForCompilation = session.GetReferencesForCompilation();
       ReadOnlyArray<string> namespacesForCompilation = session.GetNamespacesForCompilation();
       ParseOptions options = isInteractive ? ScriptEngine.DefaultInteractive : ScriptEngine.DefaultScript;
       SyntaxTree syntaxTree = SyntaxTree.ParseText(code, path, options, new CancellationToken());
       diagnostics.Add((IEnumerable<CommonDiagnostic>) syntaxTree.GetDiagnostics(new CancellationToken()));
       if (diagnostics.HasAnyErrors())
     return (CommonCompilation) null;
       string assemblyName;
       string typeName;
       this.GenerateSubmissionId(out assemblyName, out typeName);
       Compilation submission = Compilation.CreateSubmission(assemblyName, new CompilationOptions(OutputKind.DynamicallyLinkedLibrary, (string) null, typeName, (IEnumerable<string>) namespacesForCompilation.ToList(), DebugInformationKind.None, false, true, false, true, (string) null, (string) null, new bool?(), 0, 0UL, Platform.AnyCPU, ReportWarning.Default, 4, (IReadOnlyDictionary<int, ReportWarning>) null, false, new SubsystemVersion()), syntaxTree, previousSubmission, referencesForCompilation, session.FileResolver, this.metadataFileProvider, returnType, session.HostObjectType);
       this.ValidateReferences((CommonCompilation) submission, diagnostics);
       if (diagnostics.HasAnyErrors())
     return (CommonCompilation) null;
       else
     return (CommonCompilation) submission;
 }
Beispiel #20
0
        internal override CompileResult CompileAssignment(
            string target,
            string expr,
            ImmutableArray <Alias> aliases,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            var assignment = target.ParseAssignment(expr, diagnostics);

            if (assignment == null)
            {
                resultProperties = default(ResultProperties);
                return(null);
            }

            var context       = this.CreateCompilationContext();
            var moduleBuilder = context.CompileAssignment(assignment, TypeName, MethodName, aliases, testData, diagnostics, out var synthesizedMethod);

            if (moduleBuilder == null)
            {
                resultProperties = default(ResultProperties);
                return(null);
            }

            using (var stream = new MemoryStream())
            {
                Cci.PeWriter.WritePeToStream(
                    new EmitContext(moduleBuilder, null, diagnostics),
                    context.MessageProvider,
                    () => stream,
                    getPortablePdbStreamOpt: null,
                    nativePdbWriterOpt: null,
                    pdbPathOpt: null,
                    allowMissingMethodBodies: false,
                    isDeterministic: false,
                    cancellationToken: default(CancellationToken));

                if (diagnostics.HasAnyErrors())
                {
                    resultProperties = default(ResultProperties);
                    return(null);
                }

                Debug.Assert(synthesizedMethod.ContainingType.MetadataName == TypeName);
                Debug.Assert(synthesizedMethod.MetadataName == MethodName);

                resultProperties = synthesizedMethod.ResultProperties;
                return(new CSharpCompileResult(
                           stream.ToArray(),
                           synthesizedMethod,
                           formatSpecifiers: null));
            }
        }
Beispiel #21
0
        internal override CompileResult CompileExpression(
            string expr,
            DkmEvaluationFlags compilationFlags,
            ImmutableArray <Alias> aliases,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            ReadOnlyCollection <string> formatSpecifiers;
            var syntax = Parse(expr, (compilationFlags & DkmEvaluationFlags.TreatAsExpression) != 0, diagnostics, out formatSpecifiers);

            if (syntax == null)
            {
                resultProperties = default(ResultProperties);
                return(null);
            }

            var context = this.CreateCompilationContext(syntax);
            ResultProperties properties;
            var moduleBuilder = context.CompileExpression(TypeName, MethodName, aliases, testData, diagnostics, out properties);

            if (moduleBuilder == null)
            {
                resultProperties = default(ResultProperties);
                return(null);
            }

            using (var stream = new MemoryStream())
            {
                Cci.PeWriter.WritePeToStream(
                    new EmitContext((Cci.IModule)moduleBuilder, null, diagnostics),
                    context.MessageProvider,
                    () => stream,
                    getPortablePdbStreamOpt: null,
                    nativePdbWriterOpt: null,
                    pdbPathOpt: null,
                    allowMissingMethodBodies: false,
                    deterministic: false,
                    cancellationToken: default(CancellationToken));

                if (diagnostics.HasAnyErrors())
                {
                    resultProperties = default(ResultProperties);
                    return(null);
                }

                resultProperties = properties;
                return(new CSharpCompileResult(
                           stream.ToArray(),
                           GetSynthesizedMethod(moduleBuilder),
                           formatSpecifiers: formatSpecifiers));
            }
        }
Beispiel #22
0
 public bool Validate(DiagnosticBag diagnostics, CancellationToken cancellationToken = default)
 {
     foreach (var obj in this.Objects)
     {
         if (cancellationToken.IsCancellationRequested)
         {
             return(false);
         }
         obj.MValidate(diagnostics, cancellationToken);
     }
     return(!diagnostics.HasAnyErrors());
 }
Beispiel #23
0
        public static void Run(
            MethodSymbol meth, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints,
            out int asyncCatchHandlerOffset, out ImmutableArray <int> asyncYieldPoints, out ImmutableArray <int> asyncResumePoints)
        {
            CodeGenerator generator = new CodeGenerator(meth, block, builder, module, diagnostics, optimize, emitSequencePoints);

            generator.Generate();

            if (!diagnostics.HasAnyErrors())
            {
                builder.Realize();
            }

            asyncCatchHandlerOffset = (generator.asyncCatchHandlerOffset < 0)
                ? -1
                : generator.builder.GetILOffsetFromMarker(generator.asyncCatchHandlerOffset);

            ArrayBuilder <int> yieldPoints  = generator.asyncYieldPoints;
            ArrayBuilder <int> resumePoints = generator.asyncResumePoints;

            if (yieldPoints == null)
            {
                asyncYieldPoints  = ImmutableArray <int> .Empty;
                asyncResumePoints = ImmutableArray <int> .Empty;
            }
            else
            {
                var yieldPointBuilder = ArrayBuilder <int> .GetInstance();

                var resumePointBuilder = ArrayBuilder <int> .GetInstance();

                int n = yieldPoints.Count;
                for (int i = 0; i < n; i++)
                {
                    int yieldOffset  = generator.builder.GetILOffsetFromMarker(yieldPoints[i]);
                    int resumeOffset = generator.builder.GetILOffsetFromMarker(resumePoints[i]);
                    Debug.Assert(resumeOffset >= 0); // resume marker should always be reachable from dispatch

                    // yield point may not be reachable if the whole
                    // await is not reachable; we just ignore such awaits
                    if (yieldOffset > 0)
                    {
                        yieldPointBuilder.Add(yieldOffset);
                        resumePointBuilder.Add(resumeOffset);
                    }
                }

                asyncYieldPoints  = yieldPointBuilder.ToImmutableAndFree();
                asyncResumePoints = resumePointBuilder.ToImmutableAndFree();
                yieldPoints.Free();
                resumePoints.Free();
            }
        }
Beispiel #24
0
        internal override CompileResult CompileAssignment(
            InspectionContext inspectionContext,
            string target,
            string expr,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            var assignment = target.ParseAssignment(expr, diagnostics);

            if (assignment == null)
            {
                resultProperties = default(ResultProperties);
                return(default(CompileResult));
            }

            var context = this.CreateCompilationContext(assignment);
            ResultProperties properties;
            var moduleBuilder = context.CompileAssignment(inspectionContext, TypeName, MethodName, testData, diagnostics, out properties);

            if (moduleBuilder == null)
            {
                resultProperties = default(ResultProperties);
                return(default(CompileResult));
            }

            using (var stream = new MemoryStream())
            {
                Cci.PeWriter.WritePeToStream(
                    new EmitContext((Cci.IModule)moduleBuilder, null, diagnostics),
                    context.MessageProvider,
                    () => stream,
                    nativePdbWriterOpt: null,
                    pdbPathOpt: null,
                    allowMissingMethodBodies: false,
                    deterministic: false,
                    cancellationToken: default(CancellationToken));

                if (diagnostics.HasAnyErrors())
                {
                    resultProperties = default(ResultProperties);
                    return(default(CompileResult));
                }

                resultProperties = properties;
                return(new CompileResult(
                           stream.ToArray(),
                           typeName: TypeName,
                           methodName: MethodName,
                           formatSpecifiers: null));
            }
        }
Beispiel #25
0
        public static void Run(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints)
        {
            CodeGenerator generator = new CodeGenerator(method, block, builder, module, diagnostics, optimize, emitSequencePoints);

            generator.Generate();
            Debug.Assert(generator.asyncCatchHandlerOffset < 0);
            Debug.Assert(generator.asyncYieldPoints == null);
            Debug.Assert(generator.asyncResumePoints == null);

            if (!diagnostics.HasAnyErrors())
            {
                builder.Realize();
            }
        }
Beispiel #26
0
        /// <returns>
        /// Returns true if all types and members we need are present and good
        /// </returns>
        protected bool VerifyPresenceOfRequiredAPIs()
        {
            DiagnosticBag bag = DiagnosticBag.GetInstance();

            VerifyPresenceOfRequiredAPIs(bag);

            bool hasErrors = bag.HasAnyErrors();

            if (hasErrors)
            {
                diagnostics.AddRange(bag);
            }

            bag.Free();
            return(!hasErrors && _constructedSuccessfully);
        }
Beispiel #27
0
        /// <returns>
        /// Returns true if all types and members we need are present and good
        /// </returns>
        protected bool VerifyPresenceOfRequiredAPIs()
        {
            DiagnosticBag bag = DiagnosticBag.GetInstance();

            EnsureWellKnownMember(WellKnownMember.System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext, bag);
            EnsureWellKnownMember(WellKnownMember.System_Runtime_CompilerServices_IAsyncStateMachine_SetStateMachine, bag);

            bool hasErrors = bag.HasAnyErrors();

            if (hasErrors)
            {
                diagnostics.AddRange(bag);
            }

            bag.Free();
            return(!hasErrors && _constructedSuccessfully);
        }
Beispiel #28
0
        internal override ReadOnlyCollection <byte> CompileGetLocals(
            ArrayBuilder <LocalAndMethod> locals,
            bool argumentsOnly,
            ImmutableArray <Alias> aliases,
            DiagnosticBag diagnostics,
            out string typeName,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            var context       = this.CreateCompilationContext();
            var moduleBuilder = context.CompileGetLocals(TypeName, locals, argumentsOnly, aliases, testData, diagnostics);
            ReadOnlyCollection <byte> assembly = null;

            if ((moduleBuilder != null) && (locals.Count > 0))
            {
                using (var stream = new MemoryStream())
                {
                    Cci.PeWriter.WritePeToStream(
                        new EmitContext(moduleBuilder, null, diagnostics, metadataOnly: false, includePrivateMembers: true),
                        context.MessageProvider,
                        () => stream,
                        getPortablePdbStreamOpt: null,
                        nativePdbWriterOpt: null,
                        pdbPathOpt: null,
                        metadataOnly: false,
                        isDeterministic: false,
                        emitTestCoverageData: false,
                        privateKeyOpt: null,
                        cancellationToken: default(CancellationToken));

                    if (!diagnostics.HasAnyErrors())
                    {
                        assembly = new ReadOnlyCollection <byte>(stream.ToArray());
                    }
                }
            }

            if (assembly == null)
            {
                locals.Clear();
                assembly = s_emptyBytes;
            }

            typeName = TypeName;
            return(assembly);
        }
Beispiel #29
0
        private void CompileGeneratedMethods(ImmutableArray <NamedTypeSymbol> additionalTypes, DiagnosticBag diagnostics)
        {
            TypeCompilationState compilationState = new TypeCompilationState(null, moduleBeingBuilt);

            foreach (var type in additionalTypes)
            {
                foreach (var method in type.GetMethodsToEmit())
                {
                    method.GenerateMethodBody(compilationState, diagnostics);
                }
            }

            if (!diagnostics.HasAnyErrors())
            {
                CompileGeneratedMethods(compilationState);
            }
            compilationState.Free();
        }
Beispiel #30
0
        internal override ReadOnlyCollection <byte> CompileGetLocals(
            ReadOnlyCollection <Alias> aliases,
            ArrayBuilder <LocalAndMethod> locals,
            bool argumentsOnly,
            DiagnosticBag diagnostics,
            out string typeName,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            var context       = this.CreateCompilationContext(null);
            var moduleBuilder = context.CompileGetLocals(aliases, TypeName, locals, argumentsOnly, testData, diagnostics);
            ReadOnlyCollection <byte> assembly = null;

            if ((moduleBuilder != null) && (locals.Count > 0))
            {
                using (var stream = new MemoryStream())
                {
                    Cci.PeWriter.WritePeToStream(
                        new EmitContext((Cci.IModule)moduleBuilder, null, diagnostics),
                        context.MessageProvider,
                        () => stream,
                        nativePdbWriterOpt: null,
                        pdbPathOpt: null,
                        allowMissingMethodBodies: false,
                        deterministic: false,
                        cancellationToken: default(CancellationToken));

                    if (!diagnostics.HasAnyErrors())
                    {
                        assembly = new ReadOnlyCollection <byte>(stream.ToArray());
                    }
                }
            }

            if (assembly == null)
            {
                locals.Clear();
                assembly = s_emptyBytes;
            }

            typeName = TypeName;
            return(assembly);
        }
Beispiel #31
0
        protected BoundStatement Rewrite()
        {
            if (this.body.HasErrors)
            {
                return(this.body);
            }

            F.OpenNestedType(stateMachineType);

            GenerateControlFields();

            if (PreserveInitialParameterValuesAndThreadId && CanGetThreadId())
            {
                // if it is an enumerable or async-enumerable, and either Environment.CurrentManagedThreadId or Thread.ManagedThreadId are available
                // add a field: int initialThreadId
                initialThreadIdField = F.StateMachineField(F.SpecialType(SpecialType.System_Int32), GeneratedNames.MakeIteratorCurrentThreadIdFieldName());
            }

            // fields for the initial values of all the parameters of the method
            if (PreserveInitialParameterValuesAndThreadId)
            {
                initialParameters = new Dictionary <Symbol, CapturedSymbolReplacement>();
            }

            // fields for the captured variables of the method
            var variablesToHoist = IteratorAndAsyncCaptureWalker.Analyze(F.Compilation, method, body, diagnostics);

            if (diagnostics.HasAnyErrors())
            {
                // Avoid triggering assertions in further lowering.
                return(new BoundBadStatement(F.Syntax, ImmutableArray <BoundNode> .Empty, hasErrors: true));
            }

            CreateNonReusableLocalProxies(variablesToHoist, out this.nonReusableLocalProxies, out this.nextFreeHoistedLocalSlot);

            this.hoistedVariables = variablesToHoist;

            GenerateMethodImplementations();

            // Return a replacement body for the kickoff method
            return(GenerateKickoffMethodBody());
        }
Beispiel #32
0
        private static BoundExpression ConvertToLocalTypeHelper(CSharpCompilation compilation, BoundExpression expr, TypeSymbol type, DiagnosticBag diagnostics)
        {
            // NOTE: This conversion can fail if some of the types involved are from not-yet-loaded modules.
            // For example, if System.Exception hasn't been loaded, then this call will fail for $stowedexception.
            HashSet <DiagnosticInfo> useSiteDiagnostics = null;
            var conversion = compilation.Conversions.ClassifyConversionFromExpression(expr, type, ref useSiteDiagnostics);

            diagnostics.Add(expr.Syntax, useSiteDiagnostics);
            Debug.Assert(conversion.IsValid || diagnostics.HasAnyErrors());

            return(BoundConversion.Synthesized(
                       expr.Syntax,
                       expr,
                       conversion,
                       @checked: false,
                       explicitCastInCode: false,
                       constantValueOpt: null,
                       type: type,
                       hasErrors: !conversion.IsValid));
        }
Beispiel #33
0
        /// <remarks>
        /// Keep in sync with <see cref="M:SemanticModel.GetSpeculativelyBoundExpression()"/>.
        /// </remarks>
        private TypeSymbol BindCrefParameterOrReturnType(TypeSyntax typeSyntax, MemberCrefSyntax memberCrefSyntax, DiagnosticBag diagnostics)
        {
            DiagnosticBag unusedDiagnostics = DiagnosticBag.GetInstance(); // Examined, but not reported.

            // After much deliberation, we eventually decided to suppress lookup of inherited members within
            // crefs, in order to match dev11's behavior (Changeset #829014).  Unfortunately, it turns out
            // that dev11 does not suppress these members when performing lookup within parameter and return
            // types, within crefs (DevDiv #586815, #598371).
            Debug.Assert(InCrefButNotParameterOrReturnType);
            Binder parameterOrReturnTypeBinder = this.WithAdditionalFlags(BinderFlags.CrefParameterOrReturnType);

            // It would be nice to pull this binder out of the factory so we wouldn't have to worry about them getting out
            // of sync, but this code is also used for included crefs, which don't have BinderFactories.
            // As a compromise, we'll assert that the binding locations match in scenarios where we can go through the factory.
            Debug.Assert(!this.Compilation.ContainsSyntaxTree(typeSyntax.SyntaxTree) ||
                         this.Compilation.GetBinderFactory(typeSyntax.SyntaxTree).GetBinder(typeSyntax).Flags ==
                         (parameterOrReturnTypeBinder.Flags & ~BinderFlags.SemanticModel));

            TypeSymbol type = parameterOrReturnTypeBinder.BindType(typeSyntax, unusedDiagnostics);

            if (unusedDiagnostics.HasAnyErrors())
            {
                if (HasNonObsoleteError(unusedDiagnostics))
                {
                    ErrorCode code = typeSyntax.Parent.Kind == SyntaxKind.ConversionOperatorMemberCref
                        ? ErrorCode.WRN_BadXMLRefReturnType
                        : ErrorCode.WRN_BadXMLRefParamType;
                    CrefSyntax crefSyntax = GetRootCrefSyntax(memberCrefSyntax);
                    diagnostics.Add(code, crefSyntax.Location, typeSyntax.ToString(), crefSyntax.ToString());
                }
            }
            else
            {
                Debug.Assert(type.TypeKind != TypeKind.Error || typeSyntax.ContainsDiagnostics || !typeSyntax.SyntaxTree.ReportDocumentationCommentDiagnostics(), "Why wasn't there a diagnostic?");
            }

            unusedDiagnostics.Free();

            return(type);
        }
Beispiel #34
0
        /// <summary>
        /// Generate a class containing methods that represent
        /// the set of arguments and locals at the current scope.
        /// </summary>
        internal CommonPEModuleBuilder CompileGetLocals(
            string typeName,
            ArrayBuilder<LocalAndMethod> localBuilder,
            bool argumentsOnly,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics)
        {
            var objectType = this.Compilation.GetSpecialType(SpecialType.System_Object);
            var allTypeParameters = _currentFrame.GetAllTypeParameters();
            var additionalTypes = ArrayBuilder<NamedTypeSymbol>.GetInstance();

            EENamedTypeSymbol typeVariablesType = null;
            if (!argumentsOnly && (allTypeParameters.Length > 0))
            {
                // Generate a generic type with matching type parameters.
                // A null instance of the type will be used to represent the
                // "Type variables" local.
                typeVariablesType = new EENamedTypeSymbol(
                    this.Compilation.SourceModule.GlobalNamespace,
                    objectType,
                    _syntax,
                    _currentFrame,
                    ExpressionCompilerConstants.TypeVariablesClassName,
                    (m, t) => ImmutableArray.Create<MethodSymbol>(new EEConstructorSymbol(t)),
                    allTypeParameters,
                    (t1, t2) => allTypeParameters.SelectAsArray((tp, i, t) => (TypeParameterSymbol)new SimpleTypeParameterSymbol(t, i, tp.Name), t2));
                additionalTypes.Add(typeVariablesType);
            }

            var synthesizedType = new EENamedTypeSymbol(
                this.Compilation.SourceModule.GlobalNamespace,
                objectType,
                _syntax,
                _currentFrame,
                typeName,
                (m, container) =>
                {
                    var methodBuilder = ArrayBuilder<MethodSymbol>.GetInstance();

                    if (!argumentsOnly)
                    {
                        // "this" for non-static methods that are not display class methods or
                        // display class methods where the display class contains "<>4__this".
                        if (!m.IsStatic && (!IsDisplayClassType(m.ContainingType) || _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName())))
                        {
                            var methodName = GetNextMethodName(methodBuilder);
                            var method = this.GetThisMethod(container, methodName);
                            localBuilder.Add(new LocalAndMethod("this", methodName, DkmClrCompilationResultFlags.None)); // Note: writable in dev11.
                            methodBuilder.Add(method);
                        }
                    }

                    // Hoisted method parameters (represented as locals in the EE).
                    int ordinal = 0;
                    if (!_hoistedParameterNames.IsEmpty)
                    {
                        foreach (var local in _localsForBinding)
                        {
                            // Since we are showing hoisted method parameters first, the parameters may appear out of order
                            // in the Locals window if only some of the parameters are hoisted.  This is consistent with the
                            // behavior of the old EE.
                            var localName = local.Name;
                            if (_hoistedParameterNames.Contains(local.Name))
                            {
                                AppendLocalAndMethod(localBuilder, methodBuilder, localName, this.GetLocalMethod, container, ordinal, GetLocalResultFlags(local));
                            }
                            ordinal++;
                        }
                    }

                    // Method parameters (except those that have been hoisted).
                    ordinal = m.IsStatic ? 0 : 1;
                    foreach (var parameter in m.Parameters)
                    {
                        var parameterName = parameter.Name;
                        if (!_hoistedParameterNames.Contains(parameterName))
                        {
                            AppendLocalAndMethod(localBuilder, methodBuilder, parameterName, this.GetParameterMethod, container, ordinal, DkmClrCompilationResultFlags.None);
                        }
                        ordinal++;
                    }

                    if (!argumentsOnly)
                    {
                        // Locals.
                        ordinal = 0;
                        foreach (var local in _localsForBinding)
                        {
                            var localName = local.Name;
                            if (!_hoistedParameterNames.Contains(localName))
                            {
                                AppendLocalAndMethod(localBuilder, methodBuilder, localName, this.GetLocalMethod, container, ordinal, GetLocalResultFlags(local));
                            }
                            ordinal++;
                        }

                        // "Type variables".
                        if ((object)typeVariablesType != null)
                        {
                            var methodName = GetNextMethodName(methodBuilder);
                            var returnType = typeVariablesType.Construct(allTypeParameters.Cast<TypeParameterSymbol, TypeSymbol>());
                            var method = this.GetTypeVariablesMethod(container, methodName, returnType);
                            localBuilder.Add(new LocalAndMethod(ExpressionCompilerConstants.TypeVariablesLocalName, methodName, DkmClrCompilationResultFlags.ReadOnlyResult));
                            methodBuilder.Add(method);
                        }
                    }

                    return methodBuilder.ToImmutableAndFree();
                });

            additionalTypes.Add(synthesizedType);

            var module = CreateModuleBuilder(
                this.Compilation,
                synthesizedType.Methods,
                additionalTypes: additionalTypes.ToImmutableAndFree(),
                testData: testData,
                diagnostics: diagnostics);

            Debug.Assert(module != null);

            this.Compilation.Compile(
                module,
                win32Resources: null,
                xmlDocStream: null,
                generateDebugInfo: false,
                diagnostics: diagnostics,
                filterOpt: null,
                cancellationToken: CancellationToken.None);

            return diagnostics.HasAnyErrors() ? null : module;
        }
        internal static MethodSymbol DefineScriptEntryPoint(CSharpCompilation compilation, PEModuleBuilder moduleBeingBuilt, TypeSymbol returnType, bool hasDeclarationErrors, DiagnosticBag diagnostics)
        {
            var scriptEntryPoint = new SynthesizedEntryPointSymbol(compilation.ScriptClass, returnType, diagnostics);
            if (moduleBeingBuilt != null && !hasDeclarationErrors && !diagnostics.HasAnyErrors())
            {
                var compilationState = new TypeCompilationState(compilation.ScriptClass, moduleBeingBuilt);
                var body = scriptEntryPoint.CreateBody();

                var emittedBody = GenerateMethodBody(
                    compilationState,
                    scriptEntryPoint,
                    body,
                    diagnostics,
                    compilation.Options.Optimize,
                    debugDocumentProvider: null,
                    namespaceScopes: default(ImmutableArray<NamespaceScope>));

                moduleBeingBuilt.SetMethodBody(scriptEntryPoint, emittedBody);
                moduleBeingBuilt.AddCompilerGeneratedDefinition(compilation.ScriptClass, scriptEntryPoint);
            }

            return scriptEntryPoint;
        }
        internal static MethodBody GenerateMethodBody(TypeCompilationState compilationState, MethodSymbol method, BoundStatement block, DiagnosticBag diagnostics,
            bool optimize, DebugDocumentProvider debugDocumentProvider, ImmutableArray<NamespaceScope> namespaceScopes)
        {
            // Note: don't call diagnostics.HasAnyErrors() in release; could be expensive if compilation has many warnings.
            Debug.Assert(!diagnostics.HasAnyErrors(), "Running code generator when errors exist might be dangerous; code generator not well hardened");

            bool emitSequencePoints = !namespaceScopes.IsDefault && !method.IsAsync;
            var module = compilationState.ModuleBuilder;
            var compilation = module.Compilation;
            var localSlotManager = module.CreateLocalSlotManager(method);

            ILBuilder builder = new ILBuilder(module, localSlotManager, optimize);
            DiagnosticBag diagnosticsForThisMethod = DiagnosticBag.GetInstance();
            try
            {
                AsyncMethodBodyDebugInfo asyncDebugInfo = null;
                if ((object)method.AsyncKickoffMethod == null) // is this the MoveNext of an async method?
                {
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints);
                }
                else
                {
                    int asyncCatchHandlerOffset;
                    ImmutableArray<int> asyncYieldPoints;
                    ImmutableArray<int> asyncResumePoints;
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints,
                        out asyncCatchHandlerOffset, out asyncYieldPoints, out asyncResumePoints);
                    asyncDebugInfo = new AsyncMethodBodyDebugInfo(method.AsyncKickoffMethod, asyncCatchHandlerOffset, asyncYieldPoints, asyncResumePoints);
                }

                var localVariables = builder.LocalSlotManager.LocalsInOrder();

                if (localVariables.Length > 0xFFFE)
                {
                    diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First());
                }

                if (diagnosticsForThisMethod.HasAnyErrors())
                {
                    // we are done here. Since there were errors we should not emit anything.
                    return null;
                }

                // We will only save the IL builders when running tests.
                if (module.SaveTestData)
                {
                    module.SetMethodTestData(method, builder.GetSnapshot());
                }

                // Only compiler-generated MoveNext methods have iterator scopes.  See if this is one.
                bool hasIteratorScopes =
                    method.Locations.IsEmpty && method.Name == "MoveNext" &&
                    (method.ExplicitInterfaceImplementations.Contains(compilation.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__MoveNext) as MethodSymbol) ||
                     method.ExplicitInterfaceImplementations.Contains(compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext) as MethodSymbol));

                var iteratorScopes = hasIteratorScopes ? builder.GetIteratorScopes() : ImmutableArray<LocalScope>.Empty;

                var iteratorOrAsyncImplementation = compilationState.GetIteratorOrAsyncImplementationClass(method);
                return new MethodBody(
                    builder.RealizedIL,
                    builder.MaxStack,
                    method,
                    localVariables,
                    builder.RealizedSequencePoints,
                    debugDocumentProvider,
                    builder.RealizedExceptionHandlers,
                    builder.GetAllScopes(),
                    Microsoft.Cci.CustomDebugInfoKind.CSharpStyle,
                    builder.HasDynamicLocal,
                    namespaceScopes,
                    (object)iteratorOrAsyncImplementation == null ? null : iteratorOrAsyncImplementation.MetadataName,
                    iteratorScopes,
                    asyncMethodDebugInfo: asyncDebugInfo
                );
            }
            finally
            {
                // Basic blocks contain poolable builders for IL and sequence points. Free those back
                // to their pools.
                builder.FreeBasicBlocks();

                // Remember diagnostics.
                diagnostics.AddRange(diagnosticsForThisMethod);
                diagnosticsForThisMethod.Free();
            }
        }
Beispiel #37
0
        internal override CompileResult CompileExpression(
            string expr,
            DkmEvaluationFlags compilationFlags,
            ImmutableArray<Alias> aliases,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            ReadOnlyCollection<string> formatSpecifiers;
            var syntax = Parse(expr, (compilationFlags & DkmEvaluationFlags.TreatAsExpression) != 0, diagnostics, out formatSpecifiers);
            if (syntax == null)
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            var context = this.CreateCompilationContext(syntax);
            ResultProperties properties;
            var moduleBuilder = context.CompileExpression(TypeName, MethodName, aliases, testData, diagnostics, out properties);
            if (moduleBuilder == null)
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            using (var stream = new MemoryStream())
            {
                Cci.PeWriter.WritePeToStream(
                    new EmitContext((Cci.IModule)moduleBuilder, null, diagnostics),
                    context.MessageProvider,
                    () => stream,
                    getPortablePdbStreamOpt: null,
                    nativePdbWriterOpt: null,
                    pdbPathOpt: null,
                    allowMissingMethodBodies: false,
                    deterministic: false,
                    cancellationToken: default(CancellationToken));

                if (diagnostics.HasAnyErrors())
                {
                    resultProperties = default(ResultProperties);
                    return null;
                }

                resultProperties = properties;
                return new CSharpCompileResult(
                    stream.ToArray(),
                    GetSynthesizedMethod(moduleBuilder),
                    formatSpecifiers: formatSpecifiers);
            }
        }
        internal CommonPEModuleBuilder CompileExpression(
            InspectionContext inspectionContext,
            string typeName,
            string methodName,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties)
        {
            Debug.Assert(inspectionContext != null);

            var properties = default(ResultProperties);
            var objectType = this.Compilation.GetSpecialType(SpecialType.System_Object);
            var synthesizedType = new EENamedTypeSymbol(
                this.Compilation.SourceModule.GlobalNamespace,
                objectType,
                _syntax,
                _currentFrame,
                typeName,
                methodName,
                this,
                (method, diags) =>
                {
                    var hasDisplayClassThis = _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName());
                    var binder = ExtendBinderChain(
                        inspectionContext,
                        this.Compilation,
                        _metadataDecoder,
                        _syntax,
                        method,
                        this.NamespaceBinder,
                        hasDisplayClassThis,
                        _methodNotType);
                    var statementSyntax = _syntax as StatementSyntax;
                    return (statementSyntax == null) ?
                        BindExpression(binder, (ExpressionSyntax)_syntax, diags, out properties) :
                        BindStatement(binder, statementSyntax, diags, out properties);
                });

            var module = CreateModuleBuilder(
                this.Compilation,
                synthesizedType.Methods,
                additionalTypes: ImmutableArray.Create((NamedTypeSymbol)synthesizedType),
                testData: testData,
                diagnostics: diagnostics);

            Debug.Assert(module != null);

            this.Compilation.Compile(
                module,
                win32Resources: null,
                xmlDocStream: null,
                generateDebugInfo: false,
                diagnostics: diagnostics,
                filterOpt: null,
                cancellationToken: CancellationToken.None);

            if (diagnostics.HasAnyErrors())
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            // Should be no name mangling since the caller provided explicit names.
            Debug.Assert(synthesizedType.MetadataName == typeName);
            Debug.Assert(synthesizedType.GetMembers()[0].MetadataName == methodName);

            resultProperties = properties;
            return module;
        }
Beispiel #39
0
        internal CommonPEModuleBuilder CompileAssignment(
            string typeName,
            string methodName,
            ImmutableArray<Alias> aliases,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties)
        {
            var objectType = this.Compilation.GetSpecialType(SpecialType.System_Object);
            var synthesizedType = new EENamedTypeSymbol(
                Compilation.SourceModule.GlobalNamespace,
                objectType,
                _syntax,
                _currentFrame,
                typeName,
                methodName,
                this,
                (method, diags) =>
                {
                    var hasDisplayClassThis = _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName());
                    var binder = ExtendBinderChain(
                        _syntax,
                        aliases,
                        method,
                        this.NamespaceBinder,
                        hasDisplayClassThis,
                        methodNotType: true);
                    return BindAssignment(binder, (ExpressionSyntax)_syntax, diags);
                });

            var module = CreateModuleBuilder(
                this.Compilation,
                synthesizedType.Methods,
                additionalTypes: ImmutableArray.Create((NamedTypeSymbol)synthesizedType),
                synthesizedType: synthesizedType,
                testData: testData,
                diagnostics: diagnostics);

            Debug.Assert(module != null);

            this.Compilation.Compile(
                module,
                win32Resources: null,
                xmlDocStream: null,
                emittingPdb: false,
                diagnostics: diagnostics,
                filterOpt: null,
                cancellationToken: CancellationToken.None);

            if (diagnostics.HasAnyErrors())
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            // Should be no name mangling since the caller provided explicit names.
            Debug.Assert(synthesizedType.MetadataName == typeName);
            Debug.Assert(synthesizedType.GetMembers()[0].MetadataName == methodName);

            resultProperties = new ResultProperties(DkmClrCompilationResultFlags.PotentialSideEffect);
            return module;
        }
        internal override CompileResult CompileAssignment(
            InspectionContext inspectionContext,
            string target,
            string expr,
            DiagnosticBag diagnostics,
            out ResultProperties resultProperties,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            var assignment = target.ParseAssignment(expr, diagnostics);
            if (assignment == null)
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            var context = this.CreateCompilationContext(assignment);
            ResultProperties properties;
            var moduleBuilder = context.CompileAssignment(inspectionContext, TypeName, MethodName, testData, diagnostics, out properties);
            if (moduleBuilder == null)
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            using (var stream = new MemoryStream())
            {
                Cci.PeWriter.WritePeToStream(
                    new EmitContext((Cci.IModule)moduleBuilder, null, diagnostics),
                    context.MessageProvider,
                    () => stream,
                    nativePdbWriterOpt: null,
                    pdbPathOpt: null,
                    allowMissingMethodBodies: false,
                    deterministic: false,
                    cancellationToken: default(CancellationToken));

                if (diagnostics.HasAnyErrors())
                {
                    resultProperties = default(ResultProperties);
                    return null;
                }

                resultProperties = properties;
                return new CSharpCompileResult(
                    stream.ToArray(),
                    GetSynthesizedMethod(moduleBuilder),
                    formatSpecifiers: null);
            }
        }
Beispiel #41
0
        public static void Run(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints)
        {
            CodeGenerator generator = new CodeGenerator(method, block, builder, module, diagnostics, optimize, emitSequencePoints);
            generator.Generate();
            Debug.Assert(generator.asyncCatchHandlerOffset < 0);
            Debug.Assert(generator.asyncYieldPoints == null);
            Debug.Assert(generator.asyncResumePoints == null);

            if (!diagnostics.HasAnyErrors())
            {
                builder.Realize();
            }
        }
Beispiel #42
0
 /// <summary>
 /// Parse statement. Returns null if there are any errors.
 /// </summary>
 internal static StatementSyntax ParseStatement(
     this string expr,
     DiagnosticBag diagnostics)
 {
     var syntax = ParseDebuggerStatement(expr);
     diagnostics.AddRange(syntax.GetDiagnostics());
     return diagnostics.HasAnyErrors() ? null : syntax;
 }
Beispiel #43
0
        private static BoundStatement BindAssignment(Binder binder, ExpressionSyntax syntax, DiagnosticBag diagnostics)
        {
            var expression = binder.BindValue(syntax, diagnostics, Binder.BindValueKind.RValue);
            if (diagnostics.HasAnyErrors())
            {
                return null;
            }

            return new BoundExpressionStatement(expression.Syntax, expression) { WasCompilerGenerated = true };
        }
Beispiel #44
0
        private static BoundStatement BindExpression(Binder binder, ExpressionSyntax syntax, DiagnosticBag diagnostics, out ResultProperties resultProperties)
        {
            var flags = DkmClrCompilationResultFlags.None;

            // In addition to C# expressions, the native EE also supports
            // type names which are bound to a representation of the type
            // (but not System.Type) that the user can expand to see the
            // base type. Instead, we only allow valid C# expressions.
            var expression = binder.BindValue(syntax, diagnostics, Binder.BindValueKind.RValue);
            if (diagnostics.HasAnyErrors())
            {
                resultProperties = default(ResultProperties);
                return null;
            }

            try
            {
                if (MayHaveSideEffectsVisitor.MayHaveSideEffects(expression))
                {
                    flags |= DkmClrCompilationResultFlags.PotentialSideEffect;
                }
            }
            catch (BoundTreeVisitor.CancelledByStackGuardException ex)
            {
                ex.AddAnError(diagnostics);
                resultProperties = default(ResultProperties);
                return null;
            }

            var expressionType = expression.Type;
            if ((object)expressionType == null)
            {
                expression = binder.CreateReturnConversion(
                    syntax,
                    diagnostics,
                    expression,
                    binder.Compilation.GetSpecialType(SpecialType.System_Object));
                if (diagnostics.HasAnyErrors())
                {
                    resultProperties = default(ResultProperties);
                    return null;
                }
            }
            else if (expressionType.SpecialType == SpecialType.System_Void)
            {
                flags |= DkmClrCompilationResultFlags.ReadOnlyResult;
                Debug.Assert(expression.ConstantValue == null);
                resultProperties = expression.ExpressionSymbol.GetResultProperties(flags, isConstant: false);
                return new BoundExpressionStatement(syntax, expression) { WasCompilerGenerated = true };
            }
            else if (expressionType.SpecialType == SpecialType.System_Boolean)
            {
                flags |= DkmClrCompilationResultFlags.BoolResult;
            }

            if (!IsAssignableExpression(binder, expression))
            {
                flags |= DkmClrCompilationResultFlags.ReadOnlyResult;
            }

            resultProperties = expression.ExpressionSymbol.GetResultProperties(flags, expression.ConstantValue != null);
            return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
        }
Beispiel #45
0
        /// <summary>
        /// Generate a class containing methods that represent
        /// the set of arguments and locals at the current scope.
        /// </summary>
        internal CommonPEModuleBuilder CompileGetLocals(
            string typeName,
            ArrayBuilder<LocalAndMethod> localBuilder,
            bool argumentsOnly,
            ImmutableArray<Alias> aliases,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics)
        {
            var objectType = this.Compilation.GetSpecialType(SpecialType.System_Object);
            var allTypeParameters = _currentFrame.GetAllTypeParameters();
            var additionalTypes = ArrayBuilder<NamedTypeSymbol>.GetInstance();

            EENamedTypeSymbol typeVariablesType = null;
            if (!argumentsOnly && (allTypeParameters.Length > 0))
            {
                // Generate a generic type with matching type parameters.
                // A null instance of the type will be used to represent the
                // "Type variables" local.
                typeVariablesType = new EENamedTypeSymbol(
                    this.Compilation.SourceModule.GlobalNamespace,
                    objectType,
                    _syntax,
                    _currentFrame,
                    ExpressionCompilerConstants.TypeVariablesClassName,
                    (m, t) => ImmutableArray.Create<MethodSymbol>(new EEConstructorSymbol(t)),
                    allTypeParameters,
                    (t1, t2) => allTypeParameters.SelectAsArray((tp, i, t) => (TypeParameterSymbol)new SimpleTypeParameterSymbol(t, i, tp.Name), t2));
                additionalTypes.Add(typeVariablesType);
            }

            var synthesizedType = new EENamedTypeSymbol(
                Compilation.SourceModule.GlobalNamespace,
                objectType,
                _syntax,
                _currentFrame,
                typeName,
                (m, container) =>
                {
                    var methodBuilder = ArrayBuilder<MethodSymbol>.GetInstance();

                    if (!argumentsOnly)
                    {
                        // Pseudo-variables: $exception, $ReturnValue, etc.
                        if (aliases.Length > 0)
                        {
                            var sourceAssembly = Compilation.SourceAssembly;
                            var typeNameDecoder = new EETypeNameDecoder(Compilation, (PEModuleSymbol)_currentFrame.ContainingModule);
                            foreach (var alias in aliases)
                            {
                                if (alias.IsReturnValueWithoutIndex())
                                {
                                    Debug.Assert(aliases.Count(a => a.Kind == DkmClrAliasKind.ReturnValue) > 1);
                                    continue;
                                }

                                var local = PlaceholderLocalSymbol.Create(
                                    typeNameDecoder,
                                    _currentFrame,
                                    sourceAssembly,
                                    alias);
                                var methodName = GetNextMethodName(methodBuilder);
                                var syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken));
                                var aliasMethod = this.CreateMethod(container, methodName, syntax, (method, diags) =>
                                {
                                    var expression = new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type);
                                    return new BoundReturnStatement(syntax, expression) { WasCompilerGenerated = true };
                                });
                                var flags = local.IsWritable ? DkmClrCompilationResultFlags.None : DkmClrCompilationResultFlags.ReadOnlyResult;
                                localBuilder.Add(MakeLocalAndMethod(local, aliasMethod, flags));
                                methodBuilder.Add(aliasMethod);
                            }
                        }

                        // "this" for non-static methods that are not display class methods or
                        // display class methods where the display class contains "<>4__this".
                        if (!m.IsStatic && (!IsDisplayClassType(m.ContainingType) || _displayClassVariables.ContainsKey(GeneratedNames.ThisProxyFieldName())))
                        {
                            var methodName = GetNextMethodName(methodBuilder);
                            var method = this.GetThisMethod(container, methodName);
                            localBuilder.Add(new CSharpLocalAndMethod("this", "this", method, DkmClrCompilationResultFlags.None)); // Note: writable in dev11.
                            methodBuilder.Add(method);
                        }
                    }

                    // Hoisted method parameters (represented as locals in the EE).
                    if (!_hoistedParameterNames.IsEmpty)
                    {
                        int localIndex = 0;
                        foreach (var local in _localsForBinding)
                        {
                            // Since we are showing hoisted method parameters first, the parameters may appear out of order
                            // in the Locals window if only some of the parameters are hoisted.  This is consistent with the
                            // behavior of the old EE.
                            if (_hoistedParameterNames.Contains(local.Name))
                            {
                                AppendLocalAndMethod(localBuilder, methodBuilder, local, container, localIndex, GetLocalResultFlags(local));
                            }

                            localIndex++;
                        }
                    }

                    // Method parameters (except those that have been hoisted).
                    int parameterIndex = m.IsStatic ? 0 : 1;
                    foreach (var parameter in m.Parameters)
                    {
                        var parameterName = parameter.Name;
                        if (!_hoistedParameterNames.Contains(parameterName) && GeneratedNames.GetKind(parameterName) == GeneratedNameKind.None)
                        {
                            AppendParameterAndMethod(localBuilder, methodBuilder, parameter, container, parameterIndex);
                        }

                        parameterIndex++;
                    }

                    if (!argumentsOnly)
                    {
                        // Locals.
                        int localIndex = 0;
                        foreach (var local in _localsForBinding)
                        {
                            if (!_hoistedParameterNames.Contains(local.Name))
                            {
                                AppendLocalAndMethod(localBuilder, methodBuilder, local, container, localIndex, GetLocalResultFlags(local));
                            }

                            localIndex++;
                        }

                        // "Type variables".
                        if ((object)typeVariablesType != null)
                        {
                            var methodName = GetNextMethodName(methodBuilder);
                            var returnType = typeVariablesType.Construct(allTypeParameters.Cast<TypeParameterSymbol, TypeSymbol>());
                            var method = this.GetTypeVariablesMethod(container, methodName, returnType);
                            localBuilder.Add(new CSharpLocalAndMethod(
                                ExpressionCompilerConstants.TypeVariablesLocalName,
                                ExpressionCompilerConstants.TypeVariablesLocalName,
                                method,
                                DkmClrCompilationResultFlags.ReadOnlyResult));
                            methodBuilder.Add(method);
                        }
                    }

                    return methodBuilder.ToImmutableAndFree();
                });

            additionalTypes.Add(synthesizedType);

            var module = CreateModuleBuilder(
                this.Compilation,
                synthesizedType.Methods,
                additionalTypes: additionalTypes.ToImmutableAndFree(),
                synthesizedType: synthesizedType,
                testData: testData,
                diagnostics: diagnostics);

            Debug.Assert(module != null);

            this.Compilation.Compile(
                module,
                win32Resources: null,
                xmlDocStream: null,
                emittingPdb: false,
                diagnostics: diagnostics,
                filterOpt: null,
                cancellationToken: CancellationToken.None);

            return diagnostics.HasAnyErrors() ? null : module;
        }
        internal override CommonCompilation CreateCompilation(IText code, string path, bool isInteractive, Session session, Type returnType, DiagnosticBag diagnostics)
        {
            Debug.Assert(code != null && path != null && diagnostics != null);

            Compilation previousSubmission = (session != null) ? (Compilation)session.LastSubmission : null;

            IEnumerable<MetadataReference> references = GetReferences(session);
            ReadOnlyArray<string> usings = GetImportedNamespaces(session);

            // TODO (tomat): BaseDirectory should be a property on ScriptEngine?
            var fileResolver = Session.GetFileResolver(session, Directory.GetCurrentDirectory());

            // parse:
            var parseOptions = isInteractive ? DefaultInteractive : DefaultScript;
            var tree = SyntaxTree.ParseText(code, path, parseOptions);
            diagnostics.Add(tree.GetDiagnostics());
            if (diagnostics.HasAnyErrors())
            {
                return null;
            }

            // create compilation:
            string assemblyName, submissionTypeName;
            GenerateSubmissionId(out assemblyName, out submissionTypeName);

            var compilation = Compilation.CreateSubmission(
                assemblyName,
                new CompilationOptions(
                    outputKind: OutputKind.DynamicallyLinkedLibrary,
                    mainTypeName: null,
                    scriptClassName: submissionTypeName,
                    usings: usings.ToList(),
                    optimize: false,                    // TODO (tomat)
                    checkOverflow: true,                // TODO (tomat)
                    allowUnsafe: false,                 // TODO (tomat)
                    cryptoKeyContainer: null,
                    cryptoKeyFile: null,
                    delaySign: null,
                    fileAlignment: 0,
                    baseAddress: 0L,
                    platform: Platform.AnyCPU,
                    generalWarningOption: ReportWarning.Default,
                    warningLevel: 4,
                    specificWarningOptions: null,
                    highEntropyVirtualAddressSpace: false
                ),
                tree,
                previousSubmission,
                references,
                fileResolver,
                this.metadataFileProvider,
                returnType,
                (session != null) ? session.HostObjectType : null
            );

            ValidateReferences(compilation, diagnostics);
            if (diagnostics.HasAnyErrors())
            {
                return null;
            }

            return compilation;
        }
Beispiel #47
0
        internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
        {
            var body = _generateMethodBody(this, diagnostics);
            var compilation = compilationState.Compilation;

            _lazyReturnType = CalculateReturnType(compilation, body);

            // Can't do this until the return type has been computed.
            TypeParameterChecker.Check(this, _allTypeParameters);

            if (diagnostics.HasAnyErrors())
            {
                return;
            }

            DiagnosticsPass.IssueDiagnostics(compilation, body, diagnostics, this);
            if (diagnostics.HasAnyErrors())
            {
                return;
            }

            // Check for use-site diagnostics (e.g. missing types in the signature).
            DiagnosticInfo useSiteDiagnosticInfo = null;
            this.CalculateUseSiteDiagnostic(ref useSiteDiagnosticInfo);
            if (useSiteDiagnosticInfo != null && useSiteDiagnosticInfo.Severity == DiagnosticSeverity.Error)
            {
                diagnostics.Add(useSiteDiagnosticInfo, this.Locations[0]);
                return;
            }

            var declaredLocals = PooledHashSet<LocalSymbol>.GetInstance();
            try
            {
                // Rewrite local declaration statement.
                body = (BoundStatement)LocalDeclarationRewriter.Rewrite(compilation, _container, declaredLocals, body);

                // Verify local declaration names.
                foreach (var local in declaredLocals)
                {
                    Debug.Assert(local.Locations.Length > 0);
                    var name = local.Name;
                    if (name.StartsWith("$", StringComparison.Ordinal))
                    {
                        diagnostics.Add(ErrorCode.ERR_UnexpectedCharacter, local.Locations[0], name[0]);
                        return;
                    }
                }

                // Rewrite references to placeholder "locals".
                body = (BoundStatement)PlaceholderLocalRewriter.Rewrite(compilation, _container, declaredLocals, body);
            }
            finally
            {
                declaredLocals.Free();
            }

            var syntax = body.Syntax;
            var statementsBuilder = ArrayBuilder<BoundStatement>.GetInstance();
            statementsBuilder.Add(body);
            // Insert an implicit return statement if necessary.
            if (body.Kind != BoundKind.ReturnStatement)
            {
                statementsBuilder.Add(new BoundReturnStatement(syntax, expressionOpt: null));
            }

            var localsBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
            var localsSet = PooledHashSet<LocalSymbol>.GetInstance();
            foreach (var local in this.LocalsForBinding)
            {
                Debug.Assert(!localsSet.Contains(local));
                localsBuilder.Add(local);
                localsSet.Add(local);
            }
            foreach (var local in this.Locals)
            {
                if (!localsSet.Contains(local))
                {
                    localsBuilder.Add(local);
                }
            }
            localsSet.Free();

            body = new BoundBlock(syntax, localsBuilder.ToImmutableAndFree(), statementsBuilder.ToImmutableAndFree()) { WasCompilerGenerated = true };

            Debug.Assert(!diagnostics.HasAnyErrors());
            Debug.Assert(!body.HasErrors);

            bool sawLambdas;
            bool sawAwaitInExceptionHandler;
            body = LocalRewriter.Rewrite(
                compilation: this.DeclaringCompilation,
                method: this,
                methodOrdinal: _methodOrdinal,
                containingType: _container,
                statement: body,
                compilationState: compilationState,
                previousSubmissionFields: null,
                allowOmissionOfConditionalCalls: false,
                diagnostics: diagnostics,
                sawLambdas: out sawLambdas,
                sawAwaitInExceptionHandler: out sawAwaitInExceptionHandler);

            Debug.Assert(!sawAwaitInExceptionHandler);

            if (body.HasErrors)
            {
                return;
            }

            // Variables may have been captured by lambdas in the original method
            // or in the expression, and we need to preserve the existing values of
            // those variables in the expression. This requires rewriting the variables
            // in the expression based on the closure classes from both the original
            // method and the expression, and generating a preamble that copies
            // values into the expression closure classes.
            //
            // Consider the original method:
            // static void M()
            // {
            //     int x, y, z;
            //     ...
            //     F(() => x + y);
            // }
            // and the expression in the EE: "F(() => x + z)".
            //
            // The expression is first rewritten using the closure class and local <1>
            // from the original method: F(() => <1>.x + z)
            // Then lambda rewriting introduces a new closure class that includes
            // the locals <1> and z, and a corresponding local <2>: F(() => <2>.<1>.x + <2>.z)
            // And a preamble is added to initialize the fields of <2>:
            //     <2> = new <>c__DisplayClass0();
            //     <2>.<1> = <1>;
            //     <2>.z = z;

            // Rewrite "this" and "base" references to parameter in this method.
            // Rewrite variables within body to reference existing display classes.
            body = (BoundStatement)CapturedVariableRewriter.Rewrite(
                this.SubstitutedSourceMethod.IsStatic ? null : _parameters[0],
                compilation.Conversions,
                _displayClassVariables,
                body,
                diagnostics);

            if (body.HasErrors)
            {
                Debug.Assert(false, "Please add a test case capturing whatever caused this assert.");
                return;
            }

            if (diagnostics.HasAnyErrors())
            {
                return;
            }

            if (sawLambdas)
            {
                var closureDebugInfoBuilder = ArrayBuilder<ClosureDebugInfo>.GetInstance();
                var lambdaDebugInfoBuilder = ArrayBuilder<LambdaDebugInfo>.GetInstance();

                body = LambdaRewriter.Rewrite(
                    loweredBody: body,
                    thisType: this.SubstitutedSourceMethod.ContainingType,
                    thisParameter: _thisParameter,
                    method: this,
                    methodOrdinal: _methodOrdinal,
                    closureDebugInfoBuilder: closureDebugInfoBuilder,
                    lambdaDebugInfoBuilder: lambdaDebugInfoBuilder,
                    slotAllocatorOpt: null,
                    compilationState: compilationState,
                    diagnostics: diagnostics,
                    assignLocals: true);

                // we don't need this information:
                closureDebugInfoBuilder.Free();
                lambdaDebugInfoBuilder.Free();
            }

            // Insert locals from the original method,
            // followed by any new locals.
            var block = (BoundBlock)body;
            var localBuilder = ArrayBuilder<LocalSymbol>.GetInstance();
            foreach (var local in this.Locals)
            {
                Debug.Assert(!(local is EELocalSymbol) || (((EELocalSymbol)local).Ordinal == localBuilder.Count));
                localBuilder.Add(local);
            }
            foreach (var local in block.Locals)
            {
                var oldLocal = local as EELocalSymbol;
                if (oldLocal != null)
                {
                    Debug.Assert(localBuilder[oldLocal.Ordinal] == oldLocal);
                    continue;
                }
                localBuilder.Add(local);
            }

            body = block.Update(localBuilder.ToImmutableAndFree(), block.Statements);
            TypeParameterChecker.Check(body, _allTypeParameters);
            compilationState.AddSynthesizedMethod(this, body);
        }
 private static CSharpSyntaxNode Parse(
     string expr,
     bool treatAsExpression,
     DiagnosticBag diagnostics,
     out ReadOnlyCollection<string> formatSpecifiers)
 {
     if (treatAsExpression)
     {
         return expr.ParseExpression(diagnostics, allowFormatSpecifiers: true, formatSpecifiers: out formatSpecifiers);
     }
     else
     {
         // Try to parse as an expression. If that fails, parse as a statement.
         var exprDiagnostics = DiagnosticBag.GetInstance();
         ReadOnlyCollection<string> exprFormatSpecifiers;
         CSharpSyntaxNode syntax = expr.ParseExpression(exprDiagnostics, allowFormatSpecifiers: true, formatSpecifiers: out exprFormatSpecifiers);
         Debug.Assert((syntax == null) || !exprDiagnostics.HasAnyErrors());
         exprDiagnostics.Free();
         if (syntax != null)
         {
             Debug.Assert(!diagnostics.HasAnyErrors());
             formatSpecifiers = exprFormatSpecifiers;
             return syntax;
         }
         formatSpecifiers = null;
         syntax = expr.ParseStatement(diagnostics);
         if ((syntax != null) && (syntax.Kind() != SyntaxKind.LocalDeclarationStatement))
         {
             diagnostics.Add(ErrorCode.ERR_ExpressionOrDeclarationExpected, Location.None);
             return null;
         }
         return syntax;
     }
 }
Beispiel #49
0
        private static BoundStatement BindAssignment(Binder binder, ExpressionSyntax syntax, DiagnosticBag diagnostics)
        {
            binder = binder.GetBinder(syntax);
            Debug.Assert(binder != null);

            var expression = binder.BindValue(syntax, diagnostics, Binder.BindValueKind.RValue);
            if (diagnostics.HasAnyErrors())
            {
                return null;
            }

            return binder.WrapWithVariablesIfAny(syntax,
                                                 new BoundExpressionStatement(expression.Syntax, expression) { WasCompilerGenerated = true });
        }
        internal override ReadOnlyCollection<byte> CompileGetLocals(
            ReadOnlyCollection<Alias> aliases,
            ArrayBuilder<LocalAndMethod> locals,
            bool argumentsOnly,
            DiagnosticBag diagnostics,
            out string typeName,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData)
        {
            var context = this.CreateCompilationContext(null);
            var moduleBuilder = context.CompileGetLocals(aliases, TypeName, locals, argumentsOnly, testData, diagnostics);
            ReadOnlyCollection<byte> assembly = null;

            if ((moduleBuilder != null) && (locals.Count > 0))
            {
                using (var stream = new MemoryStream())
                {
                    Cci.PeWriter.WritePeToStream(
                        new EmitContext((Cci.IModule)moduleBuilder, null, diagnostics),
                        context.MessageProvider,
                        () => stream,
                        nativePdbWriterOpt: null,
                        pdbPathOpt: null,
                        allowMissingMethodBodies: false,
                        deterministic: false,
                        cancellationToken: default(CancellationToken));

                    if (!diagnostics.HasAnyErrors())
                    {
                        assembly = new ReadOnlyCollection<byte>(stream.ToArray());
                    }
                }
            }

            if (assembly == null)
            {
                locals.Clear();
                assembly = s_emptyBytes;
            }

            typeName = TypeName;
            return assembly;
        }
Beispiel #51
0
        public static void Run(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints,
            out int asyncCatchHandlerOffset, out ImmutableArray<int> asyncYieldPoints, out ImmutableArray<int> asyncResumePoints)
        {
            CodeGenerator generator = new CodeGenerator(method, block, builder, module, diagnostics, optimize, emitSequencePoints);
            generator.Generate();

            if (!diagnostics.HasAnyErrors())
            {
                builder.Realize();
            }

            asyncCatchHandlerOffset = (generator.asyncCatchHandlerOffset < 0)
                ? -1
                : generator.builder.GetILOffsetFromMarker(generator.asyncCatchHandlerOffset);

            ArrayBuilder<int> yieldPoints = generator.asyncYieldPoints;
            ArrayBuilder<int> resumePoints = generator.asyncResumePoints;
            if (yieldPoints == null)
            {
                asyncYieldPoints = ImmutableArray<int>.Empty;
                asyncResumePoints = ImmutableArray<int>.Empty;
            }
            else
            {
                var yieldPointBuilder = ArrayBuilder<int>.GetInstance();
                var resumePointBuilder = ArrayBuilder<int>.GetInstance();
                int n = yieldPoints.Count;
                for (int i = 0; i < n; i++)
                {
                    int yieldOffset = generator.builder.GetILOffsetFromMarker(yieldPoints[i]);
                    int resumeOffset = generator.builder.GetILOffsetFromMarker(resumePoints[i]);
                    Debug.Assert(resumeOffset >= 0); // resume marker should always be reachable from dispatch

                    // yield point may not be reachable if the whole 
                    // await is not reachable; we just ignore such awaits
                    if (yieldOffset > 0)
                    {
                        yieldPointBuilder.Add(yieldOffset);
                        resumePointBuilder.Add(resumeOffset);
                    }
                }

                asyncYieldPoints = yieldPointBuilder.ToImmutableAndFree();
                asyncResumePoints = resumePointBuilder.ToImmutableAndFree();
                yieldPoints.Free();
                resumePoints.Free();
            }
        }
        private static BoundExpression ConvertToLocalTypeHelper(CSharpCompilation compilation, BoundExpression expr, TypeSymbol type, DiagnosticBag diagnostics)
        {
            // NOTE: This conversion can fail if some of the types involved are from not-yet-loaded modules.
            // For example, if System.Exception hasn't been loaded, then this call will fail for $stowedexception.
            HashSet<DiagnosticInfo> useSiteDiagnostics = null;
            var conversion = compilation.Conversions.ClassifyConversionFromExpression(expr, type, ref useSiteDiagnostics);
            diagnostics.Add(expr.Syntax, useSiteDiagnostics);
            Debug.Assert(conversion.IsValid || diagnostics.HasAnyErrors());

            return BoundConversion.Synthesized(
                expr.Syntax,
                expr,
                conversion,
                @checked: false,
                explicitCastInCode: false,
                constantValueOpt: null,
                type: type,
                hasErrors: !conversion.IsValid);
        }
        /// <summary>
        /// Generate a thread-safe accessor for a WinRT field-like event.
        /// 
        /// Add:
        ///   return EventRegistrationTokenTable&lt;Event&gt;.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).AddEventHandler(value);
        /// 
        /// Remove:
        ///   EventRegistrationTokenTable&lt;Event&gt;.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).RemoveEventHandler(value);
        /// </summary>
        internal static BoundBlock ConstructFieldLikeEventAccessorBody_WinRT(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag diagnostics)
        {
            CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode;

            MethodSymbol accessor = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod;
            Debug.Assert((object)accessor != null);

            FieldSymbol field = eventSymbol.AssociatedField;
            Debug.Assert((object)field != null);

            NamedTypeSymbol fieldType = (NamedTypeSymbol)field.Type;
            Debug.Assert(fieldType.Name == "EventRegistrationTokenTable");

            MethodSymbol getOrCreateMethod = (MethodSymbol)Binder.GetWellKnownTypeMember(
                compilation,
                WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__GetOrCreateEventRegistrationTokenTable,
                diagnostics,
                syntax: syntax);

            if ((object)getOrCreateMethod == null)
            {
                Debug.Assert(diagnostics.HasAnyErrors());
                return null;
            }

            getOrCreateMethod = getOrCreateMethod.AsMember(fieldType);

            WellKnownMember processHandlerMember = isAddMethod
                ? WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__AddEventHandler
                : WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__RemoveEventHandler;

            MethodSymbol processHandlerMethod = (MethodSymbol)Binder.GetWellKnownTypeMember(
                compilation,
                processHandlerMember,
                diagnostics,
                syntax: syntax);

            if ((object)processHandlerMethod == null)
            {
                Debug.Assert(diagnostics.HasAnyErrors());
                return null;
            }

            processHandlerMethod = processHandlerMethod.AsMember(fieldType);

            // _tokenTable
            BoundFieldAccess fieldAccess = new BoundFieldAccess(
                syntax,
                field.IsStatic ? null : new BoundThisReference(syntax, accessor.ThisParameter.Type),
                field,
                constantValueOpt: null)
            { WasCompilerGenerated = true };

            // EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable)
            BoundCall getOrCreateCall = BoundCall.Synthesized(
                syntax,
                receiverOpt: null,
                method: getOrCreateMethod,
                arguments: fieldAccess);

            // value
            BoundParameter parameterAccess = new BoundParameter(
                syntax,
                accessor.Parameters.Single());

            // EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).AddHandler(value) // or RemoveHandler
            BoundCall processHandlerCall = BoundCall.Synthesized(
                syntax,
                receiverOpt: getOrCreateCall,
                method: processHandlerMethod,
                arguments: parameterAccess);

            if (isAddMethod)
            {
                // {
                //     return EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).AddHandler(value);
                // }   
                BoundStatement returnStatement = BoundReturnStatement.Synthesized(syntax, processHandlerCall);
                return BoundBlock.SynthesizedNoLocals(syntax, returnStatement);
            }
            else
            {
                // {
                //     EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).RemoveHandler(value);
                //     return;
                // }  
                BoundStatement callStatement = new BoundExpressionStatement(syntax, processHandlerCall);
                BoundStatement returnStatement = new BoundReturnStatement(syntax, expressionOpt: null);
                return BoundBlock.SynthesizedNoLocals(syntax, callStatement, returnStatement);
            }
        }