@@ -1049,55 +1049,92 @@ protected override BreakEventInfo OnInsertBreakEvent (BreakEvent be)
1049
1049
binfo . SetStatus ( BreakEventStatus . Invalid , string . Format ( "Invalid line {0}" , bp . Line ) ) ;
1050
1050
return binfo ;
1051
1051
}
1052
- ISymbolMethod met = null ;
1052
+ ISymbolMethod [ ] methods = null ;
1053
1053
if ( doc . ModuleInfo . Reader is ISymbolReader2 ) {
1054
- var methods = ( ( ISymbolReader2 ) doc . ModuleInfo . Reader ) . GetMethodsFromDocumentPosition ( doc . Document , line , 0 ) ;
1055
- if ( methods != null && methods . Any ( ) ) {
1056
- if ( methods . Count ( ) == 1 ) {
1057
- met = methods [ 0 ] ;
1058
- } else {
1059
- int deepest = - 1 ;
1060
- foreach ( var method in methods ) {
1061
- var firstSequence = method . GetSequencePoints ( ) . FirstOrDefault ( ( sp ) => sp . StartLine != 0xfeefee ) ;
1062
- if ( firstSequence != null && firstSequence . StartLine >= deepest ) {
1063
- deepest = firstSequence . StartLine ;
1064
- met = method ;
1065
- }
1066
- }
1067
- }
1068
- }
1054
+ methods = ( ( ISymbolReader2 ) doc . ModuleInfo . Reader ) . GetMethodsFromDocumentPosition ( doc . Document , line , 0 ) ;
1069
1055
}
1070
- if ( met == null ) {
1071
- met = doc . ModuleInfo . Reader . GetMethodFromDocumentPosition ( doc . Document , line , 0 ) ;
1056
+ if ( methods == null || methods . Length == 0 ) {
1057
+ var met = doc . ModuleInfo . Reader . GetMethodFromDocumentPosition ( doc . Document , line , 0 ) ;
1058
+ if ( met != null )
1059
+ methods = new ISymbolMethod [ ] { met } ;
1072
1060
}
1073
- if ( met == null ) {
1061
+
1062
+ if ( methods == null || methods . Length == 0 ) {
1074
1063
binfo . SetStatus ( BreakEventStatus . Invalid , "Unable to resolve method at position" ) ;
1075
1064
return binfo ;
1076
1065
}
1077
1066
1078
- int offset = - 1 ;
1079
- int firstSpInLine = - 1 ;
1080
- foreach ( SequencePoint sp in met . GetSequencePoints ( ) ) {
1081
- if ( sp . IsInside ( doc . Document . URL , line , bp . Column ) ) {
1082
- offset = sp . Offset ;
1083
- break ;
1084
- } else if ( firstSpInLine == - 1
1085
- && sp . StartLine == line
1086
- && sp . Document . URL . Equals ( doc . Document . URL , StringComparison . OrdinalIgnoreCase ) ) {
1087
- firstSpInLine = sp . Offset ;
1067
+ ISymbolMethod bestMethod = null ;
1068
+ ISymbolMethod bestLeftSideMethod = null ;
1069
+ ISymbolMethod bestRightSideMethod = null ;
1070
+
1071
+ SequencePoint bestSp = null ;
1072
+ SequencePoint bestLeftSideSp = null ;
1073
+ SequencePoint bestRightSideSp = null ;
1074
+
1075
+ foreach ( var met in methods ) {
1076
+ foreach ( SequencePoint sp in met . GetSequencePoints ( ) ) {
1077
+ if ( sp . IsInside ( doc . Document . URL , line , bp . Column ) ) { //breakpoint is inside current sequence point
1078
+ if ( bestSp == null || bestSp . IsInside ( doc . Document . URL , sp . StartLine , sp . StartColumn ) ) { //and sp is inside of current candidate
1079
+ bestSp = sp ;
1080
+ bestMethod = met ;
1081
+ break ;
1082
+ }
1083
+ } else if ( sp . StartLine == line
1084
+ && sp . Document . URL . Equals ( doc . Document . URL , StringComparison . OrdinalIgnoreCase )
1085
+ && sp . StartColumn <= bp . Column ) { //breakpoint is on the same line and on the right side of sp
1086
+ if ( bestLeftSideSp == null
1087
+ || bestLeftSideSp . EndColumn < sp . EndColumn ) {
1088
+ bestLeftSideSp = sp ;
1089
+ bestLeftSideMethod = met ;
1090
+ }
1091
+ } else if ( sp . StartLine >= line
1092
+ && sp . Document . URL . Equals ( doc . Document . URL , StringComparison . OrdinalIgnoreCase ) ) { //sp is after bp
1093
+ if ( bestRightSideSp == null
1094
+ || bestRightSideSp . StartLine > sp . StartLine
1095
+ || ( bestRightSideSp . StartLine == sp . StartLine && bestRightSideSp . StartColumn > sp . StartColumn ) ) { //and current candidate is on the right side of it
1096
+ bestRightSideSp = sp ;
1097
+ bestRightSideMethod = met ;
1098
+ }
1099
+ }
1088
1100
}
1089
1101
}
1090
- if ( offset == - 1 ) { //No exact match? Use first match in that line
1091
- offset = firstSpInLine ;
1102
+
1103
+ SequencePoint bestSameLineSp ;
1104
+ ISymbolMethod bestSameLineMethod ;
1105
+
1106
+ if ( bestRightSideSp != null
1107
+ && ( bestLeftSideSp == null
1108
+ || bestRightSideSp . StartLine > line ) ) {
1109
+ bestSameLineSp = bestRightSideSp ;
1110
+ bestSameLineMethod = bestRightSideMethod ;
1111
+ }
1112
+ else {
1113
+ bestSameLineSp = bestLeftSideSp ;
1114
+ bestSameLineMethod = bestLeftSideMethod ;
1092
1115
}
1093
- if ( offset == - 1 ) {
1116
+
1117
+ if ( bestSameLineSp != null ) {
1118
+ if ( bestSp == null ) {
1119
+ bestSp = bestSameLineSp ;
1120
+ bestMethod = bestSameLineMethod ;
1121
+ }
1122
+ else {
1123
+ if ( bp . Line != bestSp . StartLine || bestSp . StartColumn != bp . Column ) {
1124
+ bestSp = bestSameLineSp ;
1125
+ bestMethod = bestSameLineMethod ;
1126
+ }
1127
+ }
1128
+ }
1129
+
1130
+ if ( bestSp == null || bestMethod == null ) {
1094
1131
binfo . SetStatus ( BreakEventStatus . Invalid , "Unable to calculate an offset in IL code" ) ;
1095
1132
return binfo ;
1096
1133
}
1097
1134
1098
- CorFunction func = doc . ModuleInfo . Module . GetFunctionFromToken ( met . Token . GetToken ( ) ) ;
1135
+ CorFunction func = doc . ModuleInfo . Module . GetFunctionFromToken ( bestMethod . Token . GetToken ( ) ) ;
1099
1136
try {
1100
- CorFunctionBreakpoint corBp = func . ILCode . CreateBreakpoint ( offset ) ;
1137
+ CorFunctionBreakpoint corBp = func . ILCode . CreateBreakpoint ( bestSp . Offset ) ;
1101
1138
breakpoints [ corBp ] = binfo ;
1102
1139
binfo . Handle = corBp ;
1103
1140
corBp . Activate ( bp . Enabled ) ;
0 commit comments