Chromium Code Reviews| Index: pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart |
| diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart |
| index 347b08488602aa4c7a6d0b70cbe950d7d90611d9..4c2fd9ba86f19cb619460435b6fae6ac72d7fea9 100644 |
| --- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart |
| +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart |
| @@ -7,23 +7,32 @@ library fasta.kernel_class_builder; |
| import 'package:kernel/ast.dart' |
| show |
| Class, |
| + Constructor, |
| DartType, |
| Expression, |
| ExpressionStatement, |
| Field, |
| + FunctionNode, |
| InterfaceType, |
| ListLiteral, |
| Member, |
| Name, |
| + Procedure, |
| + ProcedureKind, |
| StaticGet, |
| StringLiteral, |
| Supertype, |
| - Throw; |
| + Throw, |
| + VariableDeclaration; |
| -import '../errors.dart' show internalError; |
| +import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; |
| + |
| +import '../errors.dart' show internalError, printUnexpected; |
| import '../messages.dart' show warning; |
| +import '../dill/dill_member_builder.dart' show DillMemberBuilder; |
| + |
| import 'kernel_builder.dart' |
| show |
| Builder, |
| @@ -38,8 +47,6 @@ import 'kernel_builder.dart' |
| TypeVariableBuilder, |
| computeDefaultTypeArguments; |
| -import '../dill/dill_member_builder.dart' show DillMemberBuilder; |
| - |
| import 'redirecting_factory_body.dart' show RedirectingFactoryBody; |
| abstract class KernelClassBuilder |
| @@ -166,4 +173,98 @@ abstract class KernelClassBuilder |
| literal.expressions |
| .add(new StaticGet(constructor.target)..parent = literal); |
| } |
| + |
| + void checkOverrides(ClassHierarchy hierarchy) { |
| + hierarchy.forEachOverridePair(cls, checkOverride); |
| + } |
| + |
| + void checkOverride( |
| + Member declaredMember, Member interfaceMember, bool isSetter) { |
| + if (declaredMember is Constructor || interfaceMember is Constructor) { |
| + internalError( |
| + "Constructor in override check.", fileUri, declaredMember.fileOffset); |
| + } |
| + if (declaredMember is Procedure && interfaceMember is Procedure) { |
| + if (declaredMember.kind == ProcedureKind.Method && |
| + interfaceMember.kind == ProcedureKind.Method) { |
| + checkMethodOverride(declaredMember, interfaceMember); |
| + return; |
| + } |
| + } |
| + } |
| + |
| + void checkMethodOverride( |
| + Procedure declaredMember, Procedure interfaceMember) { |
| + assert(declaredMember.kind == ProcedureKind.Method); |
| + assert(interfaceMember.kind == ProcedureKind.Method); |
| + FunctionNode declaredFunction = declaredMember.function; |
| + FunctionNode interfaceFunction = interfaceMember.function; |
|
ahe
2017/03/16 17:32:37
These two function nodes have lists of parameters
|
| + if (declaredFunction.typeParameters?.length != |
| + interfaceFunction.typeParameters?.length) { |
| + // TODO(ahe): This causes a lot of errors in typed_data.dart. |
| + // printUnexpected( |
| + // fileUri, |
| + // declaredMember.fileOffset, |
| + // "Declared type variables of '$name::${declaredMember.name.name}' " |
| + // "doesn't match those on overridden method " |
| + // "'${interfaceMember.enclosingClass.name}::" |
| + // "${interfaceMember.name.name}'."); |
| + } |
| + if (declaredFunction.positionalParameters.length < |
| + interfaceFunction.requiredParameterCount || |
| + declaredFunction.positionalParameters.length < |
| + interfaceFunction.positionalParameters.length) { |
| + printUnexpected( |
| + fileUri, |
| + declaredMember.fileOffset, |
| + "The method '$name::${declaredMember.name.name}' has fewer " |
| + "positional arguments than those of overridden method " |
| + "'${interfaceMember.enclosingClass.name}::" |
| + "${interfaceMember.name.name}'."); |
| + } |
| + if (interfaceFunction.requiredParameterCount < declaredFunction.requiredParameterCount) { |
| + printUnexpected( |
| + fileUri, |
| + declaredMember.fileOffset, |
| + "The method '$name::${declaredMember.name.name}' has fewer " |
| + "positional arguments than those of overridden method " |
| + "'${interfaceMember.enclosingClass.name}::" |
| + "${interfaceMember.name.name}'."); |
| + } |
| + if (declaredFunction.namedParameters.isEmpty && |
| + interfaceFunction.namedParameters.isEmpty) { |
| + return; |
| + } |
| + if (declaredFunction.namedParameters.length < |
| + interfaceFunction.namedParameters.length) { |
| + printUnexpected( |
| + fileUri, |
| + declaredMember.fileOffset, |
| + "The method '$name::${declaredMember.name.name}' has fewer named " |
| + "arguments than those of overridden method " |
| + "'${interfaceMember.enclosingClass.name}::" |
| + "${interfaceMember.name.name}'."); |
| + } |
| + Iterator<VariableDeclaration> declaredNamedParameters = |
| + declaredFunction.namedParameters.iterator; |
| + Iterator<VariableDeclaration> interfaceNamedParameters = |
| + interfaceFunction.namedParameters.iterator; |
| + outer: |
| + while (declaredNamedParameters.moveNext() && |
| + interfaceNamedParameters.moveNext()) { |
| + while (declaredNamedParameters.current.name != |
| + interfaceNamedParameters.current.name) { |
| + if (!declaredNamedParameters.moveNext()) { |
| + printUnexpected( |
| + fileUri, |
| + declaredMember.fileOffset, |
| + "The method '$name::${declaredMember.name.name}' doesn't have " |
| + "the named parameter '${interfaceNamedParameters.current.name}' " |
| + "of override method '${interfaceMember.enclosingClass.name}::" |
| + "${interfaceMember.name.name}'."); |
| + break outer; |
| + } |
| + } |
| + } |
| + } |
| } |