| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library fasta.kernel_class_builder; | 5 library fasta.kernel_class_builder; |
| 6 | 6 |
| 7 import 'package:kernel/ast.dart' | 7 import 'package:kernel/ast.dart' |
| 8 show | 8 show |
| 9 Class, | 9 Class, |
| 10 Constructor, |
| 10 DartType, | 11 DartType, |
| 11 Expression, | 12 Expression, |
| 12 ExpressionStatement, | 13 ExpressionStatement, |
| 13 Field, | 14 Field, |
| 15 FunctionNode, |
| 14 InterfaceType, | 16 InterfaceType, |
| 15 ListLiteral, | 17 ListLiteral, |
| 16 Member, | 18 Member, |
| 17 Name, | 19 Name, |
| 20 Procedure, |
| 21 ProcedureKind, |
| 18 StaticGet, | 22 StaticGet, |
| 19 StringLiteral, | 23 StringLiteral, |
| 20 Supertype, | 24 Supertype, |
| 21 Throw; | 25 Throw, |
| 26 VariableDeclaration; |
| 27 |
| 28 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; |
| 22 | 29 |
| 23 import '../errors.dart' show internalError; | 30 import '../errors.dart' show internalError; |
| 24 | 31 |
| 25 import '../messages.dart' show warning; | 32 import '../messages.dart' show warning; |
| 26 | 33 |
| 34 import '../dill/dill_member_builder.dart' show DillMemberBuilder; |
| 35 |
| 27 import 'kernel_builder.dart' | 36 import 'kernel_builder.dart' |
| 28 show | 37 show |
| 29 Builder, | 38 Builder, |
| 30 ClassBuilder, | 39 ClassBuilder, |
| 31 ConstructorReferenceBuilder, | 40 ConstructorReferenceBuilder, |
| 32 KernelLibraryBuilder, | 41 KernelLibraryBuilder, |
| 33 KernelProcedureBuilder, | 42 KernelProcedureBuilder, |
| 34 KernelTypeBuilder, | 43 KernelTypeBuilder, |
| 35 LibraryBuilder, | 44 LibraryBuilder, |
| 36 MetadataBuilder, | 45 MetadataBuilder, |
| 37 ProcedureBuilder, | 46 ProcedureBuilder, |
| 38 TypeVariableBuilder, | 47 TypeVariableBuilder, |
| 39 computeDefaultTypeArguments; | 48 computeDefaultTypeArguments; |
| 40 | 49 |
| 41 import '../dill/dill_member_builder.dart' show DillMemberBuilder; | |
| 42 | |
| 43 import 'redirecting_factory_body.dart' show RedirectingFactoryBody; | 50 import 'redirecting_factory_body.dart' show RedirectingFactoryBody; |
| 44 | 51 |
| 45 abstract class KernelClassBuilder | 52 abstract class KernelClassBuilder |
| 46 extends ClassBuilder<KernelTypeBuilder, InterfaceType> { | 53 extends ClassBuilder<KernelTypeBuilder, InterfaceType> { |
| 47 KernelClassBuilder( | 54 KernelClassBuilder( |
| 48 List<MetadataBuilder> metadata, | 55 List<MetadataBuilder> metadata, |
| 49 int modifiers, | 56 int modifiers, |
| 50 String name, | 57 String name, |
| 51 List<TypeVariableBuilder> typeVariables, | 58 List<TypeVariableBuilder> typeVariables, |
| 52 KernelTypeBuilder supertype, | 59 KernelTypeBuilder supertype, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 initializer: literal, | 166 initializer: literal, |
| 160 fileUri: cls.fileUri)..fileOffset = cls.fileOffset; | 167 fileUri: cls.fileUri)..fileOffset = cls.fileOffset; |
| 161 cls.addMember(field); | 168 cls.addMember(field); |
| 162 return new DillMemberBuilder(field, this); | 169 return new DillMemberBuilder(field, this); |
| 163 }); | 170 }); |
| 164 Field field = constructorsField.target; | 171 Field field = constructorsField.target; |
| 165 ListLiteral literal = field.initializer; | 172 ListLiteral literal = field.initializer; |
| 166 literal.expressions | 173 literal.expressions |
| 167 .add(new StaticGet(constructor.target)..parent = literal); | 174 .add(new StaticGet(constructor.target)..parent = literal); |
| 168 } | 175 } |
| 176 |
| 177 void checkOverrides(ClassHierarchy hierarchy) { |
| 178 hierarchy.forEachOverridePair(cls, checkOverride); |
| 179 } |
| 180 |
| 181 void checkOverride( |
| 182 Member declaredMember, Member interfaceMember, bool isSetter) { |
| 183 if (declaredMember is Constructor || interfaceMember is Constructor) { |
| 184 internalError( |
| 185 "Constructor in override check.", fileUri, declaredMember.fileOffset); |
| 186 } |
| 187 if (declaredMember is Procedure && interfaceMember is Procedure) { |
| 188 if (declaredMember.kind == ProcedureKind.Method && |
| 189 interfaceMember.kind == ProcedureKind.Method) { |
| 190 checkMethodOverride(declaredMember, interfaceMember); |
| 191 return; |
| 192 } |
| 193 } |
| 194 // TODO(ahe): Handle other cases: accessors, operators, and fields. |
| 195 } |
| 196 |
| 197 void checkMethodOverride( |
| 198 Procedure declaredMember, Procedure interfaceMember) { |
| 199 if (declaredMember.enclosingClass != cls) { |
| 200 // TODO(ahe): Include these checks as well, but the message needs to |
| 201 // explain that [declaredMember] is inherited. |
| 202 return; |
| 203 } |
| 204 assert(declaredMember.kind == ProcedureKind.Method); |
| 205 assert(interfaceMember.kind == ProcedureKind.Method); |
| 206 FunctionNode declaredFunction = declaredMember.function; |
| 207 FunctionNode interfaceFunction = interfaceMember.function; |
| 208 if (declaredFunction.typeParameters?.length != |
| 209 interfaceFunction.typeParameters?.length) { |
| 210 addWarning( |
| 211 declaredMember.fileOffset, |
| 212 "Declared type variables of '$name::${declaredMember.name.name}' " |
| 213 "doesn't match those on overridden method " |
| 214 "'${interfaceMember.enclosingClass.name}::" |
| 215 "${interfaceMember.name.name}'."); |
| 216 } |
| 217 if (declaredFunction.positionalParameters.length < |
| 218 interfaceFunction.requiredParameterCount || |
| 219 declaredFunction.positionalParameters.length < |
| 220 interfaceFunction.positionalParameters.length) { |
| 221 addWarning( |
| 222 declaredMember.fileOffset, |
| 223 "The method '$name::${declaredMember.name.name}' has fewer " |
| 224 "positional arguments than those of overridden method " |
| 225 "'${interfaceMember.enclosingClass.name}::" |
| 226 "${interfaceMember.name.name}'."); |
| 227 } |
| 228 if (interfaceFunction.requiredParameterCount < |
| 229 declaredFunction.requiredParameterCount) { |
| 230 addWarning( |
| 231 declaredMember.fileOffset, |
| 232 "The method '$name::${declaredMember.name.name}' has more " |
| 233 "positional arguments than those of overridden method " |
| 234 "'${interfaceMember.enclosingClass.name}::" |
| 235 "${interfaceMember.name.name}'."); |
| 236 } |
| 237 if (declaredFunction.namedParameters.isEmpty && |
| 238 interfaceFunction.namedParameters.isEmpty) { |
| 239 return; |
| 240 } |
| 241 if (declaredFunction.namedParameters.length < |
| 242 interfaceFunction.namedParameters.length) { |
| 243 addWarning( |
| 244 declaredMember.fileOffset, |
| 245 "The method '$name::${declaredMember.name.name}' has fewer named " |
| 246 "arguments than those of overridden method " |
| 247 "'${interfaceMember.enclosingClass.name}::" |
| 248 "${interfaceMember.name.name}'."); |
| 249 } |
| 250 Iterator<VariableDeclaration> declaredNamedParameters = |
| 251 declaredFunction.namedParameters.iterator; |
| 252 Iterator<VariableDeclaration> interfaceNamedParameters = |
| 253 interfaceFunction.namedParameters.iterator; |
| 254 outer: |
| 255 while (declaredNamedParameters.moveNext() && |
| 256 interfaceNamedParameters.moveNext()) { |
| 257 while (declaredNamedParameters.current.name != |
| 258 interfaceNamedParameters.current.name) { |
| 259 if (!declaredNamedParameters.moveNext()) { |
| 260 addWarning( |
| 261 declaredMember.fileOffset, |
| 262 "The method '$name::${declaredMember.name.name}' doesn't have " |
| 263 "the named parameter '${interfaceNamedParameters.current.name}' " |
| 264 "of overriden method '${interfaceMember.enclosingClass.name}::" |
| 265 "${interfaceMember.name.name}'."); |
| 266 break outer; |
| 267 } |
| 268 } |
| 269 } |
| 270 } |
| 271 |
| 272 void addCompileTimeError(int charOffset, String message) { |
| 273 library.addCompileTimeError(charOffset, message, fileUri: fileUri); |
| 274 } |
| 275 |
| 276 void addWarning(int charOffset, String message) { |
| 277 library.addWarning(charOffset, message, fileUri: fileUri); |
| 278 } |
| 279 |
| 280 void addNit(int charOffset, String message) { |
| 281 library.addNit(charOffset, message, fileUri: fileUri); |
| 282 } |
| 169 } | 283 } |
| OLD | NEW |