提交 908b0c5b 编写于 作者: J Jared Parsons

More CoreFx porting work

Made a number of small changes to enable building on CoreFx

- Remove uses of MemoryStream::GetBuffer.  This API isn't supported on
CoreFx. The TryGetBuffer is available but in these cases seemed better
to just call Stream::CopyTo
- Changed Type.Assembly to Type.GetTypeInfo().Assembly
- Moved scripting APIs out of CommonCompiler and into
ScriptCompilerUtil.  These methods relied on APIs that are not available
on CoreFx and have no equivalent.
- Minor API updates.
上级 25e16377
......@@ -33,7 +33,7 @@ protected CSharpCompiler(CSharpCommandLineParser parser, string responseFile, st
public override DiagnosticFormatter DiagnosticFormatter { get { return _diagnosticFormatter; } }
protected internal new CSharpCommandLineArguments Arguments { get { return (CSharpCommandLineArguments)base.Arguments; } }
protected override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger)
public override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger)
{
var parseOptions = Arguments.ParseOptions;
var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);
......@@ -248,7 +248,7 @@ internal override bool SuppressDefaultResponseFile(IEnumerable<string> args)
/// Print compiler logo
/// </summary>
/// <param name="consoleOutput"></param>
protected override void PrintLogo(TextWriter consoleOutput)
public override void PrintLogo(TextWriter consoleOutput)
{
consoleOutput.WriteLine(ErrorFacts.GetMessage(MessageID.IDS_LogoLine1, Culture), GetToolName(), GetAssemblyFileVersion());
consoleOutput.WriteLine(ErrorFacts.GetMessage(MessageID.IDS_LogoLine2, Culture));
......@@ -274,7 +274,7 @@ internal override Version GetAssemblyVersion()
/// Print Commandline help message (up to 80 English characters per line)
/// </summary>
/// <param name="consoleOutput"></param>
protected override void PrintHelp(TextWriter consoleOutput)
public override void PrintHelp(TextWriter consoleOutput)
{
consoleOutput.WriteLine(ErrorFacts.GetMessage(MessageID.IDS_CSCHelp, Culture));
}
......
......@@ -378,7 +378,7 @@ private static string GetFullyQualifiedTypeName(TypeDefinition typeDef, PEModule
private static bool DerivesFromDiagnosticAnalyzer(Type type)
{
return type.IsSubclassOf(typeof(DiagnosticAnalyzer));
return type.GetTypeInfo().IsSubclassOf(typeof(DiagnosticAnalyzer));
}
public override bool Equals(object obj)
......
......@@ -56,9 +56,6 @@ internal static string GetResponseFileFullPath(string responseFileName)
public abstract DiagnosticFormatter DiagnosticFormatter { get; }
private readonly HashSet<Diagnostic> _reportedDiagnostics = new HashSet<Diagnostic>();
protected abstract Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger);
protected abstract void PrintLogo(TextWriter consoleOutput);
protected abstract void PrintHelp(TextWriter consoleOutput);
internal abstract string GetToolName();
internal abstract Version GetAssemblyVersion();
internal abstract string GetAssemblyFileVersion();
......@@ -193,7 +190,6 @@ private DiagnosticInfo ToFileReadDiagnostics(Exception e, CommandLineSourceFile
return diagnosticInfo;
}
protected bool ReportErrors(IEnumerable<Diagnostic> diagnostics, TextWriter consoleOutput, ErrorLogger errorLogger)
{
bool hasErrors = false;
foreach (var diag in diagnostics)
......@@ -230,7 +226,6 @@ protected bool ReportErrors(IEnumerable<Diagnostic> diagnostics, TextWriter cons
return hasErrors;
}
protected bool ReportErrors(IEnumerable<DiagnosticInfo> diagnostics, TextWriter consoleOutput, ErrorLogger errorLogger)
{
bool hasErrors = false;
if (diagnostics != null && diagnostics.Any())
......@@ -261,7 +256,6 @@ protected virtual void PrintError(DiagnosticInfo diagnostic, TextWriter consoleO
consoleOutput.WriteLine(diagnostic.ToString(Culture));
}
private ErrorLogger GetErrorLogger(TextWriter consoleOutput, CancellationToken cancellationToken)
{
Debug.Assert(Arguments.ErrorLogPath != null);
......@@ -765,105 +759,6 @@ internal static bool TryGetCompilerDiagnosticCode(string diagnosticId, string ex
return diagnosticId.StartsWith(expectedPrefix, StringComparison.Ordinal) && uint.TryParse(diagnosticId.Substring(expectedPrefix.Length), out code);
}
/// <summary>
/// csi.exe and vbi.exe entry point.
/// </summary>
internal int RunInteractive(TextWriter consoleOutput)
{
ErrorLogger errorLogger = null;
if (Arguments.ErrorLogPath != null)
{
errorLogger = GetErrorLogger(consoleOutput, CancellationToken.None);
if (errorLogger == null)
{
return Failed;
}
}
using (errorLogger)
{
return RunInteractiveCore(consoleOutput, errorLogger);
}
}
/// <summary>
/// csi.exe and vbi.exe entry point.
/// </summary>
private int RunInteractiveCore(TextWriter consoleOutput, ErrorLogger errorLogger)
{
Debug.Assert(Arguments.IsInteractive);
var hasScriptFiles = Arguments.SourceFiles.Any(file => file.IsScript);
if (Arguments.DisplayLogo && !hasScriptFiles)
{
PrintLogo(consoleOutput);
}
if (Arguments.DisplayHelp)
{
PrintHelp(consoleOutput);
return 0;
}
// TODO (tomat):
// When we have command line REPL enabled we'll launch it if there are no input files.
IEnumerable<Diagnostic> errors = Arguments.Errors;
if (!hasScriptFiles)
{
errors = errors.Concat(new[] { Diagnostic.Create(MessageProvider, MessageProvider.ERR_NoScriptsSpecified) });
}
if (ReportErrors(errors, consoleOutput, errorLogger))
{
return Failed;
}
// arguments are always available when executing script code:
Debug.Assert(Arguments.ScriptArguments != null);
var compilation = CreateCompilation(consoleOutput, touchedFilesLogger: null, errorLogger: errorLogger);
if (compilation == null)
{
return Failed;
}
byte[] compiledAssembly;
using (MemoryStream output = new MemoryStream())
{
EmitResult emitResult = compilation.Emit(output);
if (ReportErrors(emitResult.Diagnostics, consoleOutput, errorLogger))
{
return Failed;
}
compiledAssembly = output.ToArray();
}
var assembly = Assembly.Load(compiledAssembly);
return Execute(assembly, Arguments.ScriptArguments.ToArray());
}
private static int Execute(Assembly assembly, string[] scriptArguments)
{
var parameters = assembly.EntryPoint.GetParameters();
object[] arguments;
if (parameters.Length == 0)
{
arguments = SpecializedCollections.EmptyObjects;
}
else
{
Debug.Assert(parameters.Length == 1);
arguments = new object[] { scriptArguments };
}
object result = assembly.EntryPoint.Invoke(null, arguments);
return result is int ? (int)result : Succeeded;
}
/// <summary>
/// When overriden by a derived class, this property can override the current thread's
/// CurrentUICulture property for diagnostic message resource lookups.
......
......@@ -350,7 +350,7 @@ public void Dispose()
// End dictionary for log file key-value pairs.
EndGroup();
_writer.Close();
_writer.Dispose();
}
}
}
......@@ -209,7 +209,7 @@ private void GetEffectiveIncludesCore(ImmutableArray<string>.Builder arrayBuilde
}
// If this file has already been included don't recurse into it.
if (!arrayBuilder.Contains(ruleSet.FilePath, StringComparer.InvariantCultureIgnoreCase))
if (!arrayBuilder.Contains(ruleSet.FilePath, StringComparer.OrdinalIgnoreCase))
{
ruleSet.GetEffectiveIncludesCore(arrayBuilder);
}
......
......@@ -164,8 +164,7 @@ private static int HandleResponse(BuildResponse response)
{
try
{
holdsMutex = mutex.WaitOne(TimeOutMsNewProcess,
exitContext: false);
holdsMutex = mutex.WaitOne(TimeOutMsNewProcess);
}
catch (AbandonedMutexException)
{
......
......@@ -184,7 +184,7 @@ public async Task WriteAsync(Stream outStream, CancellationToken cancellationTok
// to prevent making another copy.
var stream = (MemoryStream)writer.BaseStream;
// Write the length of the request
int length = (int)stream.Length;
int length = checked((int)stream.Length);
// Back out if the request is > 1 MB
if (stream.Length > 0x100000)
......@@ -200,8 +200,7 @@ public async Task WriteAsync(Stream outStream, CancellationToken cancellationTok
Log("Writing request of size {0}", length);
// Write the request
await outStream.WriteAsync(stream.GetBuffer(), 0, length,
cancellationToken).ConfigureAwait(false);
await stream.CopyToAsync(outStream, bufferSize: length, cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
......@@ -259,8 +258,8 @@ public void WriteToBinaryWriter(BinaryWriter writer)
///
/// Field Name Field Type Size (bytes)
/// -------------------------------------------------
/// responseLength int (positive) 4
/// responseType enum ResponseType 4
/// responseLength int (positive) 4
/// responseBody Response subclass variable
/// </summary>
internal abstract class BuildResponse
......@@ -292,8 +291,10 @@ public enum ResponseType
// Grab the MemoryStream and its internal buffer to prevent
// making another copy.
var stream = (MemoryStream)writer.BaseStream;
// Write the length of the response
uint length = (uint)stream.Length;
int length = checked((int)stream.Length);
Log("Writing response length");
// There is no way to know the number of bytes written to
// the pipe stream. We just have to assume all of them are written.
......@@ -304,12 +305,7 @@ public enum ResponseType
// Write the response
Log("Writing response of size {0}", length);
// There is no way to know the number of bytes written to
// the pipe stream. We just have to assume all of them are written.
await outStream.WriteAsync(stream.GetBuffer(),
0,
(int)length,
cancellationToken).ConfigureAwait(false);
await stream.CopyToAsync(outStream, bufferSize: length, cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
......
......@@ -54,7 +54,7 @@ protected override ImmutableArray<DiagnosticAnalyzer> ResolveAnalyzersFromArgume
return analyzers;
}
protected override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger)
public override Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger)
{
Compilation = base.CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger);
return Compilation;
......
......@@ -48,7 +48,7 @@ Friend Class MockVisualBasicCompiler
Return analyzers
End Function
Protected Overrides Function CreateCompilation(consoleOutput As TextWriter, touchedFilesLogger As TouchedFileLogger, errorLogger As ErrorLogger) As Compilation
Public Overrides Function CreateCompilation(consoleOutput As TextWriter, touchedFilesLogger As TouchedFileLogger, errorLogger As ErrorLogger) As Compilation
Compilation = MyBase.CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger)
Return Compilation
End Function
......
......@@ -65,7 +65,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return tree
End Function
Protected Overrides Function CreateCompilation(consoleOutput As TextWriter, touchedFilesLogger As TouchedFileLogger, errorLogger As ErrorLogger) As Compilation
Public Overrides Function CreateCompilation(consoleOutput As TextWriter, touchedFilesLogger As TouchedFileLogger, errorLogger As ErrorLogger) As Compilation
Dim parseOptions = Arguments.ParseOptions
Dim scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script)
......@@ -169,7 +169,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' Print compiler logo
''' </summary>
''' <param name="consoleOutput"></param>
Protected Overrides Sub PrintLogo(consoleOutput As TextWriter)
Public Overrides Sub PrintLogo(consoleOutput As TextWriter)
consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_LogoLine1, Culture), GetToolName(), GetAssemblyFileVersion())
consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_LogoLine2, Culture))
consoleOutput.WriteLine()
......@@ -191,7 +191,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' Print Commandline help message (up to 80 English characters per line)
''' </summary>
''' <param name="consoleOutput"></param>
Protected Overrides Sub PrintHelp(consoleOutput As TextWriter)
Public Overrides Sub PrintHelp(consoleOutput As TextWriter)
consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_VBCHelp, Culture))
End Sub
......
......@@ -28,7 +28,7 @@ internal static int Main(string[] args)
try
{
var responseFile = CommonCompiler.GetResponseFileFullPath(InteractiveResponseFileName);
return new Csi(responseFile, Directory.GetCurrentDirectory(), args).RunInteractive(Console.Out);
return ScriptCompilerUtil.RunInteractive(new Csi(responseFile, Directory.GetCurrentDirectory(), args), Console.Out);
}
catch (Exception ex)
{
......@@ -48,7 +48,7 @@ internal override MetadataFileReferenceResolver GetExternalMetadataResolver(Touc
return new GacFileResolver(Arguments.ReferencePaths, Arguments.BaseDirectory, GacFileResolver.Default.Architectures, CultureInfo.CurrentCulture);
}
protected override void PrintLogo(TextWriter consoleOutput)
public override void PrintLogo(TextWriter consoleOutput)
{
Assembly thisAssembly = typeof(Csi).Assembly;
consoleOutput.WriteLine(CsiResources.LogoLine1, FileVersionInfo.GetVersionInfo(thisAssembly.Location).FileVersion);
......@@ -56,7 +56,7 @@ protected override void PrintLogo(TextWriter consoleOutput)
consoleOutput.WriteLine();
}
protected override void PrintHelp(TextWriter consoleOutput)
public override void PrintHelp(TextWriter consoleOutput)
{
// TODO: format with word wrapping
consoleOutput.WriteLine(
......
......@@ -23,7 +23,7 @@ Friend NotInheritable Class Vbi
Public Shared Function Main(args As String()) As Integer
Try
Dim responseFile = CommonCompiler.GetResponseFileFullPath(InteractiveResponseFileName)
Return New Vbi(responseFile, Directory.GetCurrentDirectory(), args).RunInteractive(Console.Out)
Return ScriptCompilerUtil.RunInteractive(New Vbi(responseFile, Directory.GetCurrentDirectory(), args), Console.Out)
Catch ex As Exception
Console.WriteLine(ex.ToString())
Return Failed
......@@ -39,20 +39,22 @@ Friend NotInheritable Class Vbi
Return New GacFileResolver(Arguments.ReferencePaths, Arguments.BaseDirectory, GacFileResolver.Default.Architectures, CultureInfo.CurrentCulture)
End Function
Protected Overrides Sub PrintLogo(consoleOutput As TextWriter)
Public Overrides Sub PrintLogo(consoleOutput As TextWriter)
Dim thisAssembly As Assembly = GetType(Vbi).Assembly
consoleOutput.WriteLine(VbiResources.LogoLine1, FileVersionInfo.GetVersionInfo(thisAssembly.Location).FileVersion)
consoleOutput.WriteLine(VbiResources.LogoLine2)
consoleOutput.WriteLine()
End Sub
Protected Overrides Sub PrintHelp(consoleOutput As TextWriter)
Public Overrides Sub PrintHelp(consoleOutput As TextWriter)
' TODO
consoleOutput.WriteLine(" Roslyn Interactive Compiler Options")
End Sub
Protected Overrides Function GetSqmAppID() As UInt32
Return SqmServiceProvider.BASIC_APPID
End Function
Protected Overrides Sub CompilerSpecificSqm(sqm As IVsSqmMulti, sqmSession As UInt32)
sqm.SetDatapoint(sqmSession, SqmServiceProvider.DATAID_SQM_ROSLYN_COMPILERTYPE, CType(SqmServiceProvider.CompilerType.Interactive, UInt32))
End Sub
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Scripting
{
internal static class ScriptCompilerUtil
{
/// <summary>
/// csi.exe and vbi.exe entry point.
/// </summary>
internal static int RunInteractive(CommonCompiler compiler, TextWriter consoleOutput)
{
ErrorLogger errorLogger = null;
if (compiler.Arguments.ErrorLogPath != null)
{
errorLogger = compiler.GetErrorLogger(consoleOutput, CancellationToken.None);
if (errorLogger == null)
{
return CommonCompiler.Failed;
}
}
using (errorLogger)
{
return RunInteractiveCore(compiler, consoleOutput, errorLogger);
}
}
/// <summary>
/// csi.exe and vbi.exe entry point.
/// </summary>
private static int RunInteractiveCore(CommonCompiler compiler, TextWriter consoleOutput, ErrorLogger errorLogger)
{
Debug.Assert(compiler.Arguments.IsInteractive);
var hasScriptFiles = compiler.Arguments.SourceFiles.Any(file => file.IsScript);
if (compiler.Arguments.DisplayLogo && !hasScriptFiles)
{
compiler.PrintLogo(consoleOutput);
}
if (compiler.Arguments.DisplayHelp)
{
compiler.PrintHelp(consoleOutput);
return 0;
}
// TODO (tomat):
// When we have command line REPL enabled we'll launch it if there are no input files.
IEnumerable<Diagnostic> errors = compiler.Arguments.Errors;
if (!hasScriptFiles)
{
errors = errors.Concat(new[] { Diagnostic.Create(compiler.MessageProvider, compiler.MessageProvider.ERR_NoScriptsSpecified) });
}
if (compiler.ReportErrors(errors, consoleOutput, errorLogger))
{
return CommonCompiler.Failed;
}
// arguments are always available when executing script code:
Debug.Assert(compiler.Arguments.ScriptArguments != null);
var compilation = compiler.CreateCompilation(consoleOutput, touchedFilesLogger: null, errorLogger: errorLogger);
if (compilation == null)
{
return CommonCompiler.Failed;
}
byte[] compiledAssembly;
using (MemoryStream output = new MemoryStream())
{
EmitResult emitResult = compilation.Emit(output);
if (compiler.ReportErrors(emitResult.Diagnostics, consoleOutput, errorLogger))
{
return CommonCompiler.Failed;
}
compiledAssembly = output.ToArray();
}
var assembly = Assembly.Load(compiledAssembly);
return Execute(assembly, compiler.Arguments.ScriptArguments.ToArray());
}
private static int Execute(Assembly assembly, string[] scriptArguments)
{
var parameters = assembly.EntryPoint.GetParameters();
object[] arguments;
if (parameters.Length == 0)
{
arguments = SpecializedCollections.EmptyObjects;
}
else
{
Debug.Assert(parameters.Length == 1);
arguments = new object[] { scriptArguments };
}
object result = assembly.EntryPoint.Invoke(null, arguments);
return result is int ? (int)result : CommonCompiler.Succeeded;
}
}
}
......@@ -93,6 +93,7 @@
<Compile Include="ObjectFormatter.Formatter.cs" />
<Compile Include="Script.cs" />
<Compile Include="ScriptBuilder.cs" />
<Compile Include="ScriptCompilerUtil.cs" />
<Compile Include="ScriptingResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
......@@ -146,4 +147,4 @@
<Import Project="..\..\..\build\VSL.Imports.Closed.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册