public bool PreProcess(Guid projectType, string appName, string rawFileRelativePath, string outputFileName, string[] supportedTokens, string content, IGeneratorConfiguration generatorConfiguration) { var options = CSharpParseOptions.Default.WithPreprocessorSymbols(supportedTokens); var syntaxTree = CSharpSyntaxTree.ParseText(content, options); var root = syntaxTree.GetCompilationUnitRoot(); var walker = new DirectiveSyntaxWalker(supportedTokens); var tokensToProcess = new List <string>(); List <IfDirectiveBlock> generatorDirectiveBlocks; this.supportedTokens = supportedTokens; this.OutputContent = content; walker.Visit(root); generatorDirectiveBlocks = walker.GeneratorDirectiveBlocks; foreach (var generatorDirectiveBlock in generatorDirectiveBlocks) { var childNodes = generatorDirectiveBlock.ChildNodes.Reverse(); IfDirectiveNodeBase branchTakenNode = null; foreach (var childNode in childNodes.Where(n => !n.IsOfType <EndIfBlock>())) { if (childNode.BranchTaken.Value) { branchTakenNode = childNode; } } if (branchTakenNode != null) { var startSpan = branchTakenNode.Node.Span; var endSpan = branchTakenNode.NextNode.Node.Span; switch (branchTakenNode) { case IfBlock ifBlock: tokensToProcess.Add(ifBlock.Condition); break; case ElifBlock elifBlock: tokensToProcess.Add(elifBlock.Condition); break; } } } this.TokensToProcess = tokensToProcess.ToArray(); return(true); }
public bool Process(Dictionary <string, IWorkspaceTokenContentHandler> tokenContentHandlers, IWorkspaceTemplate workspaceTemplate, Guid projectType, string appName, string rawFileRelativePath, string outputFileName, string content, IGeneratorConfiguration generatorConfiguration) { var processing = true; var options = CSharpParseOptions.Default.WithPreprocessorSymbols(supportedTokens); IEnumerable <Diagnostic> diagnostics = null; this.OutputContent = content; while (processing) { var syntaxTree = CSharpSyntaxTree.ParseText(content, options); var root = syntaxTree.GetCompilationUnitRoot(); var walker = new DirectiveSyntaxWalker(supportedTokens); List <IfDirectiveBlock> generatorDirectiveBlocks; walker.Visit(root); generatorDirectiveBlocks = walker.GeneratorDirectiveBlocks; if (generatorDirectiveBlocks.Count > 0) { var generatorDirectiveBlock = generatorDirectiveBlocks.First(); var childNodes = generatorDirectiveBlock.ChildNodes.Reverse(); IfDirectiveNodeBase branchTakenNode = null; foreach (var childNode in childNodes.Where(n => !n.IsOfType <EndIfBlock>())) { if (childNode.BranchTaken.Value) { branchTakenNode = childNode; } else if (branchTakenNode != null) { var offsetLength = branchTakenNode.Node.FullSpan.Length; var length = childNode.Length - offsetLength; content = content.Remove(childNode.Start, length); childNodes.ShiftUp(childNode.Start, length); } else { content = content.Remove(childNode.Start, childNode.Length); childNodes.ShiftUp(childNode.Start, childNode.Length); } } if (branchTakenNode != null) { var startSpan = new TextSpan(branchTakenNode.Node.FullSpan.Start + branchTakenNode.ShiftAmount, branchTakenNode.Node.FullSpan.Length); var endSpan = new TextSpan(branchTakenNode.NextNode.Node.FullSpan.Start + branchTakenNode.ShiftAmount, branchTakenNode.NextNode.Node.FullSpan.Length); switch (branchTakenNode) { case IfBlock ifBlock: if (tokenContentHandlers.ContainsKey(ifBlock.Condition)) { var tokenContentHandler = tokenContentHandlers[ifBlock.Condition]; var insertContent = tokenContentHandler.Content; content = content.Remove(ifBlock.Start, ifBlock.Length); content = content.Insert(ifBlock.Start, insertContent); } else { content = content.Remove(endSpan.Start, endSpan.Length); content = content.Remove(startSpan.Start, startSpan.Length); } break; case ElifBlock elifBlock: DebugUtils.Break(); // untested if (tokenContentHandlers.ContainsKey(elifBlock.Condition)) { var tokenContentHandler = tokenContentHandlers[elifBlock.Condition]; var insertContent = tokenContentHandler.Content; content = content.Remove(elifBlock.Start, elifBlock.Length); content = content.Insert(elifBlock.Start, insertContent); } else { content = content.Remove(endSpan.Start, endSpan.Length); content = content.Remove(startSpan.Start, startSpan.Length); } break; case ElseBlock elseBlock: content = content.Remove(endSpan.Start, endSpan.Length); content = content.Remove(startSpan.Start, startSpan.Length); break; } } } else { processing = false; } diagnostics = syntaxTree.GetDiagnostics(); } if (diagnostics.Count() > 0) { DebugUtils.Break(); } this.OutputContent = content; return(true); }