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