This commit is contained in:
Andrey Shchekin 2017-05-14 20:55:22 +12:00
Родитель 0ee30a7681
Коммит e652e24cc3
20 изменённых файлов: 225 добавлений и 91 удалений

Просмотреть файл

@ -1,4 +1,4 @@
using System.Collections.Immutable;
using System.Collections.Generic;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
@ -7,8 +7,7 @@ namespace MirrorSharp.Internal.Abstraction {
[NotNull] string Name { get; }
[NotNull] ParseOptions DefaultParseOptions { get; }
[NotNull] CompilationOptions DefaultCompilationOptions { get; }
[NotNull] [ItemNotNull] ImmutableList<MetadataReference> DefaultAssemblyReferences { get; }
[NotNull] ILanguageSession CreateSession([NotNull] string text, ParseOptions parseOptions, CompilationOptions compilationOptions, ImmutableList<MetadataReference> metadataReferences);
[NotNull] ILanguageSession CreateSession([NotNull] string text, ParseOptions parseOptions, CompilationOptions compilationOptions, [CanBeNull] IReadOnlyCollection<MetadataReference> assemblyReferences);
}
}

Просмотреть файл

@ -26,7 +26,7 @@ namespace MirrorSharp.Internal {
if (name == "F#") {
var type = Type.GetType("MirrorSharp.FSharp.FSharpLanguage, MirrorSharp.FSharp", true);
return (ILanguage)Activator.CreateInstance(type);
return (ILanguage)Activator.CreateInstance(type, nonPublic: true);
}
throw new NotSupportedException($"Language '{name}' is not currently supported.");

Просмотреть файл

@ -19,6 +19,7 @@ namespace MirrorSharp.Internal.Roslyn {
private readonly ImmutableDictionary<string, ImmutableArray<CodeFixProvider>> _defaultCodeFixProvidersIndexedByDiagnosticIds;
private readonly ImmutableArray<DiagnosticAnalyzer> _defaultAnalyzers;
private readonly ImmutableList<AnalyzerReference> _defaultAnalyzerReferences;
private readonly ImmutableList<MetadataReference> _defaultAssemblyReferences;
protected RoslynLanguageBase(
[NotNull] string name,
@ -37,7 +38,7 @@ namespace MirrorSharp.Internal.Roslyn {
});
DefaultParseOptions = defaultParseOptions;
DefaultCompilationOptions = defaultCompilationOptions;
DefaultAssemblyReferences = ImmutableList.Create<MetadataReference>(
_defaultAssemblyReferences = ImmutableList.Create<MetadataReference>(
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)
);
_defaultAnalyzerReferences = ImmutableList.Create<AnalyzerReference>(
@ -54,15 +55,14 @@ namespace MirrorSharp.Internal.Roslyn {
public string Name { get; }
public ParseOptions DefaultParseOptions { get; }
public CompilationOptions DefaultCompilationOptions { get; }
public ImmutableList<MetadataReference> DefaultAssemblyReferences { get; }
public ILanguageSession CreateSession(string text, ParseOptions parseOptions, CompilationOptions compilationOptions, ImmutableList<MetadataReference> metadataReferences) {
public ILanguageSession CreateSession(string text, ParseOptions parseOptions, CompilationOptions compilationOptions, IReadOnlyCollection<MetadataReference> assemblyReferences) {
var projectId = ProjectId.CreateNewId();
var projectInfo = ProjectInfo.Create(
projectId, VersionStamp.Create(), "_", "_", Name,
parseOptions: parseOptions,
compilationOptions: compilationOptions,
metadataReferences: metadataReferences,
metadataReferences: assemblyReferences ?? _defaultAssemblyReferences,
analyzerReferences: _defaultAnalyzerReferences
);

Просмотреть файл

@ -70,9 +70,8 @@ namespace MirrorSharp.Internal {
foreach (var change in _compilationOptionsChanges.Values) {
compilationOptions = change(compilationOptions);
}
var metadataReferences = _options?.GetDefaultMetadataReferencesByLanguageName?.Invoke(Language.Name) ?? Language.DefaultAssemblyReferences;
_languageSession = Language.CreateSession(_lastText, parseOptions, compilationOptions, metadataReferences);
var assemblyReferences = _options?.GetDefaultMetadataReferencesByLanguageName?.Invoke(Language.Name);
_languageSession = Language.CreateSession(_lastText, parseOptions, compilationOptions, assemblyReferences);
}
public IWorkSessionOptions Options => _options;

Просмотреть файл

@ -7,6 +7,15 @@
<TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<TargetFrameworkProfile />
<Version>0.9.0</Version>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Authors>Andrey Shchekin</Authors>
<Company>Andrey Shchekin</Company>
<PackageProjectUrl>https://github.com/ashmind/mirrorsharp</PackageProjectUrl>
<RepositoryUrl>https://github.com/ashmind/mirrorsharp.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>F#;CodeMirror</PackageTags>
<Description>MirrorSharp F# support library. MirrorSharp is a code editor &lt;textarea&gt; built on Roslyn — see https://github.com/ashmind/mirrorsharp/blob/master/README.md for details.</Description>
</PropertyGroup>
<ItemGroup>

17
FSharp/FSharpCore.targets Normal file
Просмотреть файл

@ -0,0 +1,17 @@
<Project>
<!-- Should not be needed once https://github.com/Microsoft/visualfsharp/pull/2884 is available on NuGet -->
<Target Name="CopyOptdataAndSigdata" AfterTargets="Build">
<ItemGroup>
<FSharpCoreReference Include="@(Reference)" Condition="$([System.String]::Copy('%(Reference.Identity)').EndsWith('FSharp.Core.dll'))" />
</ItemGroup>
<PropertyGroup>
<FSharpCorePath>@(FSharpCoreReference->'%(Identity)')</FSharpCorePath>
<FSharpCoreDirectoryPath>$([System.IO.Path]::GetDirectoryName($(FSharpCorePath)))</FSharpCoreDirectoryPath>
</PropertyGroup>
<ItemGroup>
<OpdataAndSigdata Include="$(FSharpCoreDirectoryPath)\FSharp.Core.optdata" />
<OpdataAndSigdata Include="$(FSharpCoreDirectoryPath)\FSharp.Core.sigdata" />
</ItemGroup>
<Copy SourceFiles="@(OpdataAndSigdata)" DestinationFolder="$(OutDir)" />
</Target>
</Project>

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
@ -8,28 +9,31 @@ using Microsoft.FSharp.Core;
using MirrorSharp.Internal.Abstraction;
namespace MirrorSharp.FSharp {
internal class FSharpLanguage : ILanguage {
public class FSharpLanguage : ILanguage {
public const string Name = "F#";
public ParseOptions DefaultParseOptions => null;
public CompilationOptions DefaultCompilationOptions => null;
public ImmutableList<MetadataReference> DefaultAssemblyReferences { get; }
ParseOptions ILanguage.DefaultParseOptions => null;
CompilationOptions ILanguage.DefaultCompilationOptions => null;
private readonly ImmutableArray<string> _defaultAssemblyReferencePaths;
static FSharpLanguage() {
Library.Shim.FileSystem = new RestrictedFileSystem();
}
public FSharpLanguage() {
internal FSharpLanguage() {
var fsharpAssembly = typeof(FSharpOption<>).GetTypeInfo().Assembly;
DefaultAssemblyReferences = ImmutableList.Create<MetadataReference>(
_defaultAssemblyReferencePaths = ImmutableArray.Create<string>(
// note: this currently does not work on .NET Core, which is why this project isn't netstandard
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(new Uri(fsharpAssembly.EscapedCodeBase).LocalPath)
typeof(object).GetTypeInfo().Assembly.Location,
new Uri(fsharpAssembly.EscapedCodeBase).LocalPath
);
}
public ILanguageSession CreateSession(string text, ParseOptions parseOptions, CompilationOptions compilationOptions, ImmutableList<MetadataReference> metadataReferences) {
return new FSharpSession(text, metadataReferences);
ILanguageSession ILanguage.CreateSession(string text, ParseOptions parseOptions, CompilationOptions compilationOptions, IReadOnlyCollection<MetadataReference> assemblyReferences) {
if (assemblyReferences != null)
throw new NotSupportedException();
return new FSharpSession(text, _defaultAssemblyReferencePaths);
}
string ILanguage.Name => Name;

Просмотреть файл

@ -18,19 +18,14 @@ namespace MirrorSharp.FSharp {
private readonly FSharpChecker _checker;
private readonly FSharpProjectOptions _projectOptions;
public FSharpSession(string text, ImmutableList<MetadataReference> metadataReferences) {
public FSharpSession(string text, ImmutableArray<string> assemblyReferencePaths) {
_checker = FSharpChecker.Create(null, null, null, false);
_text = text;
var otherOptions = new List<string> { "--noframework" };
foreach (var reference in metadataReferences) {
switch (reference) {
case PortableExecutableReference pe:
// ReSharper disable once HeapView.ObjectAllocation (Unavoidable? Not worth caching)
otherOptions.Add("-r:" + pe.FilePath);
break;
default: throw new NotSupportedException($"Metadata reference type {reference.GetType()} is not supported.");
}
foreach (var path in assemblyReferencePaths) {
// ReSharper disable once HeapView.ObjectAllocation (Not worth fixing for now)
otherOptions.Add("-r:" + path);
}
_projectOptions = new FSharpProjectOptions(
@ -52,22 +47,45 @@ namespace MirrorSharp.FSharp {
_checker.ParseAndCheckFileInProject("_.fs", 0, _text, _projectOptions, null), null, cancellationToken
).ConfigureAwait(false);
var checkSuccess = check as FSharpCheckFileAnswer.Succeeded;
var diagnosticCount = parsed.Errors.Length + (checkSuccess?.Item.Errors.Length ?? 0);
if (diagnosticCount == 0)
return ImmutableArray<Diagnostic>.Empty;
var diagnostics = ImmutableArray.CreateBuilder<Diagnostic>(parsed.Errors.Length + (checkSuccess?.Item.Errors.Length ?? 0));
ConvertAndAddTo(diagnostics, parsed.Errors);
var lineOffsets = MapLineOffsets(_text);
var diagnostics = ImmutableArray.CreateBuilder<Diagnostic>(diagnosticCount);
ConvertAndAddTo(diagnostics, parsed.Errors, lineOffsets);
if (checkSuccess != null)
ConvertAndAddTo(diagnostics, checkSuccess.Item.Errors);
ConvertAndAddTo(diagnostics, checkSuccess.Item.Errors, lineOffsets);
return diagnostics.MoveToImmutable();
}
private void ConvertAndAddTo(ImmutableArray<Diagnostic>.Builder diagnostics, FSharpErrorInfo[] errors) {
private IReadOnlyList<int> MapLineOffsets(string text) {
var offsets = new List<int>();
var previous = '\0';
for (var i = 0; i < text.Length; i++) {
var @char = text[i];
if (previous == '\n' || (previous == '\r' && @char != '\n'))
offsets.Add(i);
previous = @char;
}
return offsets;
}
private void ConvertAndAddTo(ImmutableArray<Diagnostic>.Builder diagnostics, FSharpErrorInfo[] errors, IReadOnlyList<int> lineOffsets) {
foreach (var error in errors) {
var severity = ConvertToDiagnosticSeverity(error.Severity);
var startOffset = GetOffset(error.StartLineAlternate, error.StartColumn, lineOffsets);
var location = Location.Create(
"",
new TextSpan(0, 0),
new TextSpan(
startOffset,
GetOffset(error.EndLineAlternate, error.EndColumn, lineOffsets) - startOffset
),
new LinePositionSpan(
new LinePosition(error.StartLineAlternate, error.StartColumn),
new LinePosition(error.EndLineAlternate, error.EndColumn)
@ -79,12 +97,17 @@ namespace MirrorSharp.FSharp {
error.Message,
severity, severity,
isEnabledByDefault: false,
warningLevel: 0,
warningLevel: severity == DiagnosticSeverity.Warning ? 1 : 0,
location: location
));
}
}
private int GetOffset(int line, int column, IReadOnlyList<int> lineOffsets) {
var lineOffset = line > 1 ? lineOffsets[line - 2] : 0;
return lineOffset + column;
}
private DiagnosticSeverity ConvertToDiagnosticSeverity(FSharpErrorSeverity errorSeverity) {
return Equals(errorSeverity, FSharpErrorSeverity.Error) ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning;
}

Просмотреть файл

@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore", "AspNetCore\As
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Owin", "Owin\Owin.csproj", "{00CC1A50-B233-4045-9540-CB2316808C1B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Owin.Demo", "Owin.Demo\Owin.Demo.csproj", "{D2EB1CDD-12B5-4FDC-A56C-8A327200E759}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebAssets", "WebAssets\WebAssets.csproj", "{FF13139E-69D3-472E-B4FE-AC2623AD67B9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{35D73C72-267B-4598-ABC0-F1E1BACDE451}"
@ -27,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp", "FSharp\FSharp.csp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.Roslyn2.Net46", "Tests.Roslyn2.Net46\Tests.Roslyn2.Net46.csproj", "{7F531F1E-5AF6-4FC6-BF71-84EB00C1B1EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Demo", "Owin.Demo\Owin.Demo.csproj", "{3C2A0FC7-4485-4654-B3B2-5717A2F2C97A}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
Tests.Shared\MirrorSharp.Tests.Shared.projitems*{0a9078a1-bd26-4dc7-87bb-ded125f6218b}*SharedItemsImports = 13
@ -52,10 +52,6 @@ Global
{00CC1A50-B233-4045-9540-CB2316808C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00CC1A50-B233-4045-9540-CB2316808C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00CC1A50-B233-4045-9540-CB2316808C1B}.Release|Any CPU.Build.0 = Release|Any CPU
{D2EB1CDD-12B5-4FDC-A56C-8A327200E759}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2EB1CDD-12B5-4FDC-A56C-8A327200E759}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2EB1CDD-12B5-4FDC-A56C-8A327200E759}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2EB1CDD-12B5-4FDC-A56C-8A327200E759}.Release|Any CPU.Build.0 = Release|Any CPU
{FF13139E-69D3-472E-B4FE-AC2623AD67B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF13139E-69D3-472E-B4FE-AC2623AD67B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35D73C72-267B-4598-ABC0-F1E1BACDE451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@ -78,6 +74,10 @@ Global
{7F531F1E-5AF6-4FC6-BF71-84EB00C1B1EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F531F1E-5AF6-4FC6-BF71-84EB00C1B1EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F531F1E-5AF6-4FC6-BF71-84EB00C1B1EC}.Release|Any CPU.Build.0 = Release|Any CPU
{3C2A0FC7-4485-4654-B3B2-5717A2F2C97A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C2A0FC7-4485-4654-B3B2-5717A2F2C97A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C2A0FC7-4485-4654-B3B2-5717A2F2C97A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C2A0FC7-4485-4654-B3B2-5717A2F2C97A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -22,7 +22,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FSharp\FSharp.csproj" />
<ProjectReference Include="..\Owin\Owin.csproj" />
</ItemGroup>
<Import Project="../FSharp/FSharpCore.targets" />
</Project>

Просмотреть файл

@ -1,4 +1,6 @@
using Microsoft.Owin;
using Microsoft.CodeAnalysis;
using Microsoft.Owin;
using MirrorSharp.FSharp;
using MirrorSharp.Owin.Demo;
using Owin;
@ -10,6 +12,7 @@ namespace MirrorSharp.Owin.Demo {
app.UseDefaultFiles()
.UseStaticFiles()
.UseMirrorSharp(new MirrorSharpOptions {
LanguageNames = { LanguageNames.CSharp, FSharpLanguage.Name },
SelfDebugEnabled = true,
IncludeExceptionDetails = true
});

Просмотреть файл

@ -19,7 +19,19 @@
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin\Debug\net45"/>
<probing privatePath="bin\Debug\net46"/>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="1.2.0.0" newVersion="1.2.1.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="4.0.1.0" newVersion="4.0.2.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="4.4.0.0" newVersion="4.4.1.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -1,30 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta charset="utf-8">
<title>MirrorSharp Demo</title>
<link rel="stylesheet" href="bower_components/codemirror/lib/codemirror.css" />
<link rel="stylesheet" href="bower_components/codemirror/addon/lint/lint.css" />
<link rel="stylesheet" href="bower_components/codemirror/addon/hint/show-hint.css" />
<link rel="stylesheet" href="bower_components/codemirror-addon-lint-fix/dist/lint-fix.css" />
<link rel="stylesheet" href="bower_components/mirrorsharp/mirrorsharp.css" />
<link rel="stylesheet" href="bower_components/codemirror/lib/codemirror.css">
<link rel="stylesheet" href="bower_components/codemirror/addon/lint/lint.css">
<link rel="stylesheet" href="bower_components/codemirror/addon/hint/show-hint.css">
<link rel="stylesheet" href="bower_components/codemirror-addon-lint-fix/dist/lint-fix.css">
<link rel="stylesheet" href="bower_components/mirrorsharp/mirrorsharp.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans">
<style>
* { box-sizing: border-box; }
html, body { width: 100%; height: 100%; }
body { padding: 0; margin: 0; font-size: 16px; }
body {
padding: 0;
margin: 0;
font-size: 16px;
display: flex;
flex-direction: column;
padding: 10px;
}
nav { display: flex; font-family: 'Open Sans', sans-serif; }
ul {
list-style: none;
display: flex;
padding: 0;
margin: 0;
}
li {
margin-left: 10px;
}
a { text-decoration: none; }
a:hover { text-decoration: underline; }
.CodeMirror {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 10px;
height: auto;
box-sizing: border-box;
flex-grow: 1;
margin-top: 10px;
border: 1px solid #ddd;
}
</style>
</head>
<body>
<nav>
Language:
<ul>
<li><a href="index.html?language=CSharp">C#</a></li>
<li><a href="index.html?language=FSharp">F#</a></li>
</ul>
</nav>
<textarea>using System;
class C {
void M() {
@ -33,14 +55,22 @@ class C {
<script src="bower_components/codemirror/lib/codemirror.js"></script>
<script src="bower_components/codemirror/mode/clike/clike.js"></script>
<script src="bower_components/codemirror/mode/mllike/mllike.js"></script>
<script src="bower_components/codemirror/addon/lint/lint.js"></script>
<script src="bower_components/codemirror/addon/hint/show-hint.js"></script>
<script src="bower_components/codemirror-addon-lint-fix/dist/lint-fix.js"></script>
<script src="bower_components/mirrorsharp/mirrorsharp.js"></script>
<script>
mirrorsharp(document.getElementsByTagName('textarea')[0], {
serviceUrl: window.location.href.replace(/^http(.+)\/?$/i, 'ws$1/mirrorsharp'),
selfDebugEnabled: true
'use strict';
const language = (window.location.search.match(/language=([^&]+)/)[1] || ['C#']).replace('Sharp', '#');
const textarea = document.getElementsByTagName('textarea')[0];
if (language === 'F#')
textarea.value = '1 |> ignore';
mirrorsharp(textarea, {
serviceUrl: window.location.href.replace(/^http(s?:\/\/[^/]+).*$/i, 'ws$1/mirrorsharp'),
selfDebugEnabled: true,
language: (window.location.search.match(/language=([^&]+)/)[1] || ['C#']).replace('Sharp', '#')
});
</script>
</body>

Просмотреть файл

@ -68,11 +68,21 @@ namespace MirrorSharp.Testing {
return SendAsync<SlowUpdateResult<TExtensionResult>>(CommandIds.SlowUpdate);
}
[PublicAPI]
public Task<OptionsEchoResult> SendSetOptionAsync(string name, string value) {
return SendAsync<OptionsEchoResult>(CommandIds.SetOptions, $"{name}={value}");
}
[PublicAPI]
public Task<OptionsEchoResult> SendSetOptionsAsync(IDictionary<string, string> options) {
return SendAsync<OptionsEchoResult>(CommandIds.SetOptions, string.Join(",", options.Select(o => $"{o.Key}={o.Value}")));
}
[PublicAPI]
internal Task SendReplaceTextAsync(string newText, int start = 0, int length = 0, int newCursorPosition = 0, string reason = "") {
return SendAsync(CommandIds.ReplaceText, $"{start}:{length}:{newCursorPosition}:{reason}:{newText}");
}
internal async Task<TResult> SendAsync<TResult>(char commandId, HandlerTestArgument argument = null)
where TResult : class
{

Просмотреть файл

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable CollectionNeverUpdated.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace MirrorSharp.Testing.Results {
public class ResultSpan {
public int Start { get; set; }
public int Length { get; set; }
}
}

Просмотреть файл

@ -10,6 +10,7 @@ namespace MirrorSharp.Testing.Results {
[CanBeNull] public string Id { get; set; }
[CanBeNull] public string Message { get; set; }
[CanBeNull] public string Severity { get; set; }
[CanBeNull] public ResultSpan Span { get; set; }
[NotNull] public IList<string> Tags { get; } = new List<string>();
[NotNull] public IList<SlowUpdateDiagnosticAction> Actions { get; } = new List<SlowUpdateDiagnosticAction>();

Просмотреть файл

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using MirrorSharp.Internal;
using MirrorSharp.Testing;
using Xunit;
@ -8,19 +9,42 @@ namespace MirrorSharp.Tests {
public class FSharpTests {
[Fact]
public async void Prototype() {
public async void SlowUpdate_ProducesNoDiagnostics_IfCodeIsValid() {
var driver = MirrorSharpTestDriver.New();
await driver.SendSetOptionsAsync(new Dictionary<string, string> {{ "language", "F#" }});
var code = @"open System
await driver.SendSetOptionAsync("language", "F#");
var code = @"
open System
[<EntryPoint>]
let main argv =
printfn ""Hello World""
Console.ReadLine() |> ignore
0";
await driver.SendAsync(ReplaceText, $"0:0:0::{code}");
[<EntryPoint>]
let main argv =
printfn ""Hello World""
Console.ReadLine() |> ignore
0
".Trim().Replace(" ", "");
await driver.SendReplaceTextAsync(code);
var result = await driver.SendSlowUpdateAsync();
Assert.Empty(result.Diagnostics);
}
[Fact]
public async void SlowUpdate_ProducesExpectedDiagnostics_IfCodeHasErrors() {
var driver = MirrorSharpTestDriver.New();
await driver.SendSetOptionAsync("language", "F#");
await driver.SendReplaceTextAsync("xyz");
var result = await driver.SendSlowUpdateAsync();
Assert.Equal(
new[] { new {
Severity = "error",
Message = "The value or constructor 'xyz' is not defined.",
Span = new { Start = (int?)0, Length = (int?)3 }
} },
result.Diagnostics.Select(d => new {
d.Severity,
d.Message,
Span = new { d.Span?.Start, d.Span?.Length }
}).ToArray()
);
}
}
}

Просмотреть файл

@ -26,20 +26,6 @@
<ProjectReference Include="..\FSharp\FSharp.csproj" />
<ProjectReference Include="..\Testing\Testing.csproj" />
</ItemGroup>
<!-- Should not be needed once https://github.com/Microsoft/visualfsharp/pull/2884 is available on NuGet -->
<Target Name="CopyOptdataAndSigdata" AfterTargets="Build">
<ItemGroup>
<FSharpCoreReference Include="@(Reference)" Condition="$([System.String]::Copy('%(Reference.Identity)').EndsWith('FSharp.Core.dll'))" />
</ItemGroup>
<PropertyGroup>
<FSharpCorePath>@(FSharpCoreReference->'%(Identity)')</FSharpCorePath>
<FSharpCoreDirectoryPath>$([System.IO.Path]::GetDirectoryName($(FSharpCorePath)))</FSharpCoreDirectoryPath>
</PropertyGroup>
<ItemGroup>
<OpdataAndSigdata Include="$(FSharpCoreDirectoryPath)\FSharp.Core.optdata" />
<OpdataAndSigdata Include="$(FSharpCoreDirectoryPath)\FSharp.Core.sigdata" />
</ItemGroup>
<Copy SourceFiles="@(OpdataAndSigdata)" DestinationFolder="$(OutDir)" />
</Target>
<Import Project="../FSharp/FSharpCore.targets" />
</Project>

Просмотреть файл

@ -1,4 +1,4 @@
/* globals console:false, CloseEvent:false */
/* globals console:false, CloseEvent:false */
(function (root, factory) {
'use strict';
// ReSharper disable UndeclaredGlobalVariableUsing (R# bug, https://youtrack.jetbrains.com/issue/RSRP-462411)
@ -434,7 +434,8 @@
const defaultLanguage = 'C#';
const languageModes = {
'C#': 'text/x-csharp',
'Visual Basic': 'text/x-vb'
'Visual Basic': 'text/x-vb',
'F#': 'text/x-fsharp'
};
var language;

Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "mirrorsharp",
"version": "0.9.0-pre-20170501",
"version": "0.9.0-pre-20170517",
"description": "A code editor `<textarea>` for .NET.",
"authors": [
"Andrey Shchekin (https://github.com/ashmind)"