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

Unified 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, 6 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 side-by-side diff with in-line comments
Download patch
Index: dart/lib/compiler/implementation/resolver.dart
diff --git a/dart/lib/compiler/implementation/resolver.dart b/dart/lib/compiler/implementation/resolver.dart
index f2432c35b0c9ac53b81d9607f5c45f46e25ede72..284387ffcc078d670f8a98e353c2c67fb0dd3c89 100644
--- a/dart/lib/compiler/implementation/resolver.dart
+++ b/dart/lib/compiler/implementation/resolver.dart
@@ -222,16 +222,109 @@ class ResolverTask extends CompilerTask {
}
void resolveClass(ClassElement element) {
- if (element.isResolved) return;
+ if (element.isResolved || element.isBeingResolved) return;
+ element.isBeingResolved = true;
measure(() {
ClassNode tree = element.parseNode(compiler);
ClassResolverVisitor visitor =
new ClassResolverVisitor(compiler, element.getLibrary(), element);
visitor.visit(tree);
+ element.isBeingResolved = false;
element.isResolved = true;
+
+ while (!toResolve.isEmpty()) {
+ ClassElement classElement = toResolve.removeFirst();
+ classElement.ensureResolved(compiler);
+ }
+
+ checkMembers(element);
});
}
+ checkMembers(ClassElement cls) {
+ if (cls === compiler.objectClass) return;
+ cls.forEachMember((holder, member) {
+ checkAbstractField(member);
+ checkValidOverride(member, cls.lookupSuperMember(member.name));
+ });
+ }
+
+ void checkAbstractField(Element member) {
+ if (member is !AbstractFieldElement) return;
+ if (member.getter === null) return;
+ if (member.setter === null) return;
+ int getterFlags = member.getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
+ int setterFlags = member.setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
+ if (getterFlags !== setterFlags) {
+ final mismatchedFlags =
+ new Modifiers.withFlags(null, getterFlags ^ setterFlags);
+ compiler.reportMessage(
+ compiler.spanFromElement(member.getter),
+ MessageKind.GETTER_MISMATCH.error([mismatchedFlags]),
+ api.Diagnostic.ERROR);
+ compiler.reportMessage(
+ compiler.spanFromElement(member.setter),
+ MessageKind.SETTER_MISMATCH.error([mismatchedFlags]),
+ api.Diagnostic.ERROR);
+ }
+ }
+
+ reportErrorWithContext(Element errorneousElement,
+ MessageKind errorMessage,
+ Element contextElement,
+ MessageKind contextMessage) {
+ compiler.reportMessage(
+ compiler.spanFromElement(errorneousElement),
+ errorMessage.error([contextElement.name,
+ contextElement.getEnclosingClass().name]),
+ api.Diagnostic.ERROR);
+ compiler.reportMessage(
+ compiler.spanFromElement(contextElement),
+ contextMessage.error(),
+ api.Diagnostic.INFO);
+ }
+
+
+ void checkValidOverride(Element member, Element superMember) {
+ if (superMember === null) return;
+ if (member.modifiers.isStatic()) {
+ reportErrorWithContext(
+ member, MessageKind.NO_STATIC_OVERRIDE,
+ superMember, MessageKind.NO_STATIC_OVERRIDE_CONT);
+ } else {
+ FunctionElement superFunction = superMember.asFunctionElement();
+ FunctionElement function = member.asFunctionElement();
+ if (superFunction === null || superFunction.isAccessor()) {
+ // Field or accessor in super.
+ if (function !== null && !function.isAccessor()) {
+ // But a plain method in this class.
+ reportErrorWithContext(
+ member, MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
+ superMember, MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT);
+ }
+ } else {
+ // Instance method in super.
+ if (function === null || function.isAccessor()) {
+ // But a field (or accessor) in this class.
+ reportErrorWithContext(
+ member, MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
+ superMember, MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT);
+ } else {
+ // Both are plain instance methods.
+ if (superFunction.requiredParameterCount(compiler) !=
+ function.requiredParameterCount(compiler)) {
+ reportErrorWithContext(
+ member,
+ MessageKind.BAD_ARITY_OVERRIDE,
+ superMember,
+ MessageKind.BAD_ARITY_OVERRIDE_CONT);
+ }
+ // TODO(ahe): Check optional parameters.
+ }
+ }
+ }
+ }
+
FunctionSignature resolveSignature(FunctionElement element) {
return compiler.withCurrentElement(element, () {
FunctionExpression node =
« 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