Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: pkg/compiler/lib/src/js_backend/no_such_method_registry.dart

Issue 2857943002: Implement KernelNoSuchMethodResolver. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 '../common.dart'; 5 import '../common.dart';
6 import '../common_elements.dart' show CommonElements; 6 import '../common_elements.dart' show CommonElements;
7 import '../common/names.dart' show Identifiers, Names, Selectors; 7 import '../common/names.dart' show Identifiers, Names, Selectors;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../elements/entities.dart'; 9 import '../elements/entities.dart';
10 import '../types/types.dart'; 10 import '../types/types.dart';
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 /// The implementations that fall into category D1 63 /// The implementations that fall into category D1
64 final Set<FunctionEntity> complexNoReturnImpls = new Set<FunctionEntity>(); 64 final Set<FunctionEntity> complexNoReturnImpls = new Set<FunctionEntity>();
65 65
66 /// The implementations that fall into category D2 66 /// The implementations that fall into category D2
67 final Set<FunctionEntity> complexReturningImpls = new Set<FunctionEntity>(); 67 final Set<FunctionEntity> complexReturningImpls = new Set<FunctionEntity>();
68 68
69 /// The implementations that have not yet been categorized. 69 /// The implementations that have not yet been categorized.
70 final Set<FunctionEntity> _uncategorizedImpls = new Set<FunctionEntity>(); 70 final Set<FunctionEntity> _uncategorizedImpls = new Set<FunctionEntity>();
71 71
72 final CommonElements _commonElements; 72 final CommonElements _commonElements;
73 final NoSuchMethodResolver _resolver; 73 final NoSuchMethodResolver resolver;
74 74
75 NoSuchMethodRegistry(this._commonElements, this._resolver); 75 NoSuchMethodRegistry(this._commonElements, this.resolver);
76 76
77 bool get hasThrowingNoSuchMethod => throwingImpls.isNotEmpty; 77 bool get hasThrowingNoSuchMethod => throwingImpls.isNotEmpty;
78 bool get hasComplexNoSuchMethod => otherImpls.isNotEmpty; 78 bool get hasComplexNoSuchMethod => otherImpls.isNotEmpty;
79 79
80 void registerNoSuchMethod(FunctionEntity noSuchMethodElement) { 80 void registerNoSuchMethod(FunctionEntity noSuchMethodElement) {
81 _uncategorizedImpls.add(noSuchMethodElement); 81 _uncategorizedImpls.add(noSuchMethodElement);
82 } 82 }
83 83
84 void onQueueEmpty() { 84 void onQueueEmpty() {
85 _uncategorizedImpls.forEach(_categorizeImpl); 85 _uncategorizedImpls.forEach(_categorizeImpl);
(...skipping 11 matching lines...) Expand all
97 complexNoReturnImpls.add(element); 97 complexNoReturnImpls.add(element);
98 } else { 98 } else {
99 complexReturningImpls.add(element); 99 complexReturningImpls.add(element);
100 } 100 }
101 }); 101 });
102 } 102 }
103 103
104 /// Emits a diagnostic 104 /// Emits a diagnostic
105 void emitDiagnostic(DiagnosticReporter reporter) { 105 void emitDiagnostic(DiagnosticReporter reporter) {
106 throwingImpls.forEach((e) { 106 throwingImpls.forEach((e) {
107 if (!_resolver.hasForwardingSyntax(e)) { 107 if (!resolver.hasForwardingSyntax(e)) {
108 reporter.reportHintMessage(e, MessageKind.DIRECTLY_THROWING_NSM); 108 reporter.reportHintMessage(e, MessageKind.DIRECTLY_THROWING_NSM);
109 } 109 }
110 }); 110 });
111 complexNoReturnImpls.forEach((e) { 111 complexNoReturnImpls.forEach((e) {
112 if (!_resolver.hasForwardingSyntax(e)) { 112 if (!resolver.hasForwardingSyntax(e)) {
113 reporter.reportHintMessage(e, MessageKind.COMPLEX_THROWING_NSM); 113 reporter.reportHintMessage(e, MessageKind.COMPLEX_THROWING_NSM);
114 } 114 }
115 }); 115 });
116 complexReturningImpls.forEach((e) { 116 complexReturningImpls.forEach((e) {
117 if (!_resolver.hasForwardingSyntax(e)) { 117 if (!resolver.hasForwardingSyntax(e)) {
118 reporter.reportHintMessage(e, MessageKind.COMPLEX_RETURNING_NSM); 118 reporter.reportHintMessage(e, MessageKind.COMPLEX_RETURNING_NSM);
119 } 119 }
120 }); 120 });
121 } 121 }
122 122
123 /// Returns [true] if the given element is a complex [noSuchMethod] 123 /// Returns [true] if the given element is a complex [noSuchMethod]
124 /// implementation. An implementation is complex if it falls into 124 /// implementation. An implementation is complex if it falls into
125 /// category D, as described above. 125 /// category D, as described above.
126 bool isComplex(FunctionEntity element) { 126 bool isComplex(FunctionEntity element) {
127 assert(element.name == Identifiers.noSuchMethod_); 127 assert(element.name == Identifiers.noSuchMethod_);
(...skipping 14 matching lines...) Expand all
142 if (notApplicableImpls.contains(element)) { 142 if (notApplicableImpls.contains(element)) {
143 return NsmCategory.NOT_APPLICABLE; 143 return NsmCategory.NOT_APPLICABLE;
144 } 144 }
145 if (!Selectors.noSuchMethod_.signatureApplies(element)) { 145 if (!Selectors.noSuchMethod_.signatureApplies(element)) {
146 notApplicableImpls.add(element); 146 notApplicableImpls.add(element);
147 return NsmCategory.NOT_APPLICABLE; 147 return NsmCategory.NOT_APPLICABLE;
148 } 148 }
149 if (_commonElements.isDefaultNoSuchMethodImplementation(element)) { 149 if (_commonElements.isDefaultNoSuchMethodImplementation(element)) {
150 defaultImpls.add(element); 150 defaultImpls.add(element);
151 return NsmCategory.DEFAULT; 151 return NsmCategory.DEFAULT;
152 } else if (_resolver.hasForwardingSyntax(element)) { 152 } else if (resolver.hasForwardingSyntax(element)) {
153 // If the implementation is 'noSuchMethod(x) => super.noSuchMethod(x);' 153 // If the implementation is 'noSuchMethod(x) => super.noSuchMethod(x);'
154 // then it is in the same category as the super call. 154 // then it is in the same category as the super call.
155 FunctionEntity superCall = _resolver.getSuperNoSuchMethod(element); 155 FunctionEntity superCall = resolver.getSuperNoSuchMethod(element);
156 NsmCategory category = _categorizeImpl(superCall); 156 NsmCategory category = _categorizeImpl(superCall);
157 switch (category) { 157 switch (category) {
158 case NsmCategory.DEFAULT: 158 case NsmCategory.DEFAULT:
159 defaultImpls.add(element); 159 defaultImpls.add(element);
160 break; 160 break;
161 case NsmCategory.THROWING: 161 case NsmCategory.THROWING:
162 throwingImpls.add(element); 162 throwingImpls.add(element);
163 break; 163 break;
164 case NsmCategory.OTHER: 164 case NsmCategory.OTHER:
165 otherImpls.add(element); 165 otherImpls.add(element);
166 break; 166 break;
167 case NsmCategory.NOT_APPLICABLE: 167 case NsmCategory.NOT_APPLICABLE:
168 // If the super method is not applicable, the call is redirected to 168 // If the super method is not applicable, the call is redirected to
169 // `Object.noSuchMethod`. 169 // `Object.noSuchMethod`.
170 defaultImpls.add(element); 170 defaultImpls.add(element);
171 category = NsmCategory.DEFAULT; 171 category = NsmCategory.DEFAULT;
172 break; 172 break;
173 } 173 }
174 return category; 174 return category;
175 } else if (_resolver.hasThrowingSyntax(element)) { 175 } else if (resolver.hasThrowingSyntax(element)) {
176 throwingImpls.add(element); 176 throwingImpls.add(element);
177 return NsmCategory.THROWING; 177 return NsmCategory.THROWING;
178 } else { 178 } else {
179 otherImpls.add(element); 179 otherImpls.add(element);
180 return NsmCategory.OTHER; 180 return NsmCategory.OTHER;
181 } 181 }
182 } 182 }
183 } 183 }
184 184
185 enum NsmCategory { 185 enum NsmCategory {
(...skipping 15 matching lines...) Expand all
201 /// 201 ///
202 /// noSuchMethod(i) => throw new Error(); 202 /// noSuchMethod(i) => throw new Error();
203 /// 203 ///
204 bool hasThrowingSyntax(FunctionEntity method); 204 bool hasThrowingSyntax(FunctionEntity method);
205 205
206 /// Returns the `noSuchMethod` that [method] overrides. 206 /// Returns the `noSuchMethod` that [method] overrides.
207 FunctionEntity getSuperNoSuchMethod(FunctionEntity method); 207 FunctionEntity getSuperNoSuchMethod(FunctionEntity method);
208 } 208 }
209 209
210 /// AST-based implementation of [NoSuchMethodResolver]. 210 /// AST-based implementation of [NoSuchMethodResolver].
211 class NoSuchMethodResolverImpl implements NoSuchMethodResolver { 211 class NoSuchMethodResolverImpl implements NoSuchMethodResolver {
Siggi Cherem (dart-lang) 2017/05/03 17:29:49 move under resolution/* ?
Johnni Winther 2017/05/04 09:13:35 Done.
212 bool hasForwardingSyntax(MethodElement element) { 212 bool hasForwardingSyntax(MethodElement element) {
213 // At this point we know that this is signature-compatible with 213 // At this point we know that this is signature-compatible with
214 // Object.noSuchMethod, but it may have more than one argument as long as 214 // Object.noSuchMethod, but it may have more than one argument as long as
215 // it only has one required argument. 215 // it only has one required argument.
216 if (!element.hasResolvedAst) { 216 if (!element.hasResolvedAst) {
217 // TODO(johnniwinther): Why do we see unresolved elements here? 217 // TODO(johnniwinther): Why do we see unresolved elements here?
218 return false; 218 return false;
219 } 219 }
220 ResolvedAst resolvedAst = element.resolvedAst; 220 ResolvedAst resolvedAst = element.resolvedAst;
221 if (resolvedAst.kind != ResolvedAstKind.PARSED) { 221 if (resolvedAst.kind != ResolvedAstKind.PARSED) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 return stmt.expression is Throw; 281 return stmt.expression is Throw;
282 } 282 }
283 } 283 }
284 return false; 284 return false;
285 } 285 }
286 286
287 MethodElement getSuperNoSuchMethod(MethodElement method) { 287 MethodElement getSuperNoSuchMethod(MethodElement method) {
288 return method.enclosingClass.lookupSuperByName(Names.noSuchMethod_); 288 return method.enclosingClass.lookupSuperByName(Names.noSuchMethod_);
289 } 289 }
290 } 290 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/kernel/element_map.dart » ('j') | pkg/compiler/lib/src/kernel/no_such_method_resolver.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698