| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:analysis_server/plugin/protocol/protocol.dart'; | 7 import 'package:analysis_server/plugin/protocol/protocol.dart' |
| 8 hide AnalysisErrorFixes; |
| 9 import 'package:analyzer_plugin/protocol/generated_protocol.dart' as plugin; |
| 8 import 'package:meta/meta.dart'; | 10 import 'package:meta/meta.dart'; |
| 9 | 11 |
| 10 /** | 12 /** |
| 11 * An object used to merge partial lists of results that were contributed by | 13 * An object used to merge partial lists of results that were contributed by |
| 12 * plugins. | 14 * plugins. |
| 13 * | 15 * |
| 14 * All of the methods in this class assume that the contributions from the | 16 * All of the methods in this class assume that the contributions from the |
| 15 * analysis server are the first partial result in the list of partial results | 17 * analysis server are the first partial result in the list of partial results |
| 16 * to be merged. | 18 * to be merged. |
| 17 */ | 19 */ |
| 18 class ResultMerger { | 20 class ResultMerger { |
| 19 /** | 21 /** |
| 20 * Return a list of fixes composed by merging the lists of fixes in the | 22 * Return a list of fixes composed by merging the lists of fixes in the |
| 21 * [partialResultList]. | 23 * [partialResultList]. |
| 22 * | 24 * |
| 23 * The resulting list of fixes will contain exactly one fix for every analysis | 25 * The resulting list of fixes will contain exactly one fix for every analysis |
| 24 * error for which there are fixes. If two or more plugins contribute the same | 26 * error for which there are fixes. If two or more plugins contribute the same |
| 25 * fix for a given error, the resulting list will contain duplications. | 27 * fix for a given error, the resulting list will contain duplications. |
| 26 */ | 28 */ |
| 27 List<AnalysisErrorFixes> mergeAnalysisErrorFixes( | 29 List<plugin.AnalysisErrorFixes> mergeAnalysisErrorFixes( |
| 28 List<List<AnalysisErrorFixes>> partialResultList) { | 30 List<List<plugin.AnalysisErrorFixes>> partialResultList) { |
| 29 /** | 31 /** |
| 30 * Return a key encoding the unique attributes of the given [error]. | 32 * Return a key encoding the unique attributes of the given [error]. |
| 31 */ | 33 */ |
| 32 String computeKey(AnalysisError error) { | 34 String computeKey(plugin.AnalysisError error) { |
| 33 StringBuffer buffer = new StringBuffer(); | 35 StringBuffer buffer = new StringBuffer(); |
| 34 buffer.write(error.location.offset); | 36 buffer.write(error.location.offset); |
| 35 buffer.write(';'); | 37 buffer.write(';'); |
| 36 buffer.write(error.code); | 38 buffer.write(error.code); |
| 37 buffer.write(';'); | 39 buffer.write(';'); |
| 38 buffer.write(error.message); | 40 buffer.write(error.message); |
| 39 buffer.write(';'); | 41 buffer.write(';'); |
| 40 buffer.write(error.correction); | 42 buffer.write(error.correction); |
| 41 return buffer.toString(); | 43 return buffer.toString(); |
| 42 } | 44 } |
| 43 | 45 |
| 44 int count = partialResultList.length; | 46 int count = partialResultList.length; |
| 45 if (count == 0) { | 47 if (count == 0) { |
| 46 return <AnalysisErrorFixes>[]; | 48 return <plugin.AnalysisErrorFixes>[]; |
| 47 } else if (count == 1) { | 49 } else if (count == 1) { |
| 48 return partialResultList[0]; | 50 return partialResultList[0]; |
| 49 } | 51 } |
| 50 List<AnalysisErrorFixes> mergedFixes = partialResultList[0].toList(); | 52 Map<String, plugin.AnalysisErrorFixes> fixesMap = |
| 51 Map<String, AnalysisErrorFixes> fixesMap = <String, AnalysisErrorFixes>{}; | 53 <String, plugin.AnalysisErrorFixes>{}; |
| 52 for (AnalysisErrorFixes fix in mergedFixes) { | 54 for (plugin.AnalysisErrorFixes fix in partialResultList[0]) { |
| 53 fixesMap[computeKey(fix.error)] = fix; | 55 fixesMap[computeKey(fix.error)] = fix; |
| 54 } | 56 } |
| 55 for (int i = 1; i < count; i++) { | 57 for (int i = 1; i < count; i++) { |
| 56 for (AnalysisErrorFixes fix in partialResultList[i]) { | 58 for (plugin.AnalysisErrorFixes fix in partialResultList[i]) { |
| 57 String key = computeKey(fix.error); | 59 String key = computeKey(fix.error); |
| 58 AnalysisErrorFixes mergedFix = fixesMap[key]; | 60 plugin.AnalysisErrorFixes mergedFix = fixesMap[key]; |
| 59 if (mergedFix == null) { | 61 if (mergedFix == null) { |
| 60 mergedFixes.add(fix); | |
| 61 fixesMap[key] = fix; | 62 fixesMap[key] = fix; |
| 62 } else { | 63 } else { |
| 63 // If more than two plugins contribute fixes for the same error, this | 64 // If more than two plugins contribute fixes for the same error, this |
| 64 // will result in extra copy operations. | 65 // will result in extra copy operations. |
| 65 List<SourceChange> mergedChanges = mergedFix.fixes.toList(); | 66 List<plugin.PrioritizedSourceChange> mergedChanges = |
| 67 mergedFix.fixes.toList(); |
| 66 mergedChanges.addAll(fix.fixes); | 68 mergedChanges.addAll(fix.fixes); |
| 67 AnalysisErrorFixes copiedFix = | 69 plugin.AnalysisErrorFixes copiedFix = new plugin.AnalysisErrorFixes( |
| 68 new AnalysisErrorFixes(mergedFix.error, fixes: mergedChanges); | 70 mergedFix.error, |
| 69 mergedFixes[mergedFixes.indexOf(mergedFix)] = copiedFix; | 71 fixes: mergedChanges); |
| 70 fixesMap[key] = copiedFix; | 72 fixesMap[key] = copiedFix; |
| 71 } | 73 } |
| 72 } | 74 } |
| 73 } | 75 } |
| 76 List<plugin.AnalysisErrorFixes> mergedFixes = fixesMap.values.toList(); |
| 77 for (plugin.AnalysisErrorFixes fixes in mergedFixes) { |
| 78 fixes.fixes.sort((first, second) => first.priority - second.priority); |
| 79 } |
| 74 return mergedFixes; | 80 return mergedFixes; |
| 75 } | 81 } |
| 76 | 82 |
| 77 /** | 83 /** |
| 78 * Return a list of errors composed by merging the lists of errors in the | 84 * Return a list of errors composed by merging the lists of errors in the |
| 79 * [partialResultList]. | 85 * [partialResultList]. |
| 80 * | 86 * |
| 81 * The resulting list will contain all of the analysis errors from all of the | 87 * The resulting list will contain all of the analysis errors from all of the |
| 82 * plugins. If two or more plugins contribute the same error the resulting | 88 * plugins. If two or more plugins contribute the same error the resulting |
| 83 * list will contain duplications. | 89 * list will contain duplications. |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 } | 757 } |
| 752 | 758 |
| 753 /** | 759 /** |
| 754 * Return a list of source changes composed by merging the lists of source | 760 * Return a list of source changes composed by merging the lists of source |
| 755 * changes in the [partialResultList]. | 761 * changes in the [partialResultList]. |
| 756 * | 762 * |
| 757 * The resulting list will contain all of the source changes from all of the | 763 * The resulting list will contain all of the source changes from all of the |
| 758 * plugins. If two or more plugins contribute the same source change the | 764 * plugins. If two or more plugins contribute the same source change the |
| 759 * resulting list will contain duplications. | 765 * resulting list will contain duplications. |
| 760 */ | 766 */ |
| 767 List<plugin.PrioritizedSourceChange> mergePrioritizedSourceChanges( |
| 768 List<List<plugin.PrioritizedSourceChange>> partialResultList) { |
| 769 int count = partialResultList.length; |
| 770 if (count == 0) { |
| 771 return <plugin.PrioritizedSourceChange>[]; |
| 772 } else if (count == 1) { |
| 773 return partialResultList[0]; |
| 774 } |
| 775 List<plugin.PrioritizedSourceChange> mergedChanges = <plugin.PrioritizedSour
ceChange>[]; |
| 776 for (List<plugin.PrioritizedSourceChange> partialResults in partialResultLis
t) { |
| 777 mergedChanges.addAll(partialResults); |
| 778 } |
| 779 mergedChanges.sort((first, second) => first.priority - second.priority); |
| 780 return mergedChanges; |
| 781 } |
| 782 |
| 783 /** |
| 784 * Return a list of source changes composed by merging the lists of source |
| 785 * changes in the [partialResultList]. |
| 786 * |
| 787 * The resulting list will contain all of the source changes from all of the |
| 788 * plugins. If two or more plugins contribute the same source change the |
| 789 * resulting list will contain duplications. |
| 790 */ |
| 761 List<SourceChange> mergeSourceChanges( | 791 List<SourceChange> mergeSourceChanges( |
| 762 List<List<SourceChange>> partialResultList) { | 792 List<List<SourceChange>> partialResultList) { |
| 763 int count = partialResultList.length; | 793 int count = partialResultList.length; |
| 764 if (count == 0) { | 794 if (count == 0) { |
| 765 return <SourceChange>[]; | 795 return <SourceChange>[]; |
| 766 } else if (count == 1) { | 796 } else if (count == 1) { |
| 767 return partialResultList[0]; | 797 return partialResultList[0]; |
| 768 } | 798 } |
| 769 List<SourceChange> mergedChanges = <SourceChange>[]; | 799 List<SourceChange> mergedChanges = <SourceChange>[]; |
| 770 for (List<SourceChange> partialResults in partialResultList) { | 800 for (List<SourceChange> partialResults in partialResultList) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 786 if (leftEnd < rightStart || leftStart > rightEnd) { | 816 if (leftEnd < rightStart || leftStart > rightEnd) { |
| 787 return false; | 817 return false; |
| 788 } | 818 } |
| 789 if (!allowNesting) { | 819 if (!allowNesting) { |
| 790 return true; | 820 return true; |
| 791 } | 821 } |
| 792 return !((leftStart <= rightStart && rightEnd <= leftEnd) || | 822 return !((leftStart <= rightStart && rightEnd <= leftEnd) || |
| 793 (rightStart <= leftStart && leftEnd <= rightEnd)); | 823 (rightStart <= leftStart && leftEnd <= rightEnd)); |
| 794 } | 824 } |
| 795 } | 825 } |
| OLD | NEW |