OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 library trydart.poi.diff; | |
6 | |
7 import 'package:compiler/src/elements/elements.dart' show | |
8 AbstractFieldElement, | |
9 ClassElement, | |
10 CompilationUnitElement, | |
11 Element, | |
12 ElementCategory, | |
13 FunctionElement, | |
14 LibraryElement, | |
15 ScopeContainerElement; | |
16 | |
17 import 'package:compiler/src/elements/modelx.dart' as modelx; | |
18 | |
19 import 'package:compiler/src/elements/modelx.dart' show | |
20 DeclarationSite; | |
21 | |
22 import 'package:compiler/src/parser/partial_elements.dart' show | |
23 PartialClassElement, | |
24 PartialElement; | |
25 | |
26 import 'package:compiler/src/tokens/token.dart' show | |
27 ErrorToken, | |
28 Token; | |
29 | |
30 import 'package:compiler/src/tokens/token_constants.dart' show | |
31 EOF_TOKEN, | |
32 IDENTIFIER_TOKEN, | |
33 KEYWORD_TOKEN; | |
34 | |
35 class Difference { | |
36 final DeclarationSite before; | |
37 final DeclarationSite after; | |
38 | |
39 /// Records the position of first difference between [before] and [after]. If | |
40 /// either [before] or [after] are null, [token] is null. | |
41 Token token; | |
42 | |
43 Difference(this.before, this.after) { | |
44 if (before == after) { | |
45 throw '[before] and [after] are the same.'; | |
46 } | |
47 } | |
48 | |
49 String toString() { | |
50 if (before == null) return 'Added($after)'; | |
51 if (after == null) return 'Removed($before)'; | |
52 return 'Modified($after -> $before)'; | |
53 } | |
54 } | |
55 | |
56 List<Difference> computeDifference( | |
57 ScopeContainerElement before, | |
58 ScopeContainerElement after) { | |
59 Map<String, DeclarationSite> beforeMap = <String, DeclarationSite>{}; | |
60 before.forEachLocalMember((modelx.ElementX element) { | |
61 DeclarationSite site = element.declarationSite; | |
62 assert(site != null || element.isSynthesized); | |
63 if (!element.isSynthesized) { | |
64 beforeMap[element.name] = site; | |
65 } | |
66 }); | |
67 List<Difference> modifications = <Difference>[]; | |
68 List<Difference> potentiallyChanged = <Difference>[]; | |
69 after.forEachLocalMember((modelx.ElementX element) { | |
70 DeclarationSite existing = beforeMap.remove(element.name); | |
71 if (existing == null) { | |
72 modifications.add(new Difference(null, element.declarationSite)); | |
73 } else { | |
74 potentiallyChanged.add(new Difference(existing, element.declarationSite)); | |
75 } | |
76 }); | |
77 | |
78 modifications.addAll( | |
79 beforeMap.values.map( | |
80 (DeclarationSite site) => new Difference(site, null))); | |
81 | |
82 modifications.addAll( | |
83 potentiallyChanged.where(areDifferentElements)); | |
84 | |
85 return modifications; | |
86 } | |
87 | |
88 bool areDifferentElements(Difference diff) { | |
89 DeclarationSite before = diff.before; | |
90 DeclarationSite after = diff.after; | |
91 if (before is PartialElement && after is PartialElement) { | |
92 Token beforeToken = before.beginToken; | |
93 Token afterToken = after.beginToken; | |
94 Token stop = before.endToken; | |
95 int beforeKind = beforeToken.kind; | |
96 int afterKind = afterToken.kind; | |
97 while (beforeKind != EOF_TOKEN && afterKind != EOF_TOKEN) { | |
98 | |
99 if (beforeKind != afterKind) { | |
100 diff.token = afterToken; | |
101 return true; | |
102 } | |
103 | |
104 if (beforeToken is! ErrorToken && afterToken is! ErrorToken) { | |
105 if (beforeToken.value != afterToken.value) { | |
106 diff.token = afterToken; | |
107 return true; | |
108 } | |
109 } | |
110 | |
111 if (beforeToken == stop) return false; | |
112 | |
113 beforeToken = beforeToken.next; | |
114 afterToken = afterToken.next; | |
115 beforeKind = beforeToken.kind; | |
116 afterKind = afterToken.kind; | |
117 } | |
118 return beforeKind != afterKind; | |
119 } | |
120 print("$before isn't a PartialElement"); | |
121 return true; | |
122 } | |
OLD | NEW |