提交 bb03a8e7 编写于 作者: K Kevin Halverson

Implement #load "semantics" for CSharpCompilations...

上级 6c5767b2
...@@ -230,6 +230,8 @@ ...@@ -230,6 +230,8 @@
<Compile Include="Compilation\AttributeSemanticModel.cs" /> <Compile Include="Compilation\AttributeSemanticModel.cs" />
<Compile Include="Compilation\AwaitExpressionInfo.cs" /> <Compile Include="Compilation\AwaitExpressionInfo.cs" />
<Compile Include="Compilation\BuiltInOperators.cs" /> <Compile Include="Compilation\BuiltInOperators.cs" />
<Compile Include="Compilation\SyntaxAndDeclarationManager.cs" />
<Compile Include="Compilation\SyntaxAndDeclarationManager.LazyState.cs" />
<Compile Include="Compilation\CSharpCompilerDiagnosticAnalyzer.cs" /> <Compile Include="Compilation\CSharpCompilerDiagnosticAnalyzer.cs" />
<Compile Include="Compilation\CSharpCompilation.cs" /> <Compile Include="Compilation\CSharpCompilation.cs" />
<Compile Include="Compilation\CSharpCompilationReference.cs" /> <Compile Include="Compilation\CSharpCompilationReference.cs" />
......
...@@ -351,6 +351,12 @@ internal static bool HasReferenceDirectives(this SyntaxTree tree) ...@@ -351,6 +351,12 @@ internal static bool HasReferenceDirectives(this SyntaxTree tree)
return csharpTree != null && csharpTree.HasReferenceDirectives; return csharpTree != null && csharpTree.HasReferenceDirectives;
} }
internal static bool HasReferenceOrLoadDirectives(this SyntaxTree tree)
{
var csharpTree = tree as CSharpSyntaxTree;
return csharpTree != null && csharpTree.HasReferenceOrLoadDirectives;
}
internal static bool IsAnyPreprocessorSymbolDefined(this SyntaxTree tree, ImmutableArray<string> conditionalSymbols) internal static bool IsAnyPreprocessorSymbolDefined(this SyntaxTree tree, ImmutableArray<string> conditionalSymbols)
{ {
var csharpTree = tree as CSharpSyntaxTree; var csharpTree = tree as CSharpSyntaxTree;
......
...@@ -61,6 +61,15 @@ internal class CSharpResources { ...@@ -61,6 +61,15 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Cannot have a previousSubmission when not a submission..
/// </summary>
internal static string CannotHavePreviousSubmission {
get {
return ResourceManager.GetString("CannotHavePreviousSubmission", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Can&apos;t reference compilation of type &apos;{0}&apos; from {1} compilation.. /// Looks up a localized string similar to Can&apos;t reference compilation of type &apos;{0}&apos; from {1} compilation..
/// </summary> /// </summary>
...@@ -88,6 +97,15 @@ internal class CSharpResources { ...@@ -88,6 +97,15 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Could not find file..
/// </summary>
internal static string CouldNotFindFile {
get {
return ResourceManager.GetString("CouldNotFindFile", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to element is expected. /// Looks up a localized string similar to element is expected.
/// </summary> /// </summary>
...@@ -9692,6 +9710,15 @@ internal class CSharpResources { ...@@ -9692,6 +9710,15 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to SyntaxTree &apos;{0}&apos; resulted from a #load directive and cannot be removed or replaced directly..
/// </summary>
internal static string SyntaxTreeFromLoadNoRemoveReplace {
get {
return ResourceManager.GetString("SyntaxTreeFromLoadNoRemoveReplace", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to SyntaxTree &apos;{0}&apos; not found to remove. /// Looks up a localized string similar to SyntaxTree &apos;{0}&apos; not found to remove.
/// </summary> /// </summary>
...@@ -9764,24 +9791,6 @@ internal class CSharpResources { ...@@ -9764,24 +9791,6 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to trees[{0}].
/// </summary>
internal static string Trees0 {
get {
return ResourceManager.GetString("Trees0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to trees[{0}] must have root node with SyntaxKind.CompilationUnit..
/// </summary>
internal static string TreesMustHaveRootNode {
get {
return ResourceManager.GetString("TreesMustHaveRootNode", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Type argument cannot be null. /// Looks up a localized string similar to Type argument cannot be null.
/// </summary> /// </summary>
......
...@@ -4161,15 +4161,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ ...@@ -4161,15 +4161,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="CantReferenceCompilationOf" xml:space="preserve"> <data name="CantReferenceCompilationOf" xml:space="preserve">
<value>Can't reference compilation of type '{0}' from {1} compilation.</value> <value>Can't reference compilation of type '{0}' from {1} compilation.</value>
</data> </data>
<data name="TreesMustHaveRootNode" xml:space="preserve">
<value>trees[{0}] must have root node with SyntaxKind.CompilationUnit.</value>
</data>
<data name="SyntaxTreeAlreadyPresent" xml:space="preserve"> <data name="SyntaxTreeAlreadyPresent" xml:space="preserve">
<value>Syntax tree already present</value> <value>Syntax tree already present</value>
</data> </data>
<data name="Trees0" xml:space="preserve">
<value>trees[{0}]</value>
</data>
<data name="SubmissionCanOnlyInclude" xml:space="preserve"> <data name="SubmissionCanOnlyInclude" xml:space="preserve">
<value>Submission can only include script code.</value> <value>Submission can only include script code.</value>
</data> </data>
...@@ -4647,4 +4641,14 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ ...@@ -4647,4 +4641,14 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_PPLoadFollowsToken" xml:space="preserve"> <data name="ERR_PPLoadFollowsToken" xml:space="preserve">
<value>Cannot use #load after first token in file</value> <value>Cannot use #load after first token in file</value>
</data> </data>
<data name="CouldNotFindFile" xml:space="preserve">
<value>Could not find file.</value>
<comment>File path referenced in source (#load) could not be resolved.</comment>
</data>
<data name="CannotHavePreviousSubmission" xml:space="preserve">
<value>Cannot have a previousSubmission when not a submission.</value>
</data>
<data name="SyntaxTreeFromLoadNoRemoveReplace" xml:space="preserve">
<value>SyntaxTree '{0}' resulted from a #load directive and cannot be removed or replaced directly.</value>
</data>
</root> </root>
\ No newline at end of file
// 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 System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed partial class SyntaxAndDeclarationManager : CommonSyntaxAndDeclarationManager
{
internal sealed class State
{
internal readonly ImmutableArray<SyntaxTree> SyntaxTrees; // In ordinal order.
internal readonly ImmutableDictionary<SyntaxTree, int> OrdinalMap; // Inverse of syntaxTrees array (i.e. maps tree to index)
internal readonly ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> LoadDirectiveMap;
internal readonly ImmutableDictionary<string, SyntaxTree> LoadedSyntaxTreeMap;
internal readonly ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> RootNamespaces;
internal readonly DeclarationTable DeclarationTable;
internal State(
ImmutableArray<SyntaxTree> syntaxTrees,
ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap,
ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMap,
ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap,
ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> rootNamespaces,
DeclarationTable declarationTable)
{
Debug.Assert(syntaxTrees.All(tree => syntaxTrees[syntaxTreeOrdinalMap[tree]] == tree));
Debug.Assert(syntaxTrees.SetEquals(rootNamespaces.Keys.AsImmutable(), EqualityComparer<SyntaxTree>.Default));
this.SyntaxTrees = syntaxTrees;
this.OrdinalMap = syntaxTreeOrdinalMap;
this.LoadDirectiveMap = loadDirectiveMap;
this.LoadedSyntaxTreeMap = loadedSyntaxTreeMap;
this.RootNamespaces = rootNamespaces;
this.DeclarationTable = declarationTable;
}
}
}
}
...@@ -110,6 +110,22 @@ internal bool HasReferenceDirectives ...@@ -110,6 +110,22 @@ internal bool HasReferenceDirectives
} }
} }
internal bool HasReferenceOrLoadDirectives
{
get
{
Debug.Assert(this.HasCompilationUnitRoot);
if (Options.Kind == SourceCodeKind.Interactive || Options.Kind == SourceCodeKind.Script)
{
var compilationUnitRoot = this.GetCompilationUnitRoot();
return compilationUnitRoot.GetReferenceDirectives().Count > 0 || compilationUnitRoot.GetLoadDirectives().Count > 0;
}
return false;
}
}
#region Preprocessor Symbols #region Preprocessor Symbols
private bool _hasDirectives; private bool _hasDirectives;
private InternalSyntax.DirectiveStack _directives; private InternalSyntax.DirectiveStack _directives;
......
...@@ -26,7 +26,7 @@ internal IList<ReferenceDirectiveTriviaSyntax> GetReferenceDirectives(Func<Refer ...@@ -26,7 +26,7 @@ internal IList<ReferenceDirectiveTriviaSyntax> GetReferenceDirectives(Func<Refer
} }
/// <summary> /// <summary>
/// Returns #r directives specified in the compilation. /// Returns #load directives specified in the compilation.
/// </summary> /// </summary>
public IList<LoadDirectiveTriviaSyntax> GetLoadDirectives() public IList<LoadDirectiveTriviaSyntax> GetLoadDirectives()
{ {
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
<Compile Include="Compilation\GetSemanticInfoTests.cs" /> <Compile Include="Compilation\GetSemanticInfoTests.cs" />
<Compile Include="Compilation\GetUnusedImportDirectivesTests.cs" /> <Compile Include="Compilation\GetUnusedImportDirectivesTests.cs" />
<Compile Include="Compilation\IndexedProperties_BindingTests.cs" /> <Compile Include="Compilation\IndexedProperties_BindingTests.cs" />
<Compile Include="Compilation\LoadDirectiveTests.cs" />
<Compile Include="Compilation\QueryClauseInfoTests.cs" /> <Compile Include="Compilation\QueryClauseInfoTests.cs" />
<Compile Include="Compilation\ReferenceManagerTests.cs" /> <Compile Include="Compilation\ReferenceManagerTests.cs" />
<Compile Include="Compilation\SemanticModelAPITests.cs" /> <Compile Include="Compilation\SemanticModelAPITests.cs" />
......
// 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 System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class LoadDirectiveTests : CSharpTestBase
{
[Fact]
void EmptyFile()
{
var code = "#load \"\"";
var compilation = CreateCompilation(code);
Assert.Single(compilation.SyntaxTrees);
compilation.GetDiagnostics().Verify(
// error CS1504: Source file '' could not be opened -- Could not find file.
Diagnostic(ErrorCode.ERR_NoSourceFile, "\"\"").WithArguments("", CSharpResources.CouldNotFindFile).WithLocation(1, 7));
}
[Fact]
void MissingFile()
{
var code = "#load \"missing\"";
var compilation = CreateCompilation(code);
Assert.Single(compilation.SyntaxTrees);
compilation.GetDiagnostics().Verify(
// error CS1504: Source file 'missing' could not be opened -- Could not find file.
Diagnostic(ErrorCode.ERR_NoSourceFile, "\"missing\"").WithArguments("missing", CSharpResources.CouldNotFindFile).WithLocation(1, 7));
}
[Fact]
void FileWithErrors()
{
var code = "#load \"a.csx\"";
var resolver = CreateResolver(
Script("a.csx", @"
#load ""b.csx""
asdf();"));
var compilation = CreateCompilation(code, resolver);
Assert.Equal(2, compilation.SyntaxTrees.Length);
compilation.GetParseDiagnostics().Verify(
// a.csx(2,27): error CS1504: Source file 'b.csx' could not be opened -- Could not find file.
// #load "b.csx";
Diagnostic(ErrorCode.ERR_NoSourceFile, @"""b.csx""").WithArguments("b.csx", "Could not find file.").WithLocation(2, 27));
compilation.GetDiagnostics().Verify(
// a.csx(2,27): error CS1504: Source file 'b.csx' could not be opened -- Could not find file.
// #load "b.csx";
Diagnostic(ErrorCode.ERR_NoSourceFile, @"""b.csx""").WithArguments("b.csx", "Could not find file.").WithLocation(2, 27),
// a.csx(3,21): error CS0103: The name 'asdf' does not exist in the current context
// asdf();
Diagnostic(ErrorCode.ERR_NameNotInContext, "asdf").WithArguments("asdf").WithLocation(3, 21));
}
private static CSharpCompilation CreateCompilation(string code, SourceReferenceResolver sourceReferenceResolver = null)
{
var options = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
sourceReferenceResolver: sourceReferenceResolver ?? TestSourceReferenceResolver.Default);
var parseOptions = new CSharpParseOptions(kind: SourceCodeKind.Interactive);
return CreateCompilationWithMscorlib(code, options: options, parseOptions: parseOptions);
}
private static SourceReferenceResolver CreateResolver(params KeyValuePair<string, string>[] scripts)
{
var sources = new Dictionary<string, string>();
foreach (var script in scripts)
{
sources.Add(script.Key, script.Value);
}
return new TestSourceReferenceResolver(sources);
}
private static KeyValuePair<string, string> Script(string path, string source)
{
return new KeyValuePair<string, string>(path, source);
}
private class TestSourceReferenceResolver : SourceReferenceResolver
{
private readonly IDictionary<string, string> _sources;
public static TestSourceReferenceResolver Default { get; } = new TestSourceReferenceResolver();
public TestSourceReferenceResolver(IDictionary<string, string> sources = null)
{
_sources = sources;
}
public override string NormalizePath(string path, string baseFilePath)
{
return path;
}
public override string ResolveReference(string path, string baseFilePath)
{
return ((_sources != null) && _sources.ContainsKey(path)) ? path : null;
}
public override Stream OpenRead(string resolvedPath)
{
if (_sources != null)
{
return new MemoryStream(Encoding.UTF8.GetBytes(_sources[resolvedPath]));
}
else
{
throw new IOException();
}
}
public override bool Equals(object other)
{
return this.Equals(other);
}
public override int GetHashCode()
{
return this.GetHashCode();
}
}
}
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
......
...@@ -135,6 +135,8 @@ ...@@ -135,6 +135,8 @@
<Compile Include="CommandLine\ErrorLogger.WellKnownStrings.cs" /> <Compile Include="CommandLine\ErrorLogger.WellKnownStrings.cs" />
<Compile Include="CommandLine\TouchedFileLogger.cs" /> <Compile Include="CommandLine\TouchedFileLogger.cs" />
<Compile Include="Compilation.EmitStreamProvider.cs" /> <Compile Include="Compilation.EmitStreamProvider.cs" />
<Compile Include="Compilation\LoadDirective.cs" />
<Compile Include="Compilation\CommonSyntaxAndDeclarationManager.cs" />
<Compile Include="Compilation\SymbolFilter.cs" /> <Compile Include="Compilation\SymbolFilter.cs" />
<Compile Include="CompilerPathUtilities.cs" /> <Compile Include="CompilerPathUtilities.cs" />
<Compile Include="DiagnosticAnalyzer\AnalysisResult.cs" /> <Compile Include="DiagnosticAnalyzer\AnalysisResult.cs" />
......
...@@ -150,40 +150,46 @@ internal SourceText ReadFileContent(CommandLineSourceFile file, IList<Diagnostic ...@@ -150,40 +150,46 @@ internal SourceText ReadFileContent(CommandLineSourceFile file, IList<Diagnostic
/// <returns>File content or null on failure.</returns> /// <returns>File content or null on failure.</returns>
internal SourceText ReadFileContent(CommandLineSourceFile file, IList<DiagnosticInfo> diagnostics, Encoding encoding, SourceHashAlgorithm checksumAlgorithm, out string normalizedFilePath) internal SourceText ReadFileContent(CommandLineSourceFile file, IList<DiagnosticInfo> diagnostics, Encoding encoding, SourceHashAlgorithm checksumAlgorithm, out string normalizedFilePath)
{ {
var filePath = file.Path;
try try
{ {
// PERF: Using a very small buffer size for the FileStream opens up an optimization within EncodedStringText where return ReadFileContentHelper(filePath, encoding, checksumAlgorithm, out normalizedFilePath);
// we read the entire FileStream into a byte array in one shot. For files that are actually smaller than the buffer
// size, FileStream.Read still allocates the internal buffer.
using (var data = PortableShim.FileStream.Create(file.Path, PortableShim.FileMode.Open, PortableShim.FileAccess.Read, PortableShim.FileShare.ReadWrite, bufferSize: 1, options: PortableShim.FileOptions.None))
{
normalizedFilePath = (string)PortableShim.FileStream.Name.GetValue(data);
return EncodedStringText.Create(data, encoding, checksumAlgorithm);
}
} }
catch (Exception e) catch (Exception e)
{ {
diagnostics.Add(ToFileReadDiagnostics(e, file)); diagnostics.Add(ToFileReadDiagnostics(this.MessageProvider, e, filePath));
normalizedFilePath = null; normalizedFilePath = null;
return null; return null;
} }
} }
private DiagnosticInfo ToFileReadDiagnostics(Exception e, CommandLineSourceFile file) internal static SourceText ReadFileContentHelper(string filePath, Encoding encoding, SourceHashAlgorithm checksumAlgorithm, out string normalizedFilePath)
{
// PERF: Using a very small buffer size for the FileStream opens up an optimization within EncodedStringText where
// we read the entire FileStream into a byte array in one shot. For files that are actually smaller than the buffer
// size, FileStream.Read still allocates the internal buffer.
using (var data = PortableShim.FileStream.Create(filePath, PortableShim.FileMode.Open, PortableShim.FileAccess.Read, PortableShim.FileShare.ReadWrite, bufferSize: 1, options: PortableShim.FileOptions.None))
{
normalizedFilePath = (string)PortableShim.FileStream.Name.GetValue(data);
return EncodedStringText.Create(data, encoding, checksumAlgorithm);
}
}
internal static DiagnosticInfo ToFileReadDiagnostics(CommonMessageProvider messageProvider, Exception e, string filePath)
{ {
DiagnosticInfo diagnosticInfo; DiagnosticInfo diagnosticInfo;
if (e is FileNotFoundException || e.GetType().Name == "DirectoryNotFoundException") if (e is FileNotFoundException || e.GetType().Name == "DirectoryNotFoundException")
{ {
diagnosticInfo = new DiagnosticInfo(MessageProvider, MessageProvider.ERR_FileNotFound, file.Path); diagnosticInfo = new DiagnosticInfo(messageProvider, messageProvider.ERR_FileNotFound, filePath);
} }
else if (e is InvalidDataException) else if (e is InvalidDataException)
{ {
diagnosticInfo = new DiagnosticInfo(MessageProvider, MessageProvider.ERR_BinaryFile, file.Path); diagnosticInfo = new DiagnosticInfo(messageProvider, messageProvider.ERR_BinaryFile, filePath);
} }
else else
{ {
diagnosticInfo = new DiagnosticInfo(MessageProvider, MessageProvider.ERR_NoSourceFile, file.Path, e.Message); diagnosticInfo = new DiagnosticInfo(messageProvider, messageProvider.ERR_NoSourceFile, filePath, e.Message);
} }
return diagnosticInfo; return diagnosticInfo;
......
// 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 System.Linq;
using System.Collections.Immutable;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis
{
internal abstract class CommonSyntaxAndDeclarationManager
{
internal readonly ImmutableArray<SyntaxTree> ExternalSyntaxTrees;
internal readonly string ScriptClassName;
internal readonly SourceReferenceResolver Resolver;
internal readonly CommonMessageProvider MessageProvider;
internal readonly bool IsSubmission;
private ImmutableDictionary<SyntaxTree, ImmutableArray<Diagnostic>> _syntaxTreeLoadDirectiveMap;
// This ImmutableDictionary will use default (case-sensitive) comparison
// for its keys. It is the responsibility of the SourceReferenceResolver
// to normalize the paths it resolves in a way that is appropriate for the
// platforms that the host supports.
private ImmutableDictionary<string, SyntaxTree> _resolvedFilePathSyntaxTreeMap;
public CommonSyntaxAndDeclarationManager(
ImmutableArray<SyntaxTree> externalSyntaxTrees,
string scriptClassName,
SourceReferenceResolver resolver,
CommonMessageProvider messageProvider,
bool isSubmission)
{
this.ExternalSyntaxTrees = externalSyntaxTrees;
this.ScriptClassName = scriptClassName ?? "";
this.Resolver = resolver; // TODO: What if SourceReferenceResolver is null?
this.MessageProvider = messageProvider;
this.IsSubmission = isSubmission;
}
}
}
...@@ -32,9 +32,6 @@ namespace Microsoft.CodeAnalysis ...@@ -32,9 +32,6 @@ namespace Microsoft.CodeAnalysis
/// </summary> /// </summary>
public abstract partial class Compilation public abstract partial class Compilation
{ {
// Inverse of syntaxTrees array (i.e. maps tree to index)
internal readonly ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap;
/// <summary> /// <summary>
/// Returns true if this is a case sensitive compilation, false otherwise. Case sensitivity /// Returns true if this is a case sensitive compilation, false otherwise. Case sensitivity
/// affects compilation features such as name lookup as well as choosing what names to emit /// affects compilation features such as name lookup as well as choosing what names to emit
...@@ -58,17 +55,17 @@ public abstract partial class Compilation ...@@ -58,17 +55,17 @@ public abstract partial class Compilation
internal Compilation( internal Compilation(
string name, string name,
ImmutableArray<MetadataReference> references, ImmutableArray<MetadataReference> references,
IReadOnlyDictionary<string, string> features,
Type submissionReturnType, Type submissionReturnType,
Type hostObjectType, Type hostObjectType,
bool isSubmission, bool isSubmission,
ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap,
AsyncQueue<CompilationEvent> eventQueue) AsyncQueue<CompilationEvent> eventQueue)
{ {
Debug.Assert(!references.IsDefault); Debug.Assert(!references.IsDefault);
Debug.Assert(features != null);
this.AssemblyName = name; this.AssemblyName = name;
this.ExternalReferences = references; this.ExternalReferences = references;
this.syntaxTreeOrdinalMap = syntaxTreeOrdinalMap;
this.EventQueue = eventQueue; this.EventQueue = eventQueue;
if (isSubmission) if (isSubmission)
...@@ -82,10 +79,10 @@ public abstract partial class Compilation ...@@ -82,10 +79,10 @@ public abstract partial class Compilation
_lazySubmissionSlotIndex = SubmissionSlotIndexNotApplicable; _lazySubmissionSlotIndex = SubmissionSlotIndexNotApplicable;
} }
_features = SyntaxTreeCommonFeatures(syntaxTreeOrdinalMap.Keys); _features = features;
} }
private IReadOnlyDictionary<string, string> SyntaxTreeCommonFeatures(IEnumerable<SyntaxTree> trees) protected static IReadOnlyDictionary<string, string> SyntaxTreeCommonFeatures(IEnumerable<SyntaxTree> trees)
{ {
IReadOnlyDictionary<string, string> set = null; IReadOnlyDictionary<string, string> set = null;
...@@ -2137,14 +2134,10 @@ internal int CompareSyntaxTreeOrdering(SyntaxTree tree1, SyntaxTree tree2) ...@@ -2137,14 +2134,10 @@ internal int CompareSyntaxTreeOrdering(SyntaxTree tree1, SyntaxTree tree2)
Debug.Assert(this.ContainsSyntaxTree(tree1)); Debug.Assert(this.ContainsSyntaxTree(tree1));
Debug.Assert(this.ContainsSyntaxTree(tree2)); Debug.Assert(this.ContainsSyntaxTree(tree2));
return this.syntaxTreeOrdinalMap[tree1] - this.syntaxTreeOrdinalMap[tree2]; return this.GetSyntaxTreeOrdinal(tree1) - this.GetSyntaxTreeOrdinal(tree2);
} }
internal int GetSyntaxTreeOrdinal(SyntaxTree tree) internal abstract int GetSyntaxTreeOrdinal(SyntaxTree tree);
{
Debug.Assert(this.ContainsSyntaxTree(tree));
return this.syntaxTreeOrdinalMap[tree];
}
/// <summary> /// <summary>
/// Compare two source locations, using their containing trees, and then by Span.First within a tree. /// Compare two source locations, using their containing trees, and then by Span.First within a tree.
......
// 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 System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
internal struct LoadDirective : IEquatable<LoadDirective>
{
public readonly string ResolvedPath;
public readonly ImmutableArray<Diagnostic> Diagnostics;
public LoadDirective(string resolvedPath, ImmutableArray<Diagnostic> diagnostics)
{
Debug.Assert((resolvedPath != null) || !diagnostics.IsEmpty);
Debug.Assert(!diagnostics.IsDefault);
Debug.Assert(diagnostics.IsEmpty || diagnostics.All(d => d.Severity == DiagnosticSeverity.Error));
ResolvedPath = resolvedPath;
Diagnostics = diagnostics;
}
public bool Equals(LoadDirective other)
{
return this.ResolvedPath == other.ResolvedPath &&
this.Diagnostics.SequenceEqual(other.Diagnostics);
}
public override bool Equals(object obj)
{
return obj is LoadDirective && Equals((LoadDirective)obj);
}
public override int GetHashCode()
{
return Hash.Combine(this.Diagnostics.GetHashCode(), this.ResolvedPath.GetHashCode());
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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 System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis namespace Microsoft.CodeAnalysis
{ {
...@@ -53,5 +55,14 @@ internal Stream OpenReadChecked(string fullPath) ...@@ -53,5 +55,14 @@ internal Stream OpenReadChecked(string fullPath)
return stream; return stream;
} }
/// <summary>
/// Reads the contents of <paramref name="resolvedPath"/> and returns a <see cref="SourceText"/>.
/// </summary>
/// <param name="resolvedPath">Path returned by <see cref="ResolveReference(string, string)"/>.</param>
public virtual SourceText ReadText(string resolvedPath)
{
return SourceText.From(OpenRead(resolvedPath));
}
} }
} }
...@@ -48,4 +48,5 @@ static Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzerExtensions.WithAnaly ...@@ -48,4 +48,5 @@ static Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzerExtensions.WithAnaly
static Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetry.GetAnalyzerActionCountsAsync(this Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers compilationWithAnalyzers, Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer analyzer, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetry.ActionCounts> static Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetry.GetAnalyzerActionCountsAsync(this Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers compilationWithAnalyzers, Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer analyzer, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetry.ActionCounts>
static Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetry.GetAnalyzerExecutionTime(this Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers compilationWithAnalyzers, Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer analyzer) -> System.TimeSpan static Microsoft.CodeAnalysis.Diagnostics.Telemetry.AnalyzerTelemetry.GetAnalyzerExecutionTime(this Microsoft.CodeAnalysis.Diagnostics.CompilationWithAnalyzers compilationWithAnalyzers, Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer analyzer) -> System.TimeSpan
static Microsoft.CodeAnalysis.SyntaxNodeExtensions.NormalizeWhitespace<TNode>(this TNode node, string indentation = " ", string eol = "\r\n", bool elasticTrivia = false) -> TNode static Microsoft.CodeAnalysis.SyntaxNodeExtensions.NormalizeWhitespace<TNode>(this TNode node, string indentation = " ", string eol = "\r\n", bool elasticTrivia = false) -> TNode
static Microsoft.CodeAnalysis.SyntaxNodeExtensions.NormalizeWhitespace<TNode>(this TNode node, string indentation, bool elasticTrivia) -> TNode static Microsoft.CodeAnalysis.SyntaxNodeExtensions.NormalizeWhitespace<TNode>(this TNode node, string indentation, bool elasticTrivia) -> TNode
\ No newline at end of file virtual Microsoft.CodeAnalysis.SourceReferenceResolver.ReadText(string resolvedPath) -> Microsoft.CodeAnalysis.Text.SourceText
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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 System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using Roslyn.Utilities; using Roslyn.Utilities;
...@@ -17,6 +18,13 @@ private PooledDictionary(ObjectPool<PooledDictionary<K, V>> pool) ...@@ -17,6 +18,13 @@ private PooledDictionary(ObjectPool<PooledDictionary<K, V>> pool)
_pool = pool; _pool = pool;
} }
public ImmutableDictionary<K, V> ToImmutableDictionaryAndFree()
{
var result = this.ToImmutableDictionary();
this.Free();
return result;
}
public void Free() public void Free()
{ {
this.Clear(); this.Clear();
......
...@@ -80,6 +80,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -80,6 +80,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' </summary> ''' </summary>
Private ReadOnly _syntaxTrees As ImmutableArray(Of SyntaxTree) Private ReadOnly _syntaxTrees As ImmutableArray(Of SyntaxTree)
Private ReadOnly _syntaxTreeOrdinalMap As ImmutableDictionary(Of SyntaxTree, Integer)
''' <summary> ''' <summary>
''' The syntax trees of this compilation plus all 'hidden' trees ''' The syntax trees of this compilation plus all 'hidden' trees
''' added to the compilation by compiler, e.g. Vb Core Runtime. ''' added to the compilation by compiler, e.g. Vb Core Runtime.
...@@ -411,7 +413,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -411,7 +413,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
reuseReferenceManager As Boolean, reuseReferenceManager As Boolean,
Optional eventQueue As AsyncQueue(Of CompilationEvent) = Nothing Optional eventQueue As AsyncQueue(Of CompilationEvent) = Nothing
) )
MyBase.New(assemblyName, references, submissionReturnType, hostObjectType, isSubmission, syntaxTreeOrdinalMap, eventQueue) MyBase.New(assemblyName, references, SyntaxTreeCommonFeatures(syntaxTrees), submissionReturnType, hostObjectType, isSubmission, eventQueue)
Debug.Assert(rootNamespaces IsNot Nothing) Debug.Assert(rootNamespaces IsNot Nothing)
Debug.Assert(declarationTable IsNot Nothing) Debug.Assert(declarationTable IsNot Nothing)
...@@ -421,6 +423,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -421,6 +423,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
_options = options _options = options
_syntaxTrees = syntaxTrees _syntaxTrees = syntaxTrees
_syntaxTreeOrdinalMap = syntaxTreeOrdinalMap
_rootNamespaces = rootNamespaces _rootNamespaces = rootNamespaces
_embeddedTrees = embeddedTrees _embeddedTrees = embeddedTrees
_declarationTable = declarationTable _declarationTable = declarationTable
...@@ -486,7 +489,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -486,7 +489,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
_options, _options,
Me.ExternalReferences, Me.ExternalReferences,
_syntaxTrees, _syntaxTrees,
Me.syntaxTreeOrdinalMap, _syntaxTreeOrdinalMap,
_rootNamespaces, _rootNamespaces,
_embeddedTrees, _embeddedTrees,
_declarationTable, _declarationTable,
...@@ -538,7 +541,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -538,7 +541,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Me.Options, Me.Options,
Me.ExternalReferences, Me.ExternalReferences,
_syntaxTrees, _syntaxTrees,
Me.syntaxTreeOrdinalMap, _syntaxTreeOrdinalMap,
_rootNamespaces, _rootNamespaces,
_embeddedTrees, _embeddedTrees,
_declarationTable, _declarationTable,
...@@ -579,7 +582,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -579,7 +582,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Me.Options, Me.Options,
ValidateReferences(Of VisualBasicCompilationReference)(newReferences), ValidateReferences(Of VisualBasicCompilationReference)(newReferences),
_syntaxTrees, _syntaxTrees,
Me.syntaxTreeOrdinalMap, _syntaxTreeOrdinalMap,
_rootNamespaces, _rootNamespaces,
embeddedTrees, embeddedTrees,
declTable, declTable,
...@@ -632,7 +635,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -632,7 +635,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
newOptions, newOptions,
Me.ExternalReferences, Me.ExternalReferences,
_syntaxTrees, _syntaxTrees,
Me.syntaxTreeOrdinalMap, _syntaxTreeOrdinalMap,
declMap, declMap,
embeddedTrees, embeddedTrees,
declTable, declTable,
...@@ -660,7 +663,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -660,7 +663,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Me.Options, Me.Options,
Me.ExternalReferences, Me.ExternalReferences,
_syntaxTrees, _syntaxTrees,
Me.syntaxTreeOrdinalMap, _syntaxTreeOrdinalMap,
_rootNamespaces, _rootNamespaces,
_embeddedTrees, _embeddedTrees,
_declarationTable, _declarationTable,
...@@ -681,7 +684,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -681,7 +684,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Me.Options, Me.Options,
Me.ExternalReferences, Me.ExternalReferences,
_syntaxTrees, _syntaxTrees,
Me.syntaxTreeOrdinalMap, _syntaxTreeOrdinalMap,
_rootNamespaces, _rootNamespaces,
_embeddedTrees, _embeddedTrees,
_declarationTable, _declarationTable,
...@@ -845,7 +848,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -845,7 +848,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim referenceDirectivesChanged = False Dim referenceDirectivesChanged = False
Dim oldTreeCount = _syntaxTrees.Length Dim oldTreeCount = _syntaxTrees.Length
Dim ordinalMap = Me.syntaxTreeOrdinalMap Dim ordinalMap = _syntaxTreeOrdinalMap
Dim declMap = _rootNamespaces Dim declMap = _rootNamespaces
Dim declTable = _declarationTable Dim declTable = _declarationTable
Dim i = 0 Dim i = 0
...@@ -1020,7 +1023,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1020,7 +1023,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
RemoveSyntaxTreeFromDeclarationMapAndTable(vbOldTree, declMap, declTable, referenceDirectivesChanged) RemoveSyntaxTreeFromDeclarationMapAndTable(vbOldTree, declMap, declTable, referenceDirectivesChanged)
AddSyntaxTreeToDeclarationMapAndTable(vbNewTree, _options, Me.IsSubmission, declMap, declTable, referenceDirectivesChanged) AddSyntaxTreeToDeclarationMapAndTable(vbNewTree, _options, Me.IsSubmission, declMap, declTable, referenceDirectivesChanged)
Dim ordinalMap = Me.syntaxTreeOrdinalMap Dim ordinalMap = _syntaxTreeOrdinalMap
Debug.Assert(ordinalMap.ContainsKey(oldTree)) ' Checked by RemoveSyntaxTreeFromDeclarationMapAndTable Debug.Assert(ordinalMap.ContainsKey(oldTree)) ' Checked by RemoveSyntaxTreeFromDeclarationMapAndTable
Dim oldOrdinal = ordinalMap(oldTree) Dim oldOrdinal = ordinalMap(oldTree)
...@@ -1159,6 +1162,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1159,6 +1162,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return LexicalSortKey.Compare(first, second, Me) Return LexicalSortKey.Compare(first, second, Me)
End Function End Function
Friend Overrides Function GetSyntaxTreeOrdinal(tree As SyntaxTree) As Integer
Debug.Assert(Me.ContainsSyntaxTree(tree))
Return _syntaxTreeOrdinalMap(tree)
End Function
#End Region #End Region
#Region "References" #Region "References"
......
...@@ -420,8 +420,8 @@ public void AsyncExecuteFile_ScriptFileWithBuildErrors() ...@@ -420,8 +420,8 @@ public void AsyncExecuteFile_ScriptFileWithBuildErrors()
Host.ExecuteFileAsync(file.Path).Wait(); Host.ExecuteFileAsync(file.Path).Wait();
var errorOut = ReadErrorOutputToEnd().Trim(); var errorOut = ReadErrorOutputToEnd().Trim();
Assert.True(errorOut.StartsWith(file.Path + "(1,2):", StringComparison.Ordinal), "Error output should start with file name, line and column"); Assert.True(errorOut.StartsWith(file.Path + "(1,7):", StringComparison.Ordinal), "Error output should start with file name, line and column");
Assert.True(errorOut.Contains("CS1024"), "Error output should include error CS1024"); Assert.True(errorOut.Contains("CS7010"), "Error output should include error CS7010");
} }
/// <summary> /// <summary>
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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 System; using System;
using System.Collections.Immutable;
using System.Globalization; using System.Globalization;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Scripting.CSharp namespace Microsoft.CodeAnalysis.Scripting.CSharp
{ {
...@@ -44,12 +46,12 @@ public override Compilation CreateSubmission(Script script) ...@@ -44,12 +46,12 @@ public override Compilation CreateSubmission(Script script)
scriptClassName: submissionTypeName, scriptClassName: submissionTypeName,
usings: script.Options.Namespaces, usings: script.Options.Namespaces,
optimizationLevel: OptimizationLevel.Debug, // TODO optimizationLevel: OptimizationLevel.Debug, // TODO
checkOverflow: false, // TODO checkOverflow: false, // TODO
allowUnsafe: true, // TODO allowUnsafe: true, // TODO
platform: Platform.AnyCpu, platform: Platform.AnyCpu,
warningLevel: 4, warningLevel: 4,
xmlReferenceResolver: null, // don't support XML file references in interactive (permissions & doc comment includes) xmlReferenceResolver: null, // don't support XML file references in interactive (permissions & doc comment includes)
sourceReferenceResolver: SourceFileResolver.Default, // TODO sourceReferenceResolver: LoadDirectiveResolver.Default,
metadataReferenceResolver: script.Options.ReferenceResolver, metadataReferenceResolver: script.Options.ReferenceResolver,
assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default
), ),
...@@ -60,5 +62,25 @@ public override Compilation CreateSubmission(Script script) ...@@ -60,5 +62,25 @@ public override Compilation CreateSubmission(Script script)
return compilation; return compilation;
} }
private class LoadDirectiveResolver : SourceFileResolver
{
public static new LoadDirectiveResolver Default { get; } = new LoadDirectiveResolver();
private LoadDirectiveResolver()
: base(ImmutableArray<string>.Empty, baseDirectory: null)
{
}
public override SourceText ReadText(string resolvedPath)
{
string unused;
return CommonCompiler.ReadFileContentHelper(
resolvedPath,
encoding: null,
checksumAlgorithm: SourceHashAlgorithm.Sha1, // TODO: Should we be fetching the checksum algorithm from somewhere?
normalizedFilePath: out unused);
}
}
} }
} }
...@@ -54,11 +54,6 @@ ...@@ -54,11 +54,6 @@
<Compile Include="CSharpObjectFormatter.cs" /> <Compile Include="CSharpObjectFormatter.cs" />
<Compile Include="CSharpScript.cs" /> <Compile Include="CSharpScript.cs" />
<Compile Include="CSharpScriptCompiler.cs" /> <Compile Include="CSharpScriptCompiler.cs" />
<Compile Include="CSharpScriptingResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>CSharpScriptingResources.resx</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<InternalsVisibleToTest Include="Roslyn.Compilers.CSharp.Emit.UnitTests" /> <InternalsVisibleToTest Include="Roslyn.Compilers.CSharp.Emit.UnitTests" />
...@@ -67,12 +62,6 @@ ...@@ -67,12 +62,6 @@
<InternalsVisibleToTest Include="Microsoft.CodeAnalysis.Scripting.UnitTests" /> <InternalsVisibleToTest Include="Microsoft.CodeAnalysis.Scripting.UnitTests" />
<InternalsVisibleToTest Include="Microsoft.CodeAnalysis.Scripting.CSharp.UnitTests" /> <InternalsVisibleToTest Include="Microsoft.CodeAnalysis.Scripting.CSharp.UnitTests" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="CSharpScriptingResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>CSharpScriptingResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="project.json" /> <None Include="project.json" />
</ItemGroup> </ItemGroup>
......
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.CodeAnalysis.Scripting.CSharp {
using System;
using System.Reflection;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class CSharpScriptingResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal CSharpScriptingResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.CodeAnalysis.Scripting.CSharp.CSharpScriptingResources", typeof(CSharpScriptingResources).GetTypeInfo().Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file
...@@ -24,7 +24,7 @@ public abstract class Script ...@@ -24,7 +24,7 @@ public abstract class Script
private ScriptBuilder _lazyBuilder; private ScriptBuilder _lazyBuilder;
private Compilation _lazyCompilation; private Compilation _lazyCompilation;
internal Script(ScriptCompiler compiler, string code, ScriptOptions options, Type globalsType, ScriptBuilder builder, Script previous) internal Script(ScriptCompiler compiler, string code, ScriptOptions options, Type globalsType, ScriptBuilder builder, Script previous)
{ {
Compiler = compiler; Compiler = compiler;
...@@ -116,7 +116,7 @@ internal ScriptBuilder Builder ...@@ -116,7 +116,7 @@ internal ScriptBuilder Builder
/// <param name="globalsType">The type that defines members that can be accessed by the script.</param> /// <param name="globalsType">The type that defines members that can be accessed by the script.</param>
public Script WithGlobalsType(Type globalsType) => this.WithGlobalsTypeInternal(globalsType); public Script WithGlobalsType(Type globalsType) => this.WithGlobalsTypeInternal(globalsType);
internal abstract Script WithGlobalsTypeInternal(Type globalsType); internal abstract Script WithGlobalsTypeInternal(Type globalsType);
/// <summary> /// <summary>
/// Continues the script with given code snippet. /// Continues the script with given code snippet.
/// </summary> /// </summary>
...@@ -215,14 +215,14 @@ internal ImmutableArray<MetadataReference> GetReferencesForCompilation() ...@@ -215,14 +215,14 @@ internal ImmutableArray<MetadataReference> GetReferencesForCompilation()
references = references.Add(corLib); references = references.Add(corLib);
if (this.GlobalsType != null) if (this.GlobalsType != null)
{ {
var globalsTypeAssembly = MetadataReference.CreateFromAssemblyInternal(this.GlobalsType.GetTypeInfo().Assembly); var globalsTypeAssembly = MetadataReference.CreateFromAssemblyInternal(this.GlobalsType.GetTypeInfo().Assembly);
references = references.Add(globalsTypeAssembly); references = references.Add(globalsTypeAssembly);
} }
return references; return references;
} }
} }
public sealed class Script<T> : Script public sealed class Script<T> : Script
{ {
...@@ -248,19 +248,19 @@ public new Script<T> WithCode(string code) ...@@ -248,19 +248,19 @@ public new Script<T> WithCode(string code)
if (code == null) if (code == null)
{ {
code = ""; code = "";
} }
return (code == this.Code) ? return (code == this.Code) ?
this : this :
new Script<T>(this.Compiler, code, this.Options, this.GlobalsType, this.LazyBuilder, this.Previous); new Script<T>(this.Compiler, code, this.Options, this.GlobalsType, this.LazyBuilder, this.Previous);
} }
public new Script<T> WithGlobalsType(Type globalsType) public new Script<T> WithGlobalsType(Type globalsType)
{ {
return (globalsType == this.GlobalsType) ? return (globalsType == this.GlobalsType) ?
this : this :
new Script<T>(this.Compiler, this.Code, this.Options, globalsType, this.LazyBuilder, this.Previous); new Script<T>(this.Compiler, this.Code, this.Options, globalsType, this.LazyBuilder, this.Previous);
} }
internal override Script WithOptionsInternal(ScriptOptions options) => WithOptions(options); internal override Script WithOptionsInternal(ScriptOptions options) => WithOptions(options);
internal override Script WithCodeInternal(string code) => WithCode(code); internal override Script WithCodeInternal(string code) => WithCode(code);
...@@ -268,10 +268,10 @@ public new Script<T> WithGlobalsType(Type globalsType) ...@@ -268,10 +268,10 @@ public new Script<T> WithGlobalsType(Type globalsType)
/// <exception cref="CompilationErrorException">Compilation has errors.</exception> /// <exception cref="CompilationErrorException">Compilation has errors.</exception>
internal override void CommonBuild(CancellationToken cancellationToken) internal override void CommonBuild(CancellationToken cancellationToken)
{ {
GetPrecedingExecutors(cancellationToken); GetPrecedingExecutors(cancellationToken);
GetExecutor(cancellationToken); GetExecutor(cancellationToken);
} }
internal override Func<object[], Task> CommonGetExecutor(CancellationToken cancellationToken) internal override Func<object[], Task> CommonGetExecutor(CancellationToken cancellationToken)
=> GetExecutor(cancellationToken); => GetExecutor(cancellationToken);
...@@ -304,7 +304,7 @@ internal override void CommonBuild(CancellationToken cancellationToken) ...@@ -304,7 +304,7 @@ internal override void CommonBuild(CancellationToken cancellationToken)
var preceding = TryGetPrecedingExecutors(null, cancellationToken); var preceding = TryGetPrecedingExecutors(null, cancellationToken);
Debug.Assert(!preceding.IsDefault); Debug.Assert(!preceding.IsDefault);
InterlockedOperations.Initialize(ref _lazyPrecedingExecutors, preceding); InterlockedOperations.Initialize(ref _lazyPrecedingExecutors, preceding);
} }
return _lazyPrecedingExecutors; return _lazyPrecedingExecutors;
} }
...@@ -314,32 +314,32 @@ internal override void CommonBuild(CancellationToken cancellationToken) ...@@ -314,32 +314,32 @@ internal override void CommonBuild(CancellationToken cancellationToken)
{ {
Script script = Previous; Script script = Previous;
if (script == lastExecutedScriptInChainOpt) if (script == lastExecutedScriptInChainOpt)
{ {
return ImmutableArray<Func<object[], Task>>.Empty; return ImmutableArray<Func<object[], Task>>.Empty;
} }
var scriptsReversed = ArrayBuilder<Script>.GetInstance(); var scriptsReversed = ArrayBuilder<Script>.GetInstance();
while (script != null && script != lastExecutedScriptInChainOpt) while (script != null && script != lastExecutedScriptInChainOpt)
{ {
scriptsReversed.Add(script); scriptsReversed.Add(script);
script = script.Previous; script = script.Previous;
} }
if (lastExecutedScriptInChainOpt != null && script != lastExecutedScriptInChainOpt) if (lastExecutedScriptInChainOpt != null && script != lastExecutedScriptInChainOpt)
{ {
scriptsReversed.Free(); scriptsReversed.Free();
return default(ImmutableArray<Func<object[], Task>>); return default(ImmutableArray<Func<object[], Task>>);
} }
var executors = ArrayBuilder<Func<object[], Task>>.GetInstance(scriptsReversed.Count); var executors = ArrayBuilder<Func<object[], Task>>.GetInstance(scriptsReversed.Count);
// We need to build executors in the order in which they are chained, // We need to build executors in the order in which they are chained,
// so that assemblies created for the submissions are loaded in the correct order. // so that assemblies created for the submissions are loaded in the correct order.
for (int i = scriptsReversed.Count - 1; i >= 0; i--) for (int i = scriptsReversed.Count - 1; i >= 0; i--)
{ {
executors.Add(scriptsReversed[i].CommonGetExecutor(cancellationToken)); executors.Add(scriptsReversed[i].CommonGetExecutor(cancellationToken));
} }
return executors.ToImmutableAndFree(); return executors.ToImmutableAndFree();
} }
...@@ -379,7 +379,7 @@ public new Task<ScriptState<T>> RunAsync(object globals = null, CancellationToke ...@@ -379,7 +379,7 @@ public new Task<ScriptState<T>> RunAsync(object globals = null, CancellationToke
var currentExecutor = GetExecutor(cancellationToken); var currentExecutor = GetExecutor(cancellationToken);
return RunSubmissionsAsync(executionState, precedingExecutors, currentExecutor, cancellationToken); return RunSubmissionsAsync(executionState, precedingExecutors, currentExecutor, cancellationToken);
} }
/// <summary> /// <summary>
/// Creates a delegate that will run this script from the beginning when invoked. /// Creates a delegate that will run this script from the beginning when invoked.
...@@ -388,7 +388,7 @@ public new Task<ScriptState<T>> RunAsync(object globals = null, CancellationToke ...@@ -388,7 +388,7 @@ public new Task<ScriptState<T>> RunAsync(object globals = null, CancellationToke
/// The delegate doesn't hold on this script or its compilation. /// The delegate doesn't hold on this script or its compilation.
/// </remarks> /// </remarks>
public ScriptRunner<T> CreateDelegate(CancellationToken cancellationToken = default(CancellationToken)) public ScriptRunner<T> CreateDelegate(CancellationToken cancellationToken = default(CancellationToken))
{ {
var precedingExecutors = GetPrecedingExecutors(cancellationToken); var precedingExecutors = GetPrecedingExecutors(cancellationToken);
var currentExecutor = GetExecutor(cancellationToken); var currentExecutor = GetExecutor(cancellationToken);
var globalsType = GlobalsType; var globalsType = GlobalsType;
...@@ -411,26 +411,26 @@ public ScriptRunner<T> CreateDelegate(CancellationToken cancellationToken = defa ...@@ -411,26 +411,26 @@ public ScriptRunner<T> CreateDelegate(CancellationToken cancellationToken = defa
/// <exception cref="ArgumentNullException"><paramref name="previousState"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="previousState"/> is null.</exception>
/// <exception cref="ArgumentException"><paramref name="previousState"/> is not a previous execution state of this script.</exception> /// <exception cref="ArgumentException"><paramref name="previousState"/> is not a previous execution state of this script.</exception>
public new Task<ScriptState<T>> ContinueAsync(ScriptState previousState, CancellationToken cancellationToken = default(CancellationToken)) public new Task<ScriptState<T>> ContinueAsync(ScriptState previousState, CancellationToken cancellationToken = default(CancellationToken))
{ {
// The following validation and executor contruction may throw; // The following validation and executor contruction may throw;
// do so synchronously so that the exception is not wrapped in the task. // do so synchronously so that the exception is not wrapped in the task.
if (previousState == null) if (previousState == null)
{ {
throw new ArgumentNullException(nameof(previousState)); throw new ArgumentNullException(nameof(previousState));
} }
if (previousState.Script == this) if (previousState.Script == this)
{ {
// this state is already the output of running this script. // this state is already the output of running this script.
return Task.FromResult((ScriptState<T>)previousState); return Task.FromResult((ScriptState<T>)previousState);
} }
var precedingExecutors = TryGetPrecedingExecutors(previousState.Script, cancellationToken); var precedingExecutors = TryGetPrecedingExecutors(previousState.Script, cancellationToken);
if (precedingExecutors.IsDefault) if (precedingExecutors.IsDefault)
{ {
throw new ArgumentException(ScriptingResources.StartingStateIncompatible, nameof(previousState)); throw new ArgumentException(ScriptingResources.StartingStateIncompatible, nameof(previousState));
} }
var currentExecutor = GetExecutor(cancellationToken); var currentExecutor = GetExecutor(cancellationToken);
ScriptExecutionState newExecutionState = previousState.ExecutionState.FreezeAndClone(); ScriptExecutionState newExecutionState = previousState.ExecutionState.FreezeAndClone();
...@@ -447,22 +447,22 @@ private async Task<ScriptState<T>> RunSubmissionsAsync(ScriptExecutionState exec ...@@ -447,22 +447,22 @@ private async Task<ScriptState<T>> RunSubmissionsAsync(ScriptExecutionState exec
private static void ValidateGlobals(object globals, Type globalsType) private static void ValidateGlobals(object globals, Type globalsType)
{ {
if (globalsType != null) if (globalsType != null)
{ {
if (globals == null) if (globals == null)
{ {
throw new ArgumentException(ScriptingResources.ScriptRequiresGlobalVariables, nameof(globals)); throw new ArgumentException(ScriptingResources.ScriptRequiresGlobalVariables, nameof(globals));
} }
var runtimeType = globals.GetType().GetTypeInfo(); var runtimeType = globals.GetType().GetTypeInfo();
var globalsTypeInfo = globalsType.GetTypeInfo(); var globalsTypeInfo = globalsType.GetTypeInfo();
if (!globalsTypeInfo.IsAssignableFrom(runtimeType)) if (!globalsTypeInfo.IsAssignableFrom(runtimeType))
{ {
throw new ArgumentException(string.Format(ScriptingResources.GlobalsNotAssignable, runtimeType, globalsTypeInfo), nameof(globals)); throw new ArgumentException(string.Format(ScriptingResources.GlobalsNotAssignable, runtimeType, globalsTypeInfo), nameof(globals));
} }
} }
else if (globals != null) else if (globals != null)
{ {
throw new ArgumentException(ScriptingResources.GlobalVariablesWithoutGlobalType, nameof(globals)); throw new ArgumentException(ScriptingResources.GlobalVariablesWithoutGlobalType, nameof(globals));
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册