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

Side by Side Diff: dart/lib/compiler/implementation/resolver.dart

Issue 10575033: Implement override checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix problem that caused an assertion failure (and revert of the first attempt) Created 8 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 interface TreeElements { 5 interface TreeElements {
6 Element operator[](Node node); 6 Element operator[](Node node);
7 Selector getSelector(Send send); 7 Selector getSelector(Send send);
8 Type getType(TypeAnnotation annotation); 8 Type getType(TypeAnnotation annotation);
9 } 9 }
10 10
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 ResolverVisitor visitor = new ResolverVisitor(compiler, element); 215 ResolverVisitor visitor = new ResolverVisitor(compiler, element);
216 Type result = visitor.resolveTypeAnnotation(annotation); 216 Type result = visitor.resolveTypeAnnotation(annotation);
217 if (result === null) { 217 if (result === null) {
218 // TODO(karklose): warning. 218 // TODO(karklose): warning.
219 return compiler.types.dynamicType; 219 return compiler.types.dynamicType;
220 } 220 }
221 return result; 221 return result;
222 } 222 }
223 223
224 void resolveClass(ClassElement element) { 224 void resolveClass(ClassElement element) {
225 if (element.isResolved) return; 225 if (element.isResolved || element.isBeingResolved) return;
226 element.isBeingResolved = true;
226 measure(() { 227 measure(() {
227 ClassNode tree = element.parseNode(compiler); 228 ClassNode tree = element.parseNode(compiler);
228 ClassResolverVisitor visitor = 229 ClassResolverVisitor visitor =
229 new ClassResolverVisitor(compiler, element.getLibrary(), element); 230 new ClassResolverVisitor(compiler, element.getLibrary(), element);
230 visitor.visit(tree); 231 visitor.visit(tree);
232 element.isBeingResolved = false;
231 element.isResolved = true; 233 element.isResolved = true;
234
235 while (!toResolve.isEmpty()) {
236 ClassElement classElement = toResolve.removeFirst();
237 classElement.ensureResolved(compiler);
238 }
239
240 checkMembers(element);
232 }); 241 });
233 } 242 }
234 243
244 checkMembers(ClassElement cls) {
245 if (cls === compiler.objectClass) return;
246 cls.forEachMember((holder, member) {
247 checkAbstractField(member);
248 checkValidOverride(member, cls.lookupSuperMember(member.name));
249 });
250 }
251
252 void checkAbstractField(Element member) {
253 if (member is !AbstractFieldElement) return;
254 if (member.getter === null) return;
255 if (member.setter === null) return;
256 int getterFlags = member.getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
257 int setterFlags = member.setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
258 if (getterFlags !== setterFlags) {
259 final mismatchedFlags =
260 new Modifiers.withFlags(null, getterFlags ^ setterFlags);
261 compiler.reportMessage(
262 compiler.spanFromElement(member.getter),
263 MessageKind.GETTER_MISMATCH.error([mismatchedFlags]),
264 api.Diagnostic.ERROR);
265 compiler.reportMessage(
266 compiler.spanFromElement(member.setter),
267 MessageKind.SETTER_MISMATCH.error([mismatchedFlags]),
268 api.Diagnostic.ERROR);
269 }
270 }
271
272 reportErrorWithContext(Element errorneousElement,
273 MessageKind errorMessage,
274 Element contextElement,
275 MessageKind contextMessage) {
276 compiler.reportMessage(
277 compiler.spanFromElement(errorneousElement),
278 errorMessage.error([contextElement.name,
279 contextElement.getEnclosingClass().name]),
280 api.Diagnostic.ERROR);
281 compiler.reportMessage(
282 compiler.spanFromElement(contextElement),
283 contextMessage.error(),
284 api.Diagnostic.INFO);
285 }
286
287
288 void checkValidOverride(Element member, Element superMember) {
289 if (superMember === null) return;
290 if (member.modifiers.isStatic()) {
291 reportErrorWithContext(
292 member, MessageKind.NO_STATIC_OVERRIDE,
293 superMember, MessageKind.NO_STATIC_OVERRIDE_CONT);
294 } else {
295 FunctionElement superFunction = superMember.asFunctionElement();
296 FunctionElement function = member.asFunctionElement();
297 if (superFunction === null || superFunction.isAccessor()) {
298 // Field or accessor in super.
299 if (function !== null && !function.isAccessor()) {
300 // But a plain method in this class.
301 reportErrorWithContext(
302 member, MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
303 superMember, MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT);
304 }
305 } else {
306 // Instance method in super.
307 if (function === null || function.isAccessor()) {
308 // But a field (or accessor) in this class.
309 reportErrorWithContext(
310 member, MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
311 superMember, MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT);
312 } else {
313 // Both are plain instance methods.
314 if (superFunction.requiredParameterCount(compiler) !=
315 function.requiredParameterCount(compiler)) {
316 reportErrorWithContext(
317 member,
318 MessageKind.BAD_ARITY_OVERRIDE,
319 superMember,
320 MessageKind.BAD_ARITY_OVERRIDE_CONT);
321 }
322 // TODO(ahe): Check optional parameters.
323 }
324 }
325 }
326 }
327
235 FunctionSignature resolveSignature(FunctionElement element) { 328 FunctionSignature resolveSignature(FunctionElement element) {
236 return compiler.withCurrentElement(element, () { 329 return compiler.withCurrentElement(element, () {
237 FunctionExpression node = 330 FunctionExpression node =
238 compiler.parser.measure(() => element.parseNode(compiler)); 331 compiler.parser.measure(() => element.parseNode(compiler));
239 return measure(() => SignatureResolver.analyze( 332 return measure(() => SignatureResolver.analyze(
240 compiler, node.parameters, node.returnType, element)); 333 compiler, node.parameters, node.returnType, element));
241 }); 334 });
242 } 335 }
243 336
244 FunctionSignature resolveTypedef(TypedefElement element) { 337 FunctionSignature resolveTypedef(TypedefElement element) {
(...skipping 1849 matching lines...) Expand 10 before | Expand all | Expand 10 after
2094 2187
2095 TopScope(LibraryElement library) : super(null, library); 2188 TopScope(LibraryElement library) : super(null, library);
2096 Element lookup(SourceString name) { 2189 Element lookup(SourceString name) {
2097 return library.find(name); 2190 return library.find(name);
2098 } 2191 }
2099 2192
2100 Element add(Element newElement) { 2193 Element add(Element newElement) {
2101 throw "Cannot add an element in the top scope"; 2194 throw "Cannot add an element in the top scope";
2102 } 2195 }
2103 } 2196 }
OLDNEW
« no previous file with comments | « dart/lib/compiler/implementation/elements/elements.dart ('k') | dart/lib/compiler/implementation/tree/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698