Skip to content

Commit 6e5b036

Browse files
Merge pull request #539 from icsharpcode/fix-test-compile-errors
Fix test compile errors
2 parents b4f84d2 + fe85a41 commit 6e5b036

53 files changed

Lines changed: 3014 additions & 2366 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CodeConverter/CSharp/CachedReflectedDelegates.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,6 @@ namespace ICSharpCode.CodeConverter.CSharp
1919
/// </remarks>
2020
internal static class CachedReflectedDelegates
2121
{
22-
/// <summary>
23-
/// This method becomes public in CodeAnalysis 3.1 and hence we can be confident it won't disappear.
24-
/// Need to use reflection for now until that version is widely enough deployed as taking a dependency would mean everyone needs latest VS version.
25-
/// </summary>
26-
public static readonly Lazy<Func<CompilationOptions, byte, CompilationOptions>> LazyWithMetadataImportOptions =
27-
new Lazy<Func<CompilationOptions, byte, CompilationOptions>>(() => typeof(CompilationOptions)
28-
.GetMethod("WithMetadataImportOptions",
29-
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
30-
.CreateOpenInstanceDelegateForcingType<CompilationOptions, byte, CompilationOptions>());
31-
3222
public static bool IsMyGroupCollectionProperty(this IPropertySymbol declaredSymbol) =>
3323
GetCachedReflectedPropertyDelegate(declaredSymbol, "IsMyGroupCollectionProperty", ref _isMyGroupCollectionProperty);
3424
private static Func<ISymbol, bool> _isMyGroupCollectionProperty;

CodeConverter/CSharp/ExpressionNodeVisitor.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,13 @@ public override async Task<CSharpSyntaxNode> VisitSimpleArgument(VBasic.Syntax.S
447447

448448
public override async Task<CSharpSyntaxNode> VisitNameOfExpression(VBasic.Syntax.NameOfExpressionSyntax node)
449449
{
450-
return SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("nameof"), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument((ExpressionSyntax) await node.Argument.AcceptAsync(TriviaConvertingExpressionVisitor)))));
450+
return SyntaxFactory.InvocationExpression(NameOf(), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList<ArgumentSyntax>(SyntaxFactory.Argument((ExpressionSyntax)await node.Argument.AcceptAsync(TriviaConvertingExpressionVisitor)))));
451+
}
452+
453+
private static ExpressionSyntax NameOf()
454+
{
455+
// Usually it'd be preferable to just construct the Identifier ourselves, but the opportunity to inject parse options lets us control the LanguageVersion which needs to be high enough not to consider nameof an error
456+
return SyntaxFactory.ParseExpression("nameof", options: CSharpCompiler.ParseOptions);
451457
}
452458

453459
public override async Task<CSharpSyntaxNode> VisitEqualsValue(VBasic.Syntax.EqualsValueSyntax node)
@@ -486,10 +492,8 @@ public override async Task<CSharpSyntaxNode> VisitArrayCreationExpression(VBasic
486492
{
487493
var bounds = await CommonConversions.ConvertArrayRankSpecifierSyntaxes(node.RankSpecifiers, node.ArrayBounds);
488494

489-
var allowInitializer = node.Initializer.Initializers.Any()
490-
|| node.RankSpecifiers.Any()
491-
|| node.ArrayBounds == null
492-
|| (node.Initializer.Initializers.Any() && node.ArrayBounds.Arguments.All(b => b.IsOmitted || _semanticModel.GetConstantValue(b.GetExpression()).HasValue));
495+
var allowInitializer = node.ArrayBounds?.Arguments.Any() != true ||
496+
node.Initializer.Initializers.Any() && node.ArrayBounds.Arguments.All(b => b.IsOmitted || _semanticModel.GetConstantValue(b.GetExpression()).HasValue);
493497

494498
var initializerToConvert = allowInitializer ? node.Initializer : null;
495499
return SyntaxFactory.ArrayCreationExpression(
@@ -507,15 +511,18 @@ public override async Task<CSharpSyntaxNode> VisitCollectionInitializer(VBasic.S
507511
var initializers = (await node.Initializers.SelectAsync(i => i.AcceptAsync(TriviaConvertingExpressionVisitor))).Cast<ExpressionSyntax>();
508512
var initializer = SyntaxFactory.InitializerExpression(initializerKind, SyntaxFactory.SeparatedList(initializers));
509513
if (isExplicitCollectionInitializer) return initializer;
510-
511-
if (!initializers.Any() && _semanticModel.GetTypeInfo(node).ConvertedType is IArrayTypeSymbol arrayType) {
514+
515+
if (!(_semanticModel.GetTypeInfo(node).ConvertedType is IArrayTypeSymbol arrayType)) return SyntaxFactory.ImplicitArrayCreationExpression(initializer);
516+
517+
if (!initializers.Any()) {
512518

513519
var arrayTypeArgs = SyntaxFactory.TypeArgumentList(SyntaxFactory.SingletonSeparatedList(CommonConversions.GetTypeSyntax(arrayType.ElementType)));
514520
var arrayEmpty = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
515521
SyntaxFactory.IdentifierName(nameof(Array)), SyntaxFactory.GenericName(nameof(Array.Empty)).WithTypeArgumentList(arrayTypeArgs));
516522
return SyntaxFactory.InvocationExpression(arrayEmpty);
517523
}
518-
return SyntaxFactory.ImplicitArrayCreationExpression(initializer);
524+
var commas = Enumerable.Repeat(SyntaxFactory.Token(SyntaxKind.CommaToken), arrayType.Rank - 1);
525+
return SyntaxFactory.ImplicitArrayCreationExpression(SyntaxFactory.TokenList(commas), initializer);
519526
}
520527

521528
public override async Task<CSharpSyntaxNode> VisitQueryExpression(VBasic.Syntax.QueryExpressionSyntax node)

CodeConverter/CSharp/ProjectExtensions.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ internal static class ProjectExtensions
1010
{
1111
private static char[] DirSeparators = new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
1212

13-
public static Project CreateReferenceOnlyProjectFromAnyOptions(this Project project, CompilationOptions baseOptions)
13+
public static Project CreateReferenceOnlyProjectFromAnyOptions(this Project project, CompilationOptions baseOptions, ParseOptions parseOptions)
1414
{
15-
var options = baseOptions.WithMetadataImportOptionsAll();
15+
var options = baseOptions.WithMetadataImportOptions(MetadataImportOptions.All);
1616
var viewerId = ProjectId.CreateNewId();
1717
var projectReferences = project.ProjectReferences.Concat(new[] {new ProjectReference(project.Id)});
1818
var viewerProjectInfo = project.ToProjectInfo(viewerId, project.Name + viewerId, options,
19-
projectReferences);
19+
projectReferences, parseOptions);
2020
var csharpViewOfVbProject = project.Solution.AddProject(viewerProjectInfo).GetProject(viewerId);
2121
return csharpViewOfVbProject;
2222
}
@@ -70,10 +70,10 @@ public static (Project project, List<WipFileConversion<DocumentId>> firstPassDoc
7070
DocumentId docId = null;
7171
if (firstPassResult.Wip != null)
7272
{
73-
var document = project.AddDocument(firstPassResult.Path, firstPassResult.Wip,
73+
docId = DocumentId.CreateNewId(project.Id);
74+
var solution = project.Solution.AddDocument(docId, firstPassResult.Path, firstPassResult.Wip,
7475
filePath: firstPassResult.Path);
75-
project = document.Project;
76-
docId = document.Id;
76+
project = solution.GetProject(project.Id);
7777
}
7878

7979
return WipFileConversion.Create(firstPassResult.Path, docId, firstPassResult.Errors);

CodeConverter/CSharp/ProjectMergedDeclarationExtensions.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.CodeAnalysis.Rename;
1010
using Microsoft.CodeAnalysis.VisualBasic;
1111
using System.Threading;
12+
using System.Collections.Generic;
1213

1314
namespace ICSharpCode.CodeConverter.CSharp
1415
{
@@ -26,11 +27,12 @@ public static async Task<Project> WithRenamedMergedMyNamespace(this Project vbPr
2627
var projectDir = Path.Combine(vbProject.GetDirectoryPath(), "My Project");
2728

2829
var compilation = await vbProject.GetCompilationAsync(cancellationToken);
29-
string embeddedSourceText = (await GetAllEmbeddedSourceText(compilation));
30-
string generatedSourceText = (await GetDynamicallyGeneratedSourceText(compilation));
30+
var embeddedSourceTexts = await GetAllEmbeddedSourceText(compilation).Select((r, i) => (Text: r, Suffix: $".Static.{i+1}")).ToArrayAsync();
31+
var generatedSourceTexts = (Text: await GetDynamicallyGeneratedSourceText(compilation), Suffix: ".Dynamic").Yield();
3132

32-
vbProject = WithRenamespacedDocument(name + ".Static", vbProject, embeddedSourceText, projectDir);
33-
vbProject = WithRenamespacedDocument(name + ".Dynamic", vbProject, generatedSourceText, projectDir);
33+
foreach (var (text, suffix) in embeddedSourceTexts.Concat(generatedSourceTexts)) {
34+
vbProject = WithRenamespacedDocument(name + suffix, vbProject, text, projectDir);
35+
}
3436

3537
return vbProject;
3638
}
@@ -41,15 +43,12 @@ private static Project WithRenamespacedDocument(string baseName, Project vbProje
4143
return vbProject.AddDocument(baseName, sourceText.Renamespace(), filePath: Path.Combine(myProjectDirPath, baseName + ".Designer.vb")).Project;
4244
}
4345

44-
private static async Task<string> GetAllEmbeddedSourceText(Compilation compilation)
46+
private static async IAsyncEnumerable<string> GetAllEmbeddedSourceText(Compilation compilation)
4547
{
4648
var roots = await compilation.SourceModule.GlobalNamespace.Locations.
4749
Where(l => !l.IsInSource).Select(CachedReflectedDelegates.GetEmbeddedSyntaxTree)
4850
.SelectAsync(t => t.GetTextAsync());
49-
var renamespacesRootTexts =
50-
roots.Select(r => r.ToString());
51-
var combined = string.Join(Environment.NewLine, renamespacesRootTexts);
52-
return combined;
51+
foreach (var r in roots) yield return r.ToString();
5352
}
5453

5554
private static async Task<string> GetDynamicallyGeneratedSourceText(Compilation compilation)
@@ -109,6 +108,7 @@ private static string Renamespace(this string sourceText)
109108
{
110109
return sourceText
111110
.Replace("Namespace Global.Microsoft.VisualBasic", $"Namespace Global.Microsoft.{Constants.MergedMsVbNamespace}")
111+
.Replace("Global.Microsoft.VisualBasic.Embedded", $"Global.Microsoft.{Constants.MergedMsVbNamespace}.Embedded")
112112
.Replace("Namespace My", $"Namespace {Constants.MergedMyNamespace}");
113113
}
114114

CodeConverter/CSharp/VBToCSProjectContentsConverter.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@ internal class VBToCSProjectContentsConverter : IProjectContentsConverter
2020
private CSharpCompilation _csharpViewOfVbSymbols;
2121
private Project _convertedCsProject;
2222

23-
/// <summary>
24-
/// It's really hard to change simplifier options since everything is done on the Object hashcode of internal fields.
25-
/// I wanted to avoid saying "default" instead of "default(string)" because I don't want to force a later language version on people in such a common case.
26-
/// This will have that effect, but also has the possibility of failing to interpret code output by this converter.
27-
/// If this has such unintended effects in future, investigate the code that loads options from an editorconfig file
28-
/// </summary>
29-
private static readonly CSharpParseOptions DoNotAllowImplicitDefault = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7);
30-
3123
private Project _csharpReferenceProject;
3224
private readonly IProgress<ConversionProgress> _progress;
3325
private readonly CancellationToken _cancellationToken;
@@ -45,8 +37,8 @@ public VBToCSProjectContentsConverter(ConversionOptions conversionOptions, IProg
4537
public async Task InitializeSourceAsync(Project project)
4638
{
4739
var cSharpCompilationOptions = CSharpCompiler.CreateCompilationOptions();
48-
_convertedCsProject = project.ToProjectFromAnyOptions(cSharpCompilationOptions, DoNotAllowImplicitDefault);
49-
_csharpReferenceProject = project.CreateReferenceOnlyProjectFromAnyOptions(cSharpCompilationOptions);
40+
_convertedCsProject = project.ToProjectFromAnyOptions(cSharpCompilationOptions, CSharpCompiler.ParseOptions);
41+
_csharpReferenceProject = project.CreateReferenceOnlyProjectFromAnyOptions(cSharpCompilationOptions, CSharpCompiler.ParseOptions);
5042
_csharpViewOfVbSymbols = (CSharpCompilation) await _csharpReferenceProject.GetCompilationAsync(_cancellationToken);
5143
Project = await project.WithRenamedMergedMyNamespace(_cancellationToken);
5244
}

CodeConverter/ConversionResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public string GetExceptionsAsString()
5757
public void WriteToFile()
5858
{
5959
Directory.CreateDirectory(Path.GetDirectoryName(TargetPathOrNull));
60-
File.WriteAllText(TargetPathOrNull, ConvertedCode, Encoding.UTF8);
60+
File.WriteAllText(TargetPathOrNull, ConvertedCode ?? GetExceptionsAsString(), Encoding.UTF8);
6161
}
6262
}
6363
}

CodeConverter/Shared/CompilationOptionsExtensions.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,5 @@ public static Document CreateProjectDocumentFromTree(this CompilationOptions opt
2828
.WithMetadataReferences(references);
2929
return project.AddDocument("CodeToConvert", tree.GetRoot(), filePath: Path.Combine(Directory.GetCurrentDirectory(), "TempCodeToConvert.txt"));
3030
}
31-
32-
public static CompilationOptions WithMetadataImportOptionsAll(this CompilationOptions baseOptions)
33-
{
34-
return CachedReflectedDelegates.LazyWithMetadataImportOptions.Value(baseOptions, 2 /*MetadataImportOptions.All*/);
35-
}
3631
}
3732
}

CodeConverter/Shared/ProjectConversion.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,19 @@ public class ProjectConversion
1919
{
2020
private readonly IReadOnlyCollection<Document> _documentsToConvert;
2121
private readonly ILanguageConversion _languageConversion;
22-
private readonly bool _showCompilationErrors =
23-
#if DEBUG && ShowCompilationErrors
24-
true;
25-
#else
26-
false;
27-
#endif
22+
private readonly bool _showCompilationErrors;
2823
private readonly bool _returnSelectedNode;
2924
private static readonly string[] BannedPaths = new[] { ".AssemblyAttributes.", "\\bin\\", "\\obj\\" };
3025
private readonly IProjectContentsConverter _projectContentsConverter;
3126
private readonly CancellationToken _cancellationToken;
3227

3328
private ProjectConversion(IProjectContentsConverter projectContentsConverter, IEnumerable<Document> documentsToConvert,
34-
ILanguageConversion languageConversion, CancellationToken cancellationToken, bool returnSelectedNode = false)
29+
ILanguageConversion languageConversion, CancellationToken cancellationToken, bool showCompilationErrors, bool returnSelectedNode = false)
3530
{
3631
_projectContentsConverter = projectContentsConverter;
3732
_languageConversion = languageConversion;
3833
_documentsToConvert = documentsToConvert.ToList();
34+
_showCompilationErrors = showCompilationErrors;
3935
_returnSelectedNode = returnSelectedNode;
4036
_cancellationToken = cancellationToken;
4137
}
@@ -69,7 +65,7 @@ private ProjectConversion(IProjectContentsConverter projectContentsConverter, IE
6965

7066
document = projectContentsConverter.Project.GetDocument(document.Id);
7167

72-
var conversion = new ProjectConversion(projectContentsConverter, new[] { document }, languageConversion, cancellationToken, returnSelectedNode);
68+
var conversion = new ProjectConversion(projectContentsConverter, new[] { document }, languageConversion, cancellationToken, conversionOptions.ShowCompilationErrors, returnSelectedNode);
7369
var conversionResults = await conversion.Convert(progress).ToArrayAsync();
7470
var codeResult = conversionResults.SingleOrDefault(x => !string.IsNullOrWhiteSpace(x.ConvertedCode))
7571
?? conversionResults.First();
@@ -154,7 +150,7 @@ private static async IAsyncEnumerable<ConversionResult> ConvertProjectContents(
154150
//Perf heuristic: Decrease memory pressure on the simplification phase by converting large files first https://github.com/icsharpcode/CodeConverter/issues/524#issuecomment-590301594
155151
var documentsToConvert = documentsWithLengths.OrderByDescending(d => d.Length).Select(d => d.Doc);
156152

157-
var projectConversion = new ProjectConversion(projectContentsConverter, documentsToConvert, languageConversion, cancellationToken);
153+
var projectConversion = new ProjectConversion(projectContentsConverter, documentsToConvert, languageConversion, cancellationToken, false);
158154

159155
var results = projectConversion.Convert(progress);
160156
await foreach (var result in results) yield return result;
@@ -168,8 +164,8 @@ private async IAsyncEnumerable<ConversionResult> Convert(IProgress<ConversionPro
168164
var (proj1, docs1) = await _projectContentsConverter.GetConvertedProject(await firstPassResults.ToArrayAsync());
169165

170166
var warnings = await GetProjectWarnings(_projectContentsConverter.Project, proj1);
171-
if (warnings != null) {
172-
var warningPath = Path.Combine(proj1.GetDirectoryPath(), "ConversionWarnings.txt");
167+
if (!string.IsNullOrWhiteSpace(warnings)) {
168+
var warningPath = Path.Combine(_projectContentsConverter.Project.GetDirectoryPath(), "ConversionWarnings.txt");
173169
yield return new ConversionResult() { SourcePathOrNull = warningPath, Exceptions = new[] { warnings } };
174170
}
175171

CodeConverter/Shared/SingleConversionOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ namespace ICSharpCode.CodeConverter.Shared
55
public class SingleConversionOptions : ConversionOptions
66
{
77
public TextSpan SelectedTextSpan { get; set; } = new TextSpan();
8+
internal bool ShowCompilationErrors { get; set; }
89
}
910
}

CodeConverter/Util/CSharpCompiler.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class CSharpCompiler : ICompiler
1313

1414
public SyntaxTree CreateTree(string text)
1515
{
16-
return SyntaxFactory.ParseSyntaxTree(text, encoding: Encoding.UTF8);
16+
return SyntaxFactory.ParseSyntaxTree(text, ParseOptions, encoding: Encoding.UTF8);
1717
}
1818

1919
public Compilation CreateCompilationFromTree(SyntaxTree tree, IEnumerable<MetadataReference> references)
@@ -34,7 +34,9 @@ private static CSharpCompilation CreateCSharpCompilation()
3434

3535
public static CSharpCompilationOptions CreateCompilationOptions()
3636
{
37-
return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
37+
return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);
3838
}
39+
40+
public static CSharpParseOptions ParseOptions { get; } = new CSharpParseOptions(LanguageVersion.Latest);
3941
}
4042
}

0 commit comments

Comments
 (0)