private GetBasicBlocksForRange ( uint startOffset, uint endOffset ) : Sublist |
||
startOffset | uint | |
endOffset | uint | |
Результат | Sublist |
private void SplitBlock(DecompiledBlock blockToSplit, uint splitOffset, List <IStatement> leftList, List <IStatement> rightList) { Contract.Requires(blockToSplit != null); Contract.Requires(leftList != null); Contract.Requires(rightList != null); Contract.Requires(splitOffset >= blockToSplit.StartOffset); Contract.Requires(splitOffset <= blockToSplit.EndOffset); var leftBasicBlocks = blockToSplit.GetBasicBlocksForRange(blockToSplit.StartOffset, splitOffset); Contract.Assume(splitOffset >= blockToSplit.StartOffset); var leftBlock = new DecompiledBlock(blockToSplit.StartOffset, splitOffset, leftBasicBlocks, isLexicalScope: false); leftList.Add(leftBlock); var rightBasicBlocks = blockToSplit.GetBasicBlocksForRange(splitOffset, blockToSplit.EndOffset); Contract.Assume(splitOffset <= blockToSplit.EndOffset); var rightBlock = new DecompiledBlock(splitOffset, blockToSplit.EndOffset, rightBasicBlocks, isLexicalScope: false); rightList.Add(rightBlock); var n = blockToSplit.Statements.Count; if (n == 0) { return; } var leftStatements = leftBlock.Statements = new List <IStatement>(); var rightStatements = rightBlock.Statements = new List <IStatement>(); for (int i = 0; i < n; i++) { var nb = blockToSplit.Statements[i] as DecompiledBlock; Contract.Assume(nb != null); if (nb.EndOffset <= splitOffset) { leftStatements.Add(nb); } else if (nb.StartOffset < splitOffset) { Contract.Assume(!nb.IsLexicalScope); //lexical scopes are assumed to nest cleanly. this.SplitBlock(nb, splitOffset, leftStatements, rightStatements); } else { rightStatements.Add(nb); } } Consolidate(leftBlock); Consolidate(rightBlock); }
private void SplitBlock(DecompiledBlock blockToSplit, uint splitOffset, List<IStatement> leftList, List<IStatement> rightList) { Contract.Requires(blockToSplit != null); Contract.Requires(leftList != null); Contract.Requires(rightList != null); Contract.Requires(splitOffset >= blockToSplit.StartOffset); Contract.Requires(splitOffset <= blockToSplit.EndOffset); var leftBasicBlocks = blockToSplit.GetBasicBlocksForRange(blockToSplit.StartOffset, splitOffset); Contract.Assume(splitOffset >= blockToSplit.StartOffset); var leftBlock = new DecompiledBlock(blockToSplit.StartOffset, splitOffset, leftBasicBlocks, isLexicalScope: false); leftList.Add(leftBlock); var rightBasicBlocks = blockToSplit.GetBasicBlocksForRange(splitOffset, blockToSplit.EndOffset); Contract.Assume(splitOffset <= blockToSplit.EndOffset); var rightBlock = new DecompiledBlock(splitOffset, blockToSplit.EndOffset, rightBasicBlocks, isLexicalScope: false); rightList.Add(rightBlock); var n = blockToSplit.Statements.Count; if (n == 0) return; var leftStatements = leftBlock.Statements = new List<IStatement>(); var rightStatements = rightBlock.Statements = new List<IStatement>(); for (int i = 0; i < n; i++) { var nb = blockToSplit.Statements[i] as DecompiledBlock; Contract.Assume(nb != null); if (nb.EndOffset <= splitOffset) { leftStatements.Add(nb); } else if (nb.StartOffset < splitOffset) { Contract.Assume(!nb.IsLexicalScope); //lexical scopes are assumed to nest cleanly. this.SplitBlock(nb, splitOffset, leftStatements, rightStatements); } else { rightStatements.Add(nb); } } Consolidate(leftBlock); Consolidate(rightBlock); }
private DecompiledBlock CreateNestedBlock(DecompiledBlock block, uint startOffset, uint endOffset) { Contract.Requires(block != null); Contract.Requires(startOffset <= endOffset); Contract.Ensures(Contract.Result <DecompiledBlock>() != null); { nextBlock: foreach (var statement in block.Statements) { var nestedBlock = statement as DecompiledBlock; if (nestedBlock == null) { continue; } if (nestedBlock.StartOffset <= startOffset && nestedBlock.EndOffset >= endOffset) { block = nestedBlock; goto nextBlock; } } } if (block.StartOffset == startOffset && block.EndOffset == endOffset) { return(block); } //replace block.Statements with three nested blocks, the middle one corresponding to one we have to create //but keep any declarations. int n = block.Statements.Count; var oldStatements = block.Statements; var newStatements = block.Statements; int m = 0; if (n >= 0) { while (m < n && oldStatements[m] is LocalDeclarationStatement) { m++; } if (m < n) { newStatements = new List <IStatement>(m + 3); for (int i = 0; i < m; i++) { newStatements.Add(oldStatements[i]); } } } block.Statements = newStatements; var basicBlocks = block.GetBasicBlocksForRange(startOffset, endOffset); var newNestedBlock = new DecompiledBlock(startOffset, endOffset, basicBlocks, isLexicalScope: true); DecompiledBlock beforeBlock = null; if (block.StartOffset < startOffset) { var basicBlocksBefore = block.GetBasicBlocksForRange(block.StartOffset, startOffset); Contract.Assume(block.StartOffset < startOffset); beforeBlock = new DecompiledBlock(block.StartOffset, startOffset, basicBlocksBefore, isLexicalScope: false); newStatements.Add(beforeBlock); } newStatements.Add(newNestedBlock); DecompiledBlock afterBlock = null; if (block.EndOffset > endOffset) { var basicBlocksAfter = block.GetBasicBlocksForRange(endOffset, block.EndOffset); Contract.Assume(block.EndOffset > endOffset); afterBlock = new DecompiledBlock(endOffset, block.EndOffset, basicBlocksAfter, isLexicalScope: false); newStatements.Add(afterBlock); } if (newStatements != oldStatements) { //In this case there were already some nested blocks, which happens when there are nested exception blocks //and we are creating an enclosing lexical block that does not quite coincide with block. //We now have to populate the newly created blocks with these nested blocks, splitting them if necessary. for (int i = m; i < n; i++) { var nb = oldStatements[i] as DecompiledBlock; Contract.Assume(nb != null); if (nb.EndOffset <= startOffset) { Contract.Assume(beforeBlock != null); beforeBlock.Statements.Add(nb); } else if (nb.StartOffset < startOffset) { Contract.Assume(nb.EndOffset <= endOffset); //nb starts before newNestedBlock but ends inside it. Contract.Assume(beforeBlock != null); if (nb.IsLexicalScope) { //Lexical scopes are assumed to nest cleanly. But the C# is not playing along when one using statement immediately follows another //Well fix matters by making nb.EndOffset == startOffset nb.EndOffset = startOffset; beforeBlock.Statements.Add(nb); } else { this.SplitBlock(nb, startOffset, beforeBlock.Statements, newNestedBlock.Statements); } } else if (nb.EndOffset <= endOffset) { newNestedBlock.Statements.Add(nb); } else if (nb.StartOffset < endOffset) { Contract.Assert(nb.EndOffset > endOffset); //nb starts inside newNestedBlock but ends after it. Contract.Assume(!nb.IsLexicalScope); //lexical scopes are assumed to nest cleanly. Contract.Assume(afterBlock != null); this.SplitBlock(nb, endOffset, newNestedBlock.Statements, afterBlock.Statements); } else { Contract.Assume(afterBlock != null); afterBlock.Statements.Add(nb); } } //consolidate blocks consisting of a single block Consolidate(beforeBlock); Consolidate(newNestedBlock); Consolidate(afterBlock); } return(newNestedBlock); }
private DecompiledBlock CreateNestedBlock(DecompiledBlock block, uint startOffset, uint endOffset) { Contract.Requires(block != null); Contract.Requires(startOffset <= endOffset); Contract.Ensures(Contract.Result<DecompiledBlock>() != null); { nextBlock: foreach (var statement in block.Statements) { var nestedBlock = statement as DecompiledBlock; if (nestedBlock == null) continue; if (nestedBlock.StartOffset <= startOffset && nestedBlock.EndOffset >= endOffset) { block = nestedBlock; goto nextBlock; } } } if (block.StartOffset == startOffset && block.EndOffset == endOffset) return block; //replace block.Statements with three nested blocks, the middle one corresponding to one we have to create //but keep any declarations. int n = block.Statements.Count; var oldStatements = block.Statements; var newStatements = block.Statements; int m = 0; if (n >= 0) { while (m < n && oldStatements[m] is LocalDeclarationStatement) m++; if (m < n) { newStatements = new List<IStatement>(m+3); for (int i = 0; i < m; i++) newStatements.Add(oldStatements[i]); } } block.Statements = newStatements; var basicBlocks = block.GetBasicBlocksForRange(startOffset, endOffset); var newNestedBlock = new DecompiledBlock(startOffset, endOffset, basicBlocks, isLexicalScope: true); DecompiledBlock beforeBlock = null; if (block.StartOffset < startOffset) { var basicBlocksBefore = block.GetBasicBlocksForRange(block.StartOffset, startOffset); Contract.Assume(block.StartOffset < startOffset); beforeBlock = new DecompiledBlock(block.StartOffset, startOffset, basicBlocksBefore, isLexicalScope: false); newStatements.Add(beforeBlock); } newStatements.Add(newNestedBlock); DecompiledBlock afterBlock = null; if (block.EndOffset > endOffset) { var basicBlocksAfter = block.GetBasicBlocksForRange(endOffset, block.EndOffset); Contract.Assume(block.EndOffset > endOffset); afterBlock = new DecompiledBlock(endOffset, block.EndOffset, basicBlocksAfter, isLexicalScope: false); newStatements.Add(afterBlock); } if (newStatements != oldStatements) { //In this case there were already some nested blocks, which happens when there are nested exception blocks //and we are creating an enclosing lexical block that does not quite coincide with block. //We now have to populate the newly created blocks with these nested blocks, splitting them if necessary. for (int i = m; i < n; i++) { var nb = oldStatements[i] as DecompiledBlock; Contract.Assume(nb != null); if (nb.EndOffset <= startOffset) { Contract.Assume(beforeBlock != null); beforeBlock.Statements.Add(nb); } else if (nb.StartOffset < startOffset) { Contract.Assume(nb.EndOffset <= endOffset); //nb starts before newNestedBlock but ends inside it. Contract.Assume(beforeBlock != null); if (nb.IsLexicalScope) { //Lexical scopes are assumed to nest cleanly. But the C# is not playing along when one using statement immediately follows another //Well fix matters by making nb.EndOffset == startOffset nb.EndOffset = startOffset; beforeBlock.Statements.Add(nb); } else this.SplitBlock(nb, startOffset, beforeBlock.Statements, newNestedBlock.Statements); } else if (nb.EndOffset <= endOffset) { newNestedBlock.Statements.Add(nb); } else if (nb.StartOffset < endOffset) { Contract.Assert(nb.EndOffset > endOffset); //nb starts inside newNestedBlock but ends after it. Contract.Assume(!nb.IsLexicalScope); //lexical scopes are assumed to nest cleanly. Contract.Assume(afterBlock != null); this.SplitBlock(nb, endOffset, newNestedBlock.Statements, afterBlock.Statements); } else { Contract.Assume(afterBlock != null); afterBlock.Statements.Add(nb); } } //consolidate blocks consisting of a single block Consolidate(beforeBlock); Consolidate(newNestedBlock); Consolidate(afterBlock); } return newNestedBlock; }