public void Dump(Indenter stream) { // display the nodes in reverse order of creation as we create the tree bottom-up so the last are the topmost nodes for (int i = _count - 1; i >= 0; i--) { Node node = _index[i]; stream.WriteLine("{0,4:D4} {1} {2}:", node.Id, node.ToString(), node.Position.ToString()); stream.Indent(); node.DumpFields(stream); stream.Dedent(); stream.WriteLine(); } }
public override void DumpFields(Indenter stream) { base.DumpFields(stream); System.Text.StringBuilder mangled = new System.Text.StringBuilder(64); this.Encode(mangled); stream.WriteLine("Mangled = {0}", mangled.ToString()); stream.WriteLine("Demangled = {0}", Demangler.Decode(mangled.ToString())); foreach (ParameterDeclaration parameter in _parameters) stream.WriteLine("Parameter = {0,4:D4}", parameter.Id); stream.WriteLine("Body = {0,4:D4}", (_body == null) ? "null" : _body.Id.ToString("D4")); }
public void IndentCaseOnWorks() { var code = new[] { "Public Function Test() As Integer", "Select Case Foo", "Case Bar", "Test = 1", "Case Baz", "Test = 2", "End Select", "End Function" }; var expected = new[] { "Public Function Test() As Integer", " Select Case Foo", " Case Bar", " Test = 1", " Case Baz", " Test = 2", " End Select", "End Function" }; var indenter = new Indenter(null, () => { var s = IndenterSettingsTests.GetMockIndenterSettings(); s.IndentCase = true; return(s); }); var actual = indenter.Indent(code); Assert.IsTrue(expected.SequenceEqual(actual)); }
public void VerticalSpacing_DimBlocksStayIntact() { var code = new[] { "Private foo As String", "Private bar As String", "", "Function TestFunction() As Long", "End Function", "Sub TestSub()", "End Sub" }; var expected = new[] { "Private foo As String", "Private bar As String", "", "Function TestFunction() As Long", "End Function", "", "Sub TestSub()", "End Sub" }; var indenter = new Indenter(null, () => { var s = IndenterSettingsTests.GetMockIndenterSettings(); s.VerticallySpaceProcedures = true; s.LinesBetweenProcedures = 1; return(s); }); var actual = indenter.Indent(code); Assert.IsTrue(expected.SequenceEqual(actual)); }
public void VerticalSpacing_IgnoresDeclareFunctions() { var code = new[] { @"Public Declare Function Foo Lib ""bar.dll"" (X As Any) As Variant", @"Public Declare Sub Bar Lib ""bar.dll"" (Y As Integer)", "", "Function TestFunction() As Long", "End Function", "Sub TestSub()", "End Sub" }; var expected = new[] { @"Public Declare Function Foo Lib ""bar.dll"" (X As Any) As Variant", @"Public Declare Sub Bar Lib ""bar.dll"" (Y As Integer)", "", "Function TestFunction() As Long", "End Function", "", "Sub TestSub()", "End Sub" }; var indenter = new Indenter(null, () => { var s = IndenterSettingsTests.GetMockIndenterSettings(); s.VerticallySpaceProcedures = true; s.LinesBetweenProcedures = 1; return(s); }); var actual = indenter.Indent(code); Assert.IsTrue(expected.SequenceEqual(actual)); }
public void IndentFirstDeclarationBlockOffOnlyOnFirst() { var code = new[] { "Public Function Test() As String", "'Comment block", "'Comment block", "Dim Foo As Long", "Dim Bar As Long", @"Test = ""Passed!""", "Dim Baz as Long", "End Function" }; var expected = new[] { "Public Function Test() As String", " 'Comment block", " 'Comment block", "Dim Foo As Long", "Dim Bar As Long", @" Test = ""Passed!""", " Dim Baz as Long", "End Function" }; var indenter = new Indenter(null, () => { var s = IndenterSettingsTests.GetMockIndenterSettings(); s.IndentFirstDeclarationBlock = false; return(s); }); var actual = indenter.Indent(code); Assert.IsTrue(expected.SequenceEqual(actual)); }
protected override bool ShouldUseTokenIndenter(Indenter indenter, out SyntaxToken syntaxToken) => ShouldUseSmartTokenFormatterInsteadOfIndenter( indenter.Rules, indenter.Root, indenter.LineToBeIndented, indenter.Options, out syntaxToken);
public override void DumpFields(Indenter stream) { stream.WriteLine("Name = {0}", _name); }
public override void DumpFields(Indenter stream) { stream.WriteLine("Commands = {0,4:D4}", _commands.Id); }
protected abstract ISmartTokenFormatter CreateSmartTokenFormatter(Indenter indenter);
public override void DumpFields(Indenter stream) { foreach (Command command in _commands) stream.WriteLine("Command = {0,4:D4}", command.Id); }
public DecompilerOutput(IDecompilerEventReceiver eventReceiver, RenderTreeBuilder builder, int sequence, Indenter indenter) { this.eventReceiver = eventReceiver; this.builder = builder; this.NextSequence = sequence; this.indenter = indenter; }
public override void DumpFields(Indenter stream) { stream.WriteLine("Name = {0}", _identifier); foreach (Expression argument in _arguments) stream.WriteLine("Argument = {0,4:D4}", argument.Id); }
public override void DumpFields(Indenter stream) { stream.WriteLine("Value = {0}", _value); }
protected override IndentationResult?GetDesiredIndentationWorker(Indenter indenter, SyntaxToken?tokenOpt, SyntaxTrivia?triviaOpt) => TryGetDesiredIndentation(indenter, triviaOpt) ?? TryGetDesiredIndentation(indenter, tokenOpt);
/// <summary> /// Constructor /// </summary> /// <param name="writer">Text writer to use</param> /// <param name="indenter">Indenter or null</param> public TextWriterDecompilerOutput(TextWriter writer, Indenter indenter = null) { this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); this.indenter = indenter ?? new Indenter(4, 4, true); }
public override void DumpFields(Indenter stream) { stream.WriteLine("Value = {0}", _value ? "true" : "false"); }
public override void DumpFields(Indenter stream) { stream.WriteLine("Kind = {0}", _kind.ToString()); }
public abstract void DumpFields(Indenter stream);
public override void DumpFields(Indenter stream) { stream.WriteLine("Name = {0}", _name); stream.WriteLine("Kind = {0}", _kind.ToString()); stream.WriteLine("Type = {0,4:D4}", _type.Id); }
/// <summary> /// Constructor /// </summary> public StringBuilderDecompilerOutput() { sb = new StringBuilder(); indenter = new Indenter(4, 4, true); }
public override void DumpFields(Indenter stream) { base.DumpFields(stream); }
private static void CreateReadFunction(SaveType type, Indenter sb) { sb.AppendLine(); sb.AppendLine($"public {type.Name}(DataBuffer save)"); sb.AppendLineAndIncrease("{"); bool firstField = true; bool prevWasArray = false; foreach (var field in type.Fields) { switch (field.Type) { case "Scalar": if (prevWasArray) { sb.AppendLine(); } if (field.DataType == "string") { sb.AppendLine(GetReadValue(field)); } else { sb.AppendLine($"{field.Name} = {GetReadValue(field)}"); } prevWasArray = false; break; case "Array": if (!firstField) { sb.AppendLine(); } sb.AppendLine($"for (int i = 0; i < {field.Name}.Length; i++)"); sb.AppendLineAndIncrease("{"); sb.AppendLine($"{field.Name}[i] = {GetReadValue(field)}"); sb.DecreaseAndAppendLine("}"); prevWasArray = true; break; case "Bitfield": sb.AppendLine($"{field.DataType} {field.Name} = {GetReadValue(field)}"); int bit = 0; foreach (var value in field.Bitfield) { sb.AppendLine( $"{value.Name} = ({field.DataType})({field.Name} >> {bit} & ((1u << {value.Size}) - 1));"); bit += int.Parse(value.Size); } break; case "BitfieldArray": sb.AppendLine($"Read.ReadBitfieldArray(save, {field.Name}, {field.Length}, {field.Size});"); break; case "Padding": sb.AppendLine($"save.Position += {field.Length};"); break; } firstField = false; } sb.DecreaseAndAppendLine("}"); }
TextColorWriterToDecompilerOutput(ITextColorWriter output) { this.output = output; indenter = new Indenter(4, 4, true); offset = 0; }
protected override IndentationResult GetDesiredIndentationWorker( Indenter indenter, SyntaxToken token, TextLine previousLine, int lastNonWhitespacePosition) { // okay, now check whether the text we found is trivia or actual token. if (token.Span.Contains(lastNonWhitespacePosition)) { // okay, it is a token case, do special work based on type of last token on previous line return(GetIndentationBasedOnToken(indenter, token)); } else { // there must be trivia that contains or touch this position Debug.Assert(token.FullSpan.Contains(lastNonWhitespacePosition)); // okay, now check whether the trivia is at the beginning of the line var firstNonWhitespacePosition = previousLine.GetFirstNonWhitespacePosition(); if (!firstNonWhitespacePosition.HasValue) { return(indenter.IndentFromStartOfLine(0)); } var trivia = indenter.Root.FindTrivia(firstNonWhitespacePosition.Value, findInsideTrivia: true); if (trivia.Kind() == SyntaxKind.None || indenter.LineToBeIndented.LineNumber > previousLine.LineNumber + 1) { // If the token belongs to the next statement and is also the first token of the statement, then it means the user wants // to start type a new statement. So get indentation from the start of the line but not based on the token. // Case: // static void Main(string[] args) // { // // A // // B // // $$ // return; // } var containingStatement = token.GetAncestor <StatementSyntax>(); if (containingStatement != null && containingStatement.GetFirstToken() == token) { var position = indenter.GetCurrentPositionNotBelongToEndOfFileToken(indenter.LineToBeIndented.Start); return(indenter.IndentFromStartOfLine(indenter.Finder.GetIndentationOfCurrentPosition(indenter.Tree, token, position, indenter.CancellationToken))); } // If the token previous of the base token happens to be a Comma from a separation list then we need to handle it different // Case: // var s = new List<string> // { // """", // """",/*sdfsdfsdfsdf*/ // // dfsdfsdfsdfsdf // // $$ // }; var previousToken = token.GetPreviousToken(); if (previousToken.IsKind(SyntaxKind.CommaToken)) { return(GetIndentationFromCommaSeparatedList(indenter, previousToken)); } else if (!previousToken.IsKind(SyntaxKind.None)) { // okay, beginning of the line is not trivia, use the last token on the line as base token return(GetIndentationBasedOnToken(indenter, token)); } } // this case we will keep the indentation of this trivia line // this trivia can't be preprocessor by the way. return(indenter.GetIndentationOfLine(previousLine)); } }
public override void DumpFields(Indenter stream) { stream.WriteLine("Expression = {0,4:D4}", _expression.Id); }
public static bool Fits( PrintCommand nextCommand, Stack <PrintCommand> remainingCommands, int remainingWidth, Dictionary <string, PrintMode> groupModeMap, Indenter indenter ) { var returnFalseIfMoreStringsFound = false; var newCommands = new Stack <PrintCommand>(); newCommands.Push(nextCommand); void Push(Doc doc, PrintMode printMode, Indent indent) { newCommands.Push(new PrintCommand(indent, printMode, doc)); } var output = new StringBuilder(); for (var x = 0; x < remainingCommands.Count || newCommands.Count > 0;) { if (remainingWidth < 0) { return(false); } PrintCommand command; if (newCommands.Count > 0) { command = newCommands.Pop(); } else { command = remainingCommands.ElementAt(x); x++; } var(currentIndent, currentMode, currentDoc) = command; if (currentDoc is StringDoc stringDoc) { if (stringDoc.Value == null) { continue; } if (returnFalseIfMoreStringsFound) { return(false); } output.Append(stringDoc.Value); remainingWidth -= stringDoc.Value.GetPrintedWidth(); } else if (currentDoc != Doc.Null) { switch (currentDoc) { case LeadingComment: case TrailingComment: if (output.Length > 0) { returnFalseIfMoreStringsFound = true; } break; case Concat concat: for (var i = concat.Contents.Count - 1; i >= 0; i--) { Push(concat.Contents[i], currentMode, currentIndent); } break; case IndentDoc indent: Push( indent.Contents, currentMode, indenter.IncreaseIndent(currentIndent) ); break; case Trim: remainingWidth += output.TrimTrailingWhitespace(); break; case Group group: var groupMode = group.Break ? PrintMode.Break : currentMode; // when determining if something fits, use the last option from a conditionalGroup, which should be the most expanded one var groupContents = groupMode == PrintMode.Break && group is ConditionalGroup conditionalGroup ? conditionalGroup.Options.Last() : group.Contents; Push(groupContents, groupMode, currentIndent); if (group.GroupId != null) { groupModeMap ![group.GroupId] = groupMode;
/// <summary> /// Returns <see langword="true"/> if the language specific <see /// cref="ISmartTokenFormatter"/> should be deferred to figure out indentation. If so, it /// will be asked to <see cref="ISmartTokenFormatter.FormatTokenAsync"/> the resultant /// <paramref name="token"/> provided by this method. /// </summary> protected abstract bool ShouldUseTokenIndenter(Indenter indenter, out SyntaxToken token);
public static void PrintTable(BdatStringTable table, Indenter sb) { sb.AppendLineAndIncrease("<table class=\"sortable\">"); sb.AppendLineAndIncrease("<thead>"); sb.AppendLineAndIncrease("<tr id=\"header\">"); sb.AppendLine("<th class=\" dir-d \">ID</th>"); sb.AppendLine("<th>Referenced By</th>"); foreach (BdatMember member in table.Members) { if (member.Metadata?.Type == BdatFieldType.Hide) { continue; } bool sticky = table.DisplayMember == member.Name; string cellTag = $"<th{(sticky ? " class=\"side\"" : "")}"; switch (member.Type) { case BdatMemberType.Scalar: case BdatMemberType.Flag: sb.AppendLine($"{cellTag}>{member.Name}</th>"); break; case BdatMemberType.Array: sb.AppendLine($"{cellTag} colspan=\"{member.ArrayCount}\">{member.Name}</th>"); break; } } sb.DecreaseAndAppendLine("</tr>"); sb.DecreaseAndAppendLine("</thead>"); foreach (BdatStringItem item in table.Items.Where(x => x != null)) { sb.AppendLineAndIncrease($"<tr id=\"{item.Id}\">"); sb.AppendLine($"<td>{item.Id}</td>"); sb.AppendLineAndIncrease("<td>"); if (item.ReferencedBy.Count > 0) { sb.AppendLineAndIncrease("<details>"); sb.AppendLine($"<summary>{item.ReferencedBy.Count} refs</summary>"); foreach (BdatStringItem a in item.ReferencedBy.OrderBy(x => x.Table.Name).ThenBy(x => x.Id)) { string link = GetLink(table, a.Table, a.Id.ToString()); string display = (string)a.Display?.Display ?? a.Id.ToString(); if (string.IsNullOrWhiteSpace(display)) { display = a.Id.ToString(); } sb.AppendLine($"<a href=\"{link}\">{a.Table.Name}#{display}</a>"); } sb.DecreaseAndAppendLine("</details>"); } sb.DecreaseAndAppendLine("</td>"); foreach (BdatStringValue value in item.Values.Values) { BdatMember member = value.Member; if (member.Metadata?.Type == BdatFieldType.Hide) { continue; } bool sticky = value.Parent.Display == value; string cellTag = $"<td{(sticky ? " class=\"side\"" : "")}>"; switch (member.Type) { case BdatMemberType.Scalar: case BdatMemberType.Flag: PrintValue(value, cellTag); break; case BdatMemberType.Array: foreach (BdatStringValue arrValue in value.Array) { PrintValue(arrValue, cellTag); } break; } } sb.DecreaseAndAppendLine("</tr>"); } sb.DecreaseAndAppendLine("</table>"); void PrintValue(BdatStringValue value, string cellTag) { BdatStringItem child = value.Reference; if (child != null) { string display = child.Display?.DisplayString; if (string.IsNullOrWhiteSpace(display)) { display = child.Id.ToString(); } string link = GetLink(table, child.Table, child.Id.ToString()); sb.AppendLine($"{cellTag}<a href=\"{link}\">{WebUtility.HtmlEncode(display)}</td></a>"); } else { sb.AppendLine($"{cellTag}{WebUtility.HtmlEncode(value.DisplayString)}</td>"); } } }
protected abstract IndentationResult GetDesiredIndentationWorker( Indenter indenter, SyntaxToken token, TextLine previousLine, int lastNonWhitespacePosition);
public static void PrintTable(BdatStringCollection tables, BdatInfo info, string tableName, Indenter sb) { BdatStringTable table = tables[tableName]; sb.AppendLineAndIncrease("<table border=\"1\">"); sb.AppendLineAndIncrease("<thead>"); sb.AppendLineAndIncrease("<tr>"); sb.AppendLine("<th>ID</th>"); sb.AppendLine("<th>Referenced By</th>"); foreach (BdatMember member in table.Members) { if (info.FieldInfo.TryGetValue((tableName, member.Name), out var field)) { if (field.Type == BdatFieldType.Hide) { continue; } } switch (member.Type) { case BdatMemberType.Scalar: case BdatMemberType.Flag: sb.AppendLine($"<th>{member.Name}</th>"); break; case BdatMemberType.Array: sb.AppendLine($"<th colspan=\"{member.ArrayCount}\">{member.Name}</th>"); break; } } sb.DecreaseAndAppendLine("</tr>"); sb.DecreaseAndAppendLine("</thead>"); int id = table.BaseId; foreach (BdatStringItem item in table.Items) { sb.AppendLineAndIncrease($"<tr id=\"{id}\">"); sb.AppendLine($"<td>{id}</td>"); sb.AppendLineAndIncrease("<td>"); if (item.ReferencedBy.Count > 0) { sb.AppendLineAndIncrease("<details>"); sb.AppendLine($"<summary>{item.ReferencedBy.Count} refs</summary>"); foreach (var a in item.ReferencedBy) { var link = GetLink(table, tables[a.Table], a.Id.ToString()); string display = a.Id.ToString(); if (info.DisplayFields.TryGetValue(a.Table, out var displayField)) { var child = BdatStringTools.ReadValue(a.Table, a.Id, displayField, tables, info); if (!string.IsNullOrWhiteSpace(child.value)) { display = child.value; } } sb.AppendLine($"<a href=\"{link}\">{a.Table}#{display}</a>"); } sb.DecreaseAndAppendLine("</details>"); } sb.DecreaseAndAppendLine("</td>"); foreach (BdatMember member in table.Members) { if (info.FieldInfo.TryGetValue((tableName, member.Name), out var field)) { if (field.Type == BdatFieldType.Hide) { continue; } } switch (member.Type) { case BdatMemberType.Scalar: case BdatMemberType.Flag: var val = BdatStringTools.ReadValue(tableName, id, member.Name, tables, info); if (val.childTable != null) { var link = GetLink(table, tables[val.childTable], val.childId); sb.AppendLine($"<td><a href=\"{link}\">{val.value}</td></a>"); } else { sb.AppendLine($"<td>{val.value}</td>"); } break; case BdatMemberType.Array: var arr = (string[])item.Values[member.Name]; foreach (string value in arr) { sb.AppendLine($"<td>{value}</td>"); } break; } } sb.DecreaseAndAppendLine("</tr>"); id++; } sb.DecreaseAndAppendLine("</table>"); }
public override void DumpFields(Indenter stream) { foreach (Declaration declaration in _declarations) stream.WriteLine("Declaration = {0,4:D4}", declaration.Id); }
public void RespectsGroupRelatedPropertiesIndenterSetting(bool groupRelatedProperties) { var inputCode = @" Public mTestField As Long Public mTestField1 As Long Public mTestField2 As Long "; EncapsulateFieldUseBackingFieldModel modelBuilder(RubberduckParserState state, EncapsulateFieldTestsResolver resolver) { var field = state.AllUserDeclarations.Single(d => d.IdentifierName.Equals("mTestField")); var fieldModel = new FieldEncapsulationModel(field as VariableDeclaration, false); var modelFactory = resolver.Resolve <IEncapsulateFieldUseBackingFieldModelFactory>(); var model = modelFactory.Create(new List <FieldEncapsulationModel>() { fieldModel }); foreach (var candidate in model.EncapsulationCandidates) { candidate.EncapsulateFlag = true; } return(model); } var testIndenter = new Indenter(null, () => { var s = IndenterSettingsTests.GetMockIndenterSettings(); s.VerticallySpaceProcedures = true; s.LinesBetweenProcedures = 1; s.GroupRelatedProperties = groupRelatedProperties; return(s); }); var refactoredCode = RefactoredCode(inputCode, modelBuilder, testIndenter); var lines = refactoredCode.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); var expectedGrouped = new[] { "Public Property Get TestField() As Long", "TestField = mTestField", "End Property", "Public Property Let TestField(ByVal RHS As Long)", "mTestField = RHS", "End Property", "", "Public Property Get TestField1() As Long", "TestField1 = mTestField1", "End Property", "Public Property Let TestField1(ByVal RHS As Long)", "mTestField1 = RHS", "End Property", "", "Public Property Get TestField2() As Long", "TestField2 = mTestField2", "End Property", "Public Property Let TestField2(ByVal RHS As Long)", "mTestField2 = RHS", "End Property", "", }; var expectedNotGrouped = new[] { "Public Property Get TestField() As Long", "TestField = mTestField", "End Property", "", "Public Property Let TestField(ByVal RHS As Long)", "mTestField = RHS", "End Property", "", "Public Property Get TestField1() As Long", "TestField1 = mTestField1", "End Property", "", "Public Property Let TestField1(ByVal RHS As Long)", "mTestField1 = RHS", "End Property", "", "Public Property Get TestField2() As Long", "TestField2 = mTestField2", "End Property", "", "Public Property Let TestField2(ByVal RHS As Long)", "mTestField2 = RHS", "End Property", "", }; var idx = 0; IList <string> expected = groupRelatedProperties ? expectedGrouped.ToList() : expectedNotGrouped.ToList(); var refactoredLinesOfInterest = lines.SkipWhile(rl => !rl.Contains(expected[0])); Assert.IsTrue(refactoredLinesOfInterest.Any()); foreach (var line in refactoredLinesOfInterest) { if (!line.Contains("=")) { StringAssert.AreEqualIgnoringCase(expected[idx], line); } idx++; } }
private static IndentationResult GetIndentationFromCommaSeparatedList(Indenter indenter, SyntaxToken token) => token.Parent switch {
public RefactorEncapsulateFieldCommand(IVBE vbe, RubberduckParserState state, Indenter indenter) : base(vbe) { _state = state; _indenter = indenter; }
private static IndentationResult GetIndentationBasedOnToken(Indenter indenter, SyntaxToken token) { Contract.ThrowIfNull(indenter.Tree); Contract.ThrowIfTrue(token.Kind() == SyntaxKind.None); // special cases // case 1: token belongs to verbatim token literal // case 2: $@"$${0}" // case 3: $@"Comment$$ in-between{0}" // case 4: $@"{0}$$" if (token.IsVerbatimStringLiteral() || token.IsKind(SyntaxKind.InterpolatedVerbatimStringStartToken) || token.IsKind(SyntaxKind.InterpolatedStringTextToken) || (token.IsKind(SyntaxKind.CloseBraceToken) && token.Parent.IsKind(SyntaxKind.Interpolation))) { return(indenter.IndentFromStartOfLine(0)); } // if previous statement belong to labeled statement, don't follow label's indentation // but its previous one. if (token.Parent is LabeledStatementSyntax || token.IsLastTokenInLabelStatement()) { token = token.GetAncestor <LabeledStatementSyntax>() !.GetFirstToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true); } var position = indenter.GetCurrentPositionNotBelongToEndOfFileToken(indenter.LineToBeIndented.Start); // first check operation service to see whether we can determine indentation from it var indentation = indenter.Finder.FromIndentBlockOperations(indenter.Tree, token, position, indenter.CancellationToken); if (indentation.HasValue) { return(indenter.IndentFromStartOfLine(indentation.Value)); } var alignmentTokenIndentation = indenter.Finder.FromAlignTokensOperations(indenter.Tree, token); if (alignmentTokenIndentation.HasValue) { return(indenter.IndentFromStartOfLine(alignmentTokenIndentation.Value)); } // if we couldn't determine indentation from the service, use heuristic to find indentation. var sourceText = indenter.LineToBeIndented.Text; RoslynDebug.AssertNotNull(sourceText); // If this is the last token of an embedded statement, walk up to the top-most parenting embedded // statement owner and use its indentation. // // cases: // if (true) // if (false) // Goo(); // // if (true) // { } if (token.IsSemicolonOfEmbeddedStatement() || token.IsCloseBraceOfEmbeddedBlock()) { Debug.Assert( token.Parent != null && (token.Parent.Parent is StatementSyntax || token.Parent.Parent is ElseClauseSyntax)); var embeddedStatementOwner = token.Parent.Parent; while (embeddedStatementOwner.IsEmbeddedStatement()) { RoslynDebug.AssertNotNull(embeddedStatementOwner.Parent); embeddedStatementOwner = embeddedStatementOwner.Parent; } return(indenter.GetIndentationOfLine(sourceText.Lines.GetLineFromPosition(embeddedStatementOwner.GetFirstToken(includeZeroWidth: true).SpanStart))); } switch (token.Kind()) { case SyntaxKind.SemicolonToken: { // special cases if (token.IsSemicolonInForStatement()) { return(GetDefaultIndentationFromToken(indenter, token)); } return(indenter.IndentFromStartOfLine(indenter.Finder.GetIndentationOfCurrentPosition(indenter.Tree, token, position, indenter.CancellationToken))); } case SyntaxKind.CloseBraceToken: { if (token.Parent.IsKind(SyntaxKind.AccessorList) && token.Parent.Parent.IsKind(SyntaxKind.PropertyDeclaration)) { if (token.GetNextToken().IsEqualsTokenInAutoPropertyInitializers()) { return(GetDefaultIndentationFromToken(indenter, token)); } } return(indenter.IndentFromStartOfLine(indenter.Finder.GetIndentationOfCurrentPosition(indenter.Tree, token, position, indenter.CancellationToken))); } case SyntaxKind.OpenBraceToken: { return(indenter.IndentFromStartOfLine(indenter.Finder.GetIndentationOfCurrentPosition(indenter.Tree, token, position, indenter.CancellationToken))); } case SyntaxKind.ColonToken: { var nonTerminalNode = token.Parent; Contract.ThrowIfNull(nonTerminalNode, @"Malformed code or bug in parser???"); if (nonTerminalNode is SwitchLabelSyntax) { return(indenter.GetIndentationOfLine(sourceText.Lines.GetLineFromPosition(nonTerminalNode.GetFirstToken(includeZeroWidth: true).SpanStart), indenter.Options.FormattingOptions.IndentationSize)); } goto default; } case SyntaxKind.CloseBracketToken: { var nonTerminalNode = token.Parent; Contract.ThrowIfNull(nonTerminalNode, @"Malformed code or bug in parser???"); // if this is closing an attribute, we shouldn't indent. if (nonTerminalNode is AttributeListSyntax) { return(indenter.GetIndentationOfLine(sourceText.Lines.GetLineFromPosition(nonTerminalNode.GetFirstToken(includeZeroWidth: true).SpanStart))); } goto default; } case SyntaxKind.XmlTextLiteralToken: { return(indenter.GetIndentationOfLine(sourceText.Lines.GetLineFromPosition(token.SpanStart))); } case SyntaxKind.CommaToken: { return(GetIndentationFromCommaSeparatedList(indenter, token)); } case SyntaxKind.CloseParenToken: { if (token.Parent.IsKind(SyntaxKind.ArgumentList)) { return(GetDefaultIndentationFromToken(indenter, token.Parent.GetFirstToken(includeZeroWidth: true))); } goto default; } default: { return(GetDefaultIndentationFromToken(indenter, token)); } } }
private static void PrintEnemy(Enemy enemy, Indenter sb) { sb.AppendLine($"<h2>{enemy.Name} (#{enemy.Id})</h2>"); sb.AppendLineAndIncrease("<table>"); sb.AppendLine($"<tr><td>Normal</td><td>{enemy.NormalDropRate:P2}</td>"); sb.AppendLine($"<tr><td>Rare</td><td>{enemy.RareDropRate:P2}</td>"); sb.AppendLine($"<tr><td>Super Rare</td><td>{enemy.SuperRareDropRate:P2}</td>"); sb.DecreaseAndAppendLine("</table>"); if (enemy.HasNormalDrops()) { sb.AppendLine("<h3>Normal:</h3>"); sb.AppendLine("<h4>Materials (From normal chest)</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.NormalDrops.MaterialsDouble.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); sb.AppendLine("<h4>Materials (From other chests)</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.NormalDrops.MaterialsSingle.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } if (enemy.HasRareDrops()) { sb.AppendLine("<h3>Rare:</h3>"); if (enemy.RareDrops.Crystals.Any(x => x.TotalDropRate != 0)) { if (enemy.RareDrops.Crystals.Any(x => x.Item.IsCylinder)) { sb.AppendLine("<h4>Cylinders</h4>"); } else { sb.AppendLine("<h4>Crystals</h4>"); } sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.RareDrops.Crystals.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.GetDisplayString()}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } if (enemy.RareDrops.Weapons.Any(x => x.TotalDropRate != 0)) { sb.AppendLine("<h4>Weapons</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.RareDrops.Weapons.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{GetSlotsString(item.SlotCount)}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } if (enemy.RareDrops.Armor.Any(x => x.TotalDropRate != 0)) { sb.AppendLine("<h4>Armor</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.RareDrops.Armor.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{GetSlotsString(item.SlotCount)}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } if (enemy.RareDrops.ArtBooks.Any(x => x.TotalDropRate != 0)) { sb.AppendLine("<h4>Art Books</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.RareDrops.ArtBooks.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } } if (enemy.HasSuperRareDrops()) { sb.AppendLine("<h3>Super Rare:</h3>"); if (enemy.SuperRareDrops.Weapons.Any(x => x.TotalDropRate != 0)) { sb.AppendLine("<h4>Weapons</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.SuperRareDrops.Weapons.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{GetSlotsString(item.SlotCount)}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } if (enemy.SuperRareDrops.UniqueWeapons.Any(x => x.TotalDropRate != 0)) { sb.AppendLine("<h4>Unique Weapons</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.SuperRareDrops.UniqueWeapons.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } if (enemy.SuperRareDrops.UniqueArmor.Any(x => x.TotalDropRate != 0)) { sb.AppendLine("<h4>Unique Armor</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.SuperRareDrops.UniqueArmor.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } if (enemy.SuperRareDrops.ArtBooks.Any(x => x.TotalDropRate != 0)) { sb.AppendLine("<h4>Art Books</h4>"); sb.AppendLineAndIncrease("<table>"); foreach (var item in enemy.SuperRareDrops.ArtBooks.OrderDrops()) { sb.AppendLine($"<tr><td>{item.Item.Name}</td><td>{item.TotalDropRate:P2}</td>"); } sb.DecreaseAndAppendLine("</table>"); } } }
/// <summary> /// Constructor /// </summary> /// <param name="indenter">Indenter</param> public StringBuilderDecompilerOutput(Indenter indenter) { sb = new StringBuilder(); this.indenter = indenter ?? throw new ArgumentNullException(nameof(indenter)); }
protected abstract IndentationResult?GetDesiredIndentationWorker( Indenter indenter, SyntaxToken?token, SyntaxTrivia?trivia);