Browse Source

CodeCoverage: Use new OpenCover attributes

Now is simpler/cleaner to find start/final SP
Remove obsolete methods & code
pull/343/head
Dragan 12 years ago
parent
commit
041a8d4676
  1. 146
      src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodElement.cs

146
src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodElement.cs

@ -98,23 +98,22 @@ namespace ICSharpCode.CodeCoverage @@ -98,23 +98,22 @@ namespace ICSharpCode.CodeCoverage
if ( !String.IsNullOrEmpty( this.FileID ) ) {
this.GetSequencePoints();
this.GetSequencePointsContent();
this.getBodyStartSP(); // before OrderBy Line/Col
this.getBodyFinalSP(); // before orderBy Line/Col
//this.FilterSequencePoints(); // before orderBy Line/Col
this.getBodyStartSP();
this.getBodyFinalSP();
this.GetBranchRatio();
this.GetBranchCoverage();
// SP's are originaly ordered by CIL offset
// but ccrewrite can move offset of
// Contract.Requires before method signature SP { and
// Contract.Ensures after method closing SP }
// because ccrewrite can move offset of
// Contract.Requires before method start ({) SP offset
// Contract.Ensures after method final (}) SP offset
// So sort SP's back by line/column
this.SequencePoints.OrderBy(item => item.Line).OrderBy(item => item.Column);
}
}
private static var cacheGetSource_LastFileName = (string)null;
private static var cacheGetSource_LastSource = (CodeCoverageStringTextSource)null;
private static string cacheGetSource_LastFileName = null;
private static CodeCoverageStringTextSource cacheGetSource_LastSource = null;
static CodeCoverageStringTextSource GetSource(string filename) {
@ -159,12 +158,12 @@ namespace ICSharpCode.CodeCoverage @@ -159,12 +158,12 @@ namespace ICSharpCode.CodeCoverage
sp.Document = xSPoint.Attribute("fileid").Value?? "";
}
else if (sp.FileID == this.FileID) {
// This method SequencePoint (from this.FileName)
// This method SequencePoint (from this.FileName)
sp.Document = this.FileName;
}
else {
// SequencePoint from another method/file
// ie: ccrewriten CodeContractClass/CodeContractClassFor
// ie: ccrewriten CodeContractClass/CodeContractClassFor
// [or dependency-injected or fody-weaved???]
sp.Document = parent.GetFileName(sp.FileID);
}
@ -210,91 +209,49 @@ namespace ICSharpCode.CodeCoverage @@ -210,91 +209,49 @@ namespace ICSharpCode.CodeCoverage
}
}
// Find method-body start SequencePoint "{" (sp.Content required)
// Sequence points expected to be ordered by Offset
// Cannot just get first one because of ccrewrite&ContractClassFor
// Find method-body first SequencePoint
// -> this method SP with lowest Line/Column
void getBodyStartSP() {
bool startPointFound = false;
CodeCoverageSequencePoint startSeqPoint = null;
foreach (CodeCoverageSequencePoint sp in this.SequencePoints) {
if ( sp.Content == "{") {
if ( this.IsConstructor ) {
// take previous/last one if not null
startSeqPoint = startSeqPoint?? sp;
}
else {
startSeqPoint = sp;
if (this.SequencePoints.Count != 0) {
foreach (CodeCoverageSequencePoint sp in this.SequencePoints) {
if (sp.FileID != this.FileID) continue;
if (this.BodyStartSP == null || (sp.Line < this.BodyStartSP.Line) ||
(sp.Line == this.BodyStartSP.Line && sp.Column < this.BodyStartSP.Column)
) {
this.BodyStartSP = sp;
}
startPointFound = true;
break;
}
startSeqPoint = sp;
}
this.BodyStartSP = startPointFound? startSeqPoint: null;
}
// Find method-body final SequencePoint "}" (sp.Content required)
// Sequence points expected to be ordered by Offset
// Find method-body last SequencePoint
// -> this method SP.Content=="}" with highest Line/Column
// and lowest Offset (when duplicated bw ccrewrite)
void getBodyFinalSP() {
CodeCoverageSequencePoint finalSeqPoint = null;
foreach (CodeCoverageSequencePoint sp in ((IEnumerable<CodeCoverageSequencePoint>)this.SequencePoints).Reverse()) {
if ( sp.Content == "}") {
if (finalSeqPoint == null) {
finalSeqPoint = sp;
}
// check for ccrewrite duplicate
else if (sp.Line == finalSeqPoint.Line &&
sp.Column == finalSeqPoint.Column &&
sp.EndLine == finalSeqPoint.EndLine &&
sp.EndColumn == finalSeqPoint.EndColumn &&
sp.Offset < finalSeqPoint.Offset) {
finalSeqPoint = sp;
// duplicate found, so far no reason to expect "triplicate" :)
break;
}
}
}
this.BodyFinalSP = finalSeqPoint;
}
void FilterSequencePoints() {
if (this.SequencePoints.Count != 0 &&
this.BodyStartSP != null &&
this.BodyFinalSP != null ) {
// After ccrewrite ContractClass/ContractClassFor
// sequence point(s) from another file/class/method
// is inserted into this method sequence points
//
// To remove alien sequence points, all sequence points on lines
// before method signature and after end-brackets xxx{} are removed
// If ContractClassFor is in another file but interleaves this method lines
// then, afaik, not much can be done to remove inserted alien SP's
var selected = new List<CodeCoverageSequencePoint>();
foreach (var point in this.SequencePoints) {
// if Content.Length is 0, GetText() is failed by ccrewrite inserted invalid SequencePoint
if (point.Content.Length != 0
&& (point.Line > BodyStartSP.Line || (point.Line == BodyStartSP.Line && point.Column >= BodyStartSP.Column))
&& (point.Line < BodyFinalSP.Line || (point.Line == BodyFinalSP.Line && point.Column < BodyFinalSP.Column))
) {
selected.Add (point);
}
// After ccrewrite ContractClass/ContractClassFor
// duplicate method end-sequence-point "}" is added
//
// Add only first finalSP (can be a duplicate)
// Note: IL.Offset of second duplicate finalSP will
// extend branch coverage outside method-end "}",
// and that can lead to wrong branch coverage display!
if (object.ReferenceEquals (point, this.BodyFinalSP)) {
selected.Add (point);
if (this.SequencePoints.Count != 0) {
for (int i = this.SequencePoints.Count-1; i > 0; i--) {
var sp = this.SequencePoints[i];
if (sp.FileID != this.FileID) continue;
if (sp.Content != "}") continue;
if (this.BodyFinalSP == null || (sp.Line > this.BodyFinalSP.Line) ||
(sp.Line == this.BodyFinalSP.Line && sp.Column >= this.BodyFinalSP.Column)
) {
// ccrewrite ContractClass/ContractClassFor
// adds duplicate method end-sequence-point "}"
//
// Take duplicate BodyFinalSP with lower Offset
// Because IL.Offset of second duplicate
// will extend branch coverage of this method
// by coverage of ContractClassFor inserted SequencePoint!
if (this.BodyFinalSP != null &&
sp.Line == this.BodyFinalSP.Line &&
sp.Column == this.BodyFinalSP.Column &&
sp.Offset < this.BodyFinalSP.Offset) {
this.SequencePoints.Remove(this.BodyFinalSP); // remove duplicate
}
this.BodyFinalSP = sp;
}
}
this.SequencePoints = selected;
}
}
@ -309,21 +266,6 @@ namespace ICSharpCode.CodeCoverage @@ -309,21 +266,6 @@ namespace ICSharpCode.CodeCoverage
return 0;
}
void GetBranchPoints() {
// get all BranchPoints
var xBPoints = this.element
.Elements("BranchPoints")
.Elements("BranchPoint");
foreach (XElement xBPoint in xBPoints) {
CodeCoverageBranchPoint bp = new CodeCoverageBranchPoint();
bp.VisitCount = (int)GetDecimalAttributeValue(xBPoint.Attribute("vc"));
bp.Offset = (int)GetDecimalAttributeValue(xBPoint.Attribute("offset"));
bp.Path = (int)GetDecimalAttributeValue(xBPoint.Attribute("path"));
bp.OffsetEnd = (int)GetDecimalAttributeValue(xBPoint.Attribute("offsetend"));
this.BranchPoints.Add(bp);
}
}
void GetBranchRatio () {
this.BranchCoverageRatio = null;
@ -344,7 +286,7 @@ namespace ICSharpCode.CodeCoverage @@ -344,7 +286,7 @@ namespace ICSharpCode.CodeCoverage
foreach (var sp in this.SequencePoints) {
// SequencePoint is visited and belongs to this method?
if (sp.VisitCount != 0 && sp.Document == this.FileName) {
if (sp.VisitCount != 0 && sp.FileID == this.FileID) {
// Don't want branch coverage of ccrewrite(n)
// SequencePoint's with offset before and after method body

Loading…
Cancel
Save