This commit is contained in:
GrahamTheCoder 2018-02-25 17:40:33 +00:00
Родитель 9b004e984d
Коммит a655bae331
1 изменённых файлов: 41 добавлений и 41 удалений

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

@ -17,38 +17,38 @@ namespace ICSharpCode.CodeConverter.CSharp
public class ProjectConversion
{
private bool _methodBodyOnly;
private VisualBasicCompilation _compilation;
private IEnumerable<VisualBasicSyntaxTree> _syntaxTreesToConvert;
private Compilation _sourceCompilation;
private IEnumerable<SyntaxTree> _syntaxTreesToConvert;
private static readonly AdhocWorkspace AdhocWorkspace = new AdhocWorkspace();
private readonly ConcurrentDictionary<string, Exception> _errors = new ConcurrentDictionary<string, Exception>();
private readonly Dictionary<string, SyntaxTree> _firstPassResults = new Dictionary<string, SyntaxTree>();
private CSharpCompilation _cSharpCompilation;
private Compilation _targetCompilation;
private ProjectConversion(VisualBasicCompilation compilation, string solutionDir)
: this(compilation, compilation.SyntaxTrees.OfType<VisualBasicSyntaxTree>().Where(t => t.FilePath.StartsWith(solutionDir)))
private ProjectConversion(Compilation sourceCompilation, string solutionDir)
: this(sourceCompilation, sourceCompilation.SyntaxTrees.Where(t => t.FilePath.StartsWith(solutionDir)))
{
}
private ProjectConversion(VisualBasicCompilation compilation, IEnumerable<VisualBasicSyntaxTree> syntaxTreesToConvert)
private ProjectConversion(Compilation sourceCompilation, IEnumerable<SyntaxTree> syntaxTreesToConvert)
{
_compilation = compilation;
_sourceCompilation = sourceCompilation;
_syntaxTreesToConvert = syntaxTreesToConvert;
}
public static ConversionResult ConvertText(string text, IReadOnlyCollection<MetadataReference> references)
{
var visualBasicSyntaxTree = CreateTree(text);
var compilation = CreateCompilationFromTree(visualBasicSyntaxTree, references);
return ConvertSingle(compilation, visualBasicSyntaxTree, new TextSpan(0, 0)).GetAwaiter().GetResult();
var syntaxTree = CreateTree(text);
var compilation = CreateCompilationFromTree(syntaxTree, references);
return ConvertSingle(compilation, syntaxTree, new TextSpan(0, 0)).GetAwaiter().GetResult();
}
public static async Task<ConversionResult> ConvertSingle(VisualBasicCompilation compilation, VisualBasicSyntaxTree syntaxTree, TextSpan selected)
public static async Task<ConversionResult> ConvertSingle(Compilation compilation, SyntaxTree syntaxTree, TextSpan selected)
{
var root = await syntaxTree.GetRootAsync();
if (selected.Length > 0) {
var annotatedSyntaxTree = GetSyntaxTreeWithAnnotatedSelection(selected, root);
compilation = compilation.ReplaceSyntaxTree(syntaxTree, annotatedSyntaxTree);
syntaxTree = (VisualBasicSyntaxTree) annotatedSyntaxTree;
syntaxTree = annotatedSyntaxTree;
}
var conversion = new ProjectConversion(compilation, new [] {syntaxTree});
@ -68,7 +68,7 @@ namespace ICSharpCode.CodeConverter.CSharp
var solutionDir = Path.GetDirectoryName(projects.First().Solution.FilePath);
foreach (var project in projects) {
var compilation = project.GetCompilationAsync().GetAwaiter().GetResult();
var projectConversion = new ProjectConversion((VisualBasicCompilation)compilation, solutionDir);
var projectConversion = new ProjectConversion(compilation, solutionDir);
foreach (var pathNodePair in projectConversion.Convert()) {
yield return new ConversionResult(pathNodePair.Value.ToFullString()) {SourcePathOrNull = pathNodePair.Key};
}
@ -84,7 +84,7 @@ namespace ICSharpCode.CodeConverter.CSharp
private Dictionary<string, SyntaxNode> Convert()
{
FirstPass();
_cSharpCompilation = CSharpCompilation.Create("Conversion", _firstPassResults.Values, _compilation.References);
_targetCompilation = CSharpCompilation.Create("Conversion", _firstPassResults.Values, _sourceCompilation.References);
var secondPassByFilePath = _firstPassResults.ToDictionary(cs => cs.Key, SingleSecondPass);
return secondPassByFilePath;
}
@ -99,7 +99,7 @@ namespace ICSharpCode.CodeConverter.CSharp
SingleFirstPass(tree, treeFilePath);
}
catch (NotImplementedOrRequiresSurroundingMethodDeclaration)
when (!_methodBodyOnly && _compilation.SyntaxTrees.Length == 1)
when (!_methodBodyOnly && _sourceCompilation.SyntaxTrees.Count() == 1)
{
SingleFirstPassSurroundedByClassAndMethod(tree);
}
@ -110,37 +110,15 @@ namespace ICSharpCode.CodeConverter.CSharp
}
}
private SyntaxNode SingleSecondPass(KeyValuePair<string, SyntaxTree> cs)
{
var secondPassNode = new CompilationErrorFixer(_cSharpCompilation, (CSharpSyntaxTree) cs.Value).Fix();
if (_methodBodyOnly) secondPassNode = secondPassNode.DescendantNodes().OfType<MethodDeclarationSyntax>().First().Body;
return Formatter.Format(secondPassNode, AdhocWorkspace);
}
private void SingleFirstPass(VisualBasicSyntaxTree tree, string treeFilePath)
{
var converted = VisualBasicConverter.ConvertCompilationTree(_compilation, tree);
_firstPassResults.Add(treeFilePath, SyntaxFactory.SyntaxTree(converted));
}
private void SingleFirstPassSurroundedByClassAndMethod(SyntaxTree tree)
{
var newTree = CreateTree(WithSurroundingClassAndMethod(tree.GetText().ToString()));
_methodBodyOnly = true;
_compilation = _compilation.AddSyntaxTrees(newTree);
_sourceCompilation = _sourceCompilation.AddSyntaxTrees(newTree);
_syntaxTreesToConvert = new[] {newTree};
Convert();
}
private static string WithSurroundingClassAndMethod(string text)
{
return $@"Class SurroundingClass
Sub SurroundingSub()
{text}
End Sub
End Class";
}
private static SyntaxTree GetSyntaxTreeWithAnnotatedSelection(TextSpan selected, SyntaxNode root)
{
var selectedNode = root.FindNode(selected);
@ -154,12 +132,34 @@ End Class";
return annotatedNode == null ? resultNode : Formatter.Format(annotatedNode, AdhocWorkspace);
}
private static VisualBasicSyntaxTree CreateTree(string text)
private void SingleFirstPass(SyntaxTree tree, string treeFilePath)
{
return (VisualBasicSyntaxTree) Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseSyntaxTree(SourceText.From(text));
var converted = VisualBasicConverter.ConvertCompilationTree((VisualBasicCompilation)_sourceCompilation, (VisualBasicSyntaxTree)tree);
_firstPassResults.Add(treeFilePath, SyntaxFactory.SyntaxTree(converted));
}
private static VisualBasicCompilation CreateCompilationFromTree(VisualBasicSyntaxTree tree, IEnumerable<MetadataReference> references)
private SyntaxNode SingleSecondPass(KeyValuePair<string, SyntaxTree> cs)
{
var secondPassNode = new CompilationErrorFixer((CSharpCompilation)_targetCompilation, (CSharpSyntaxTree)cs.Value).Fix();
if (_methodBodyOnly) secondPassNode = secondPassNode.DescendantNodes().OfType<MethodDeclarationSyntax>().First().Body;
return Formatter.Format(secondPassNode, AdhocWorkspace);
}
private static string WithSurroundingClassAndMethod(string text)
{
return $@"Class SurroundingClass
Sub SurroundingSub()
{text}
End Sub
End Class";
}
private static SyntaxTree CreateTree(string text)
{
return Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseSyntaxTree(SourceText.From(text));
}
private static Compilation CreateCompilationFromTree(SyntaxTree tree, IEnumerable<MetadataReference> references)
{
var compilationOptions = new VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithRootNamespace("TestProject")