Separate language specifics
This commit is contained in:
Родитель
9b004e984d
Коммит
a655bae331
|
@ -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")
|
||||
|
|
Загрузка…
Ссылка в новой задаче