GetBasicBlocksForRange() приватный Метод

private GetBasicBlocksForRange ( uint startOffset, uint endOffset ) : Sublist>
startOffset uint
endOffset uint
Результат Sublist>
Пример #1
0
        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);
        }
Пример #2
0
    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);
    }
Пример #3
0
        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);
        }
Пример #4
0
    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;
    }