| 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_procedure_builder; | 5 library fasta.kernel_procedure_builder; |
| 6 | 6 |
| 7 import 'package:kernel/ast.dart' show | 7 import 'package:kernel/ast.dart' |
| 8 Arguments, | 8 show |
| 9 AsyncMarker, | 9 Arguments, |
| 10 Constructor, | 10 AsyncMarker, |
| 11 ConstructorInvocation, | 11 Constructor, |
| 12 DartType, | 12 ConstructorInvocation, |
| 13 DynamicType, | 13 DartType, |
| 14 EmptyStatement, | 14 DynamicType, |
| 15 Expression, | 15 EmptyStatement, |
| 16 FunctionNode, | 16 Expression, |
| 17 Initializer, | 17 FunctionNode, |
| 18 Library, | 18 Initializer, |
| 19 LocalInitializer, | 19 Library, |
| 20 Member, | 20 LocalInitializer, |
| 21 Name, | 21 Member, |
| 22 NamedExpression, | 22 Name, |
| 23 Procedure, | 23 NamedExpression, |
| 24 ProcedureKind, | 24 Procedure, |
| 25 RedirectingInitializer, | 25 ProcedureKind, |
| 26 Statement, | 26 RedirectingInitializer, |
| 27 StaticInvocation, | 27 Statement, |
| 28 StringLiteral, | 28 StaticInvocation, |
| 29 SuperInitializer, | 29 StringLiteral, |
| 30 TypeParameter, | 30 SuperInitializer, |
| 31 VariableDeclaration, | 31 TypeParameter, |
| 32 VariableGet, | 32 VariableDeclaration, |
| 33 VoidType, | 33 VariableGet, |
| 34 setParents; | 34 VoidType, |
| 35 setParents; |
| 35 | 36 |
| 36 import 'package:kernel/type_algebra.dart' show | 37 import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute; |
| 37 containsTypeVariable, | |
| 38 substitute; | |
| 39 | 38 |
| 40 import '../errors.dart' show | 39 import '../errors.dart' show internalError; |
| 41 internalError; | |
| 42 | 40 |
| 43 import '../messages.dart' show | 41 import '../messages.dart' show warning; |
| 44 warning; | |
| 45 | 42 |
| 46 import '../loader.dart' show | 43 import '../loader.dart' show Loader; |
| 47 Loader; | |
| 48 | 44 |
| 49 import 'kernel_builder.dart' show | 45 import 'kernel_builder.dart' |
| 50 Builder, | 46 show |
| 51 ClassBuilder, | 47 Builder, |
| 52 ConstructorReferenceBuilder, | 48 ClassBuilder, |
| 53 FormalParameterBuilder, | 49 ConstructorReferenceBuilder, |
| 54 KernelFormalParameterBuilder, | 50 FormalParameterBuilder, |
| 55 KernelLibraryBuilder, | 51 KernelFormalParameterBuilder, |
| 56 KernelTypeBuilder, | 52 KernelLibraryBuilder, |
| 57 KernelTypeVariableBuilder, | 53 KernelTypeBuilder, |
| 58 MetadataBuilder, | 54 KernelTypeVariableBuilder, |
| 59 ProcedureBuilder, | 55 MetadataBuilder, |
| 60 TypeVariableBuilder, | 56 ProcedureBuilder, |
| 61 memberError; | 57 TypeVariableBuilder, |
| 58 memberError; |
| 62 | 59 |
| 63 abstract class KernelFunctionBuilder | 60 abstract class KernelFunctionBuilder |
| 64 extends ProcedureBuilder<KernelTypeBuilder> { | 61 extends ProcedureBuilder<KernelTypeBuilder> { |
| 65 final String nativeMethodName; | 62 final String nativeMethodName; |
| 66 | 63 |
| 67 FunctionNode function; | 64 FunctionNode function; |
| 68 | 65 |
| 69 Statement actualBody; | 66 Statement actualBody; |
| 70 | 67 |
| 71 KernelFunctionBuilder(List<MetadataBuilder> metadata, int modifiers, | 68 KernelFunctionBuilder( |
| 72 KernelTypeBuilder returnType, String name, | 69 List<MetadataBuilder> metadata, |
| 70 int modifiers, |
| 71 KernelTypeBuilder returnType, |
| 72 String name, |
| 73 List<TypeVariableBuilder> typeVariables, | 73 List<TypeVariableBuilder> typeVariables, |
| 74 List<FormalParameterBuilder> formals, | 74 List<FormalParameterBuilder> formals, |
| 75 KernelLibraryBuilder compilationUnit, int charOffset, | 75 KernelLibraryBuilder compilationUnit, |
| 76 int charOffset, |
| 76 this.nativeMethodName) | 77 this.nativeMethodName) |
| 77 : super(metadata, modifiers, returnType, name, typeVariables, formals, | 78 : super(metadata, modifiers, returnType, name, typeVariables, formals, |
| 78 compilationUnit, charOffset); | 79 compilationUnit, charOffset); |
| 79 | 80 |
| 80 void set body(Statement newBody) { | 81 void set body(Statement newBody) { |
| 81 if (isAbstract && newBody != null) { | 82 if (isAbstract && newBody != null) { |
| 82 return internalError("Attempting to set body on abstract method."); | 83 return internalError("Attempting to set body on abstract method."); |
| 83 } | 84 } |
| 84 actualBody = newBody; | 85 actualBody = newBody; |
| 85 if (function != null) { | 86 if (function != null) { |
| 86 function.body = newBody; | 87 function.body = newBody; |
| 87 newBody?.parent = function; | 88 newBody?.parent = function; |
| 88 } | 89 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 if (substitution == null) { | 127 if (substitution == null) { |
| 127 substitution = <TypeParameter, DartType>{}; | 128 substitution = <TypeParameter, DartType>{}; |
| 128 for (TypeParameter parameter in typeParameters) { | 129 for (TypeParameter parameter in typeParameters) { |
| 129 substitution[parameter] = const DynamicType(); | 130 substitution[parameter] = const DynamicType(); |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 warning(fileUri, charOffset, | 133 warning(fileUri, charOffset, |
| 133 "Can only use type variables in instance methods."); | 134 "Can only use type variables in instance methods."); |
| 134 return substitute(type, substitution); | 135 return substitute(type, substitution); |
| 135 } | 136 } |
| 137 |
| 136 Set<TypeParameter> set = typeParameters.toSet(); | 138 Set<TypeParameter> set = typeParameters.toSet(); |
| 137 for (VariableDeclaration parameter in result.positionalParameters) { | 139 for (VariableDeclaration parameter in result.positionalParameters) { |
| 138 if (containsTypeVariable(parameter.type, set)) { | 140 if (containsTypeVariable(parameter.type, set)) { |
| 139 parameter.type = removeTypeVariables(parameter.type); | 141 parameter.type = removeTypeVariables(parameter.type); |
| 140 } | 142 } |
| 141 } | 143 } |
| 142 for (VariableDeclaration parameter in result.namedParameters) { | 144 for (VariableDeclaration parameter in result.namedParameters) { |
| 143 if (containsTypeVariable(parameter.type, set)) { | 145 if (containsTypeVariable(parameter.type, set)) { |
| 144 parameter.type = removeTypeVariables(parameter.type); | 146 parameter.type = removeTypeVariables(parameter.type); |
| 145 } | 147 } |
| 146 } | 148 } |
| 147 if (containsTypeVariable(result.returnType, set)) { | 149 if (containsTypeVariable(result.returnType, set)) { |
| 148 result.returnType = removeTypeVariables(result.returnType); | 150 result.returnType = removeTypeVariables(result.returnType); |
| 149 } | 151 } |
| 150 } | 152 } |
| 151 } | 153 } |
| 152 return function = result; | 154 return function = result; |
| 153 } | 155 } |
| 154 | 156 |
| 155 Member build(Library library); | 157 Member build(Library library); |
| 156 | 158 |
| 157 void becomeNative(Loader loader) { | 159 void becomeNative(Loader loader) { |
| 158 target.isExternal = true; | 160 target.isExternal = true; |
| 159 Builder constructor = loader.getNativeAnnotation(); | 161 Builder constructor = loader.getNativeAnnotation(); |
| 160 Arguments arguments = | 162 Arguments arguments = |
| 161 new Arguments(<Expression>[new StringLiteral(nativeMethodName)]); | 163 new Arguments(<Expression>[new StringLiteral(nativeMethodName)]); |
| 162 Expression annotation; | 164 Expression annotation; |
| 163 if (constructor.isConstructor) { | 165 if (constructor.isConstructor) { |
| 164 annotation = new ConstructorInvocation(constructor.target, arguments) | 166 annotation = new ConstructorInvocation(constructor.target, arguments) |
| 165 ..isConst = true; | 167 ..isConst = true; |
| 166 } else { | 168 } else { |
| 167 annotation = new StaticInvocation(constructor.target, arguments) | 169 annotation = new StaticInvocation(constructor.target, arguments) |
| 168 ..isConst = true; | 170 ..isConst = true; |
| 169 } | 171 } |
| 170 target.addAnnotation(annotation); | 172 target.addAnnotation(annotation); |
| 171 } | 173 } |
| 172 } | 174 } |
| 173 | 175 |
| 174 class KernelProcedureBuilder extends KernelFunctionBuilder { | 176 class KernelProcedureBuilder extends KernelFunctionBuilder { |
| 175 final Procedure procedure; | 177 final Procedure procedure; |
| 176 | 178 |
| 177 AsyncMarker actualAsyncModifier; | 179 AsyncMarker actualAsyncModifier; |
| 178 | 180 |
| 179 final ConstructorReferenceBuilder redirectionTarget; | 181 final ConstructorReferenceBuilder redirectionTarget; |
| 180 | 182 |
| 181 KernelProcedureBuilder( | 183 KernelProcedureBuilder( |
| 182 List<MetadataBuilder> metadata, | 184 List<MetadataBuilder> metadata, |
| 183 int modifiers, KernelTypeBuilder returnType, String name, | 185 int modifiers, |
| 186 KernelTypeBuilder returnType, |
| 187 String name, |
| 184 List<TypeVariableBuilder> typeVariables, | 188 List<TypeVariableBuilder> typeVariables, |
| 185 List<FormalParameterBuilder> formals, this.actualAsyncModifier, | 189 List<FormalParameterBuilder> formals, |
| 186 ProcedureKind kind, KernelLibraryBuilder compilationUnit, int charOffset, | 190 this.actualAsyncModifier, |
| 187 [String nativeMethodName, this.redirectionTarget]) | 191 ProcedureKind kind, |
| 192 KernelLibraryBuilder compilationUnit, |
| 193 int charOffset, |
| 194 [String nativeMethodName, |
| 195 this.redirectionTarget]) |
| 188 : procedure = new Procedure(null, kind, null, | 196 : procedure = new Procedure(null, kind, null, |
| 189 fileUri: compilationUnit?.relativeFileUri), | 197 fileUri: compilationUnit?.relativeFileUri), |
| 190 super(metadata, modifiers, returnType, name, typeVariables, formals, | 198 super(metadata, modifiers, returnType, name, typeVariables, formals, |
| 191 compilationUnit, charOffset, nativeMethodName); | 199 compilationUnit, charOffset, nativeMethodName); |
| 192 | 200 |
| 193 ProcedureKind get kind => procedure.kind; | 201 ProcedureKind get kind => procedure.kind; |
| 194 | 202 |
| 195 AsyncMarker get asyncModifier => actualAsyncModifier; | 203 AsyncMarker get asyncModifier => actualAsyncModifier; |
| 196 | 204 |
| 197 Statement get body { | 205 Statement get body { |
| 198 if (actualBody == null && redirectionTarget == null && !isAbstract && | 206 if (actualBody == null && |
| 207 redirectionTarget == null && |
| 208 !isAbstract && |
| 199 !isExternal) { | 209 !isExternal) { |
| 200 actualBody = new EmptyStatement(); | 210 actualBody = new EmptyStatement(); |
| 201 } | 211 } |
| 202 return actualBody; | 212 return actualBody; |
| 203 } | 213 } |
| 204 | 214 |
| 205 void set asyncModifier(AsyncMarker newModifier) { | 215 void set asyncModifier(AsyncMarker newModifier) { |
| 206 actualAsyncModifier = newModifier; | 216 actualAsyncModifier = newModifier; |
| 207 if (function != null) { | 217 if (function != null) { |
| 208 // No parent, it's an enum. | 218 // No parent, it's an enum. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 232 final Constructor constructor = new Constructor(null); | 242 final Constructor constructor = new Constructor(null); |
| 233 | 243 |
| 234 bool hasMovedSuperInitializer = false; | 244 bool hasMovedSuperInitializer = false; |
| 235 | 245 |
| 236 SuperInitializer superInitializer; | 246 SuperInitializer superInitializer; |
| 237 | 247 |
| 238 RedirectingInitializer redirectingInitializer; | 248 RedirectingInitializer redirectingInitializer; |
| 239 | 249 |
| 240 KernelConstructorBuilder( | 250 KernelConstructorBuilder( |
| 241 List<MetadataBuilder> metadata, | 251 List<MetadataBuilder> metadata, |
| 242 int modifiers, KernelTypeBuilder returnType, String name, | 252 int modifiers, |
| 253 KernelTypeBuilder returnType, |
| 254 String name, |
| 243 List<TypeVariableBuilder> typeVariables, | 255 List<TypeVariableBuilder> typeVariables, |
| 244 List<FormalParameterBuilder> formals, | 256 List<FormalParameterBuilder> formals, |
| 245 KernelLibraryBuilder compilationUnit, int charOffset, | 257 KernelLibraryBuilder compilationUnit, |
| 258 int charOffset, |
| 246 [String nativeMethodName]) | 259 [String nativeMethodName]) |
| 247 : super(metadata, modifiers, returnType, name, typeVariables, formals, | 260 : super(metadata, modifiers, returnType, name, typeVariables, formals, |
| 248 compilationUnit, charOffset, nativeMethodName); | 261 compilationUnit, charOffset, nativeMethodName); |
| 249 | 262 |
| 250 bool get isInstanceMember => false; | 263 bool get isInstanceMember => false; |
| 251 | 264 |
| 252 bool get isConstructor => true; | 265 bool get isConstructor => true; |
| 253 | 266 |
| 254 AsyncMarker get asyncModifier => AsyncMarker.Sync; | 267 AsyncMarker get asyncModifier => AsyncMarker.Sync; |
| 255 | 268 |
| 256 ProcedureKind get kind => null; | 269 ProcedureKind get kind => null; |
| 257 | 270 |
| 258 Constructor build(Library library) { | 271 Constructor build(Library library) { |
| 259 if (constructor.name == null) { | 272 if (constructor.name == null) { |
| 260 constructor.function = buildFunction(); | 273 constructor.function = buildFunction(); |
| 261 constructor.function.parent = constructor; | 274 constructor.function.parent = constructor; |
| 262 constructor.isConst = isConst; | 275 constructor.isConst = isConst; |
| 263 constructor.isExternal = isExternal; | 276 constructor.isExternal = isExternal; |
| 264 constructor.name = new Name(name, library); | 277 constructor.name = new Name(name, library); |
| 265 } | 278 } |
| 266 return constructor; | 279 return constructor; |
| 267 } | 280 } |
| 268 | 281 |
| 269 FunctionNode buildFunction() { | 282 FunctionNode buildFunction() { |
| 270 // TODO(ahe): Should complain if another type is explicitly set. | 283 // TODO(ahe): Should complain if another type is explicitly set. |
| 271 return super.buildFunction() | 284 return super.buildFunction()..returnType = const VoidType(); |
| 272 ..returnType = const VoidType(); | |
| 273 } | 285 } |
| 274 | 286 |
| 275 Constructor get target => constructor; | 287 Constructor get target => constructor; |
| 276 | 288 |
| 277 void checkSuperOrThisInitializer(Initializer initializer) { | 289 void checkSuperOrThisInitializer(Initializer initializer) { |
| 278 if (superInitializer != null || redirectingInitializer != null) { | 290 if (superInitializer != null || redirectingInitializer != null) { |
| 279 memberError(target, | 291 memberError( |
| 292 target, |
| 280 "Can't have more than one 'super' or 'this' initializer.", | 293 "Can't have more than one 'super' or 'this' initializer.", |
| 281 initializer.fileOffset); | 294 initializer.fileOffset); |
| 282 } | 295 } |
| 283 } | 296 } |
| 284 | 297 |
| 285 void addInitializer(Initializer initializer) { | 298 void addInitializer(Initializer initializer) { |
| 286 List<Initializer> initializers = constructor.initializers; | 299 List<Initializer> initializers = constructor.initializers; |
| 287 if (initializer is SuperInitializer) { | 300 if (initializer is SuperInitializer) { |
| 288 checkSuperOrThisInitializer(initializer); | 301 checkSuperOrThisInitializer(initializer); |
| 289 superInitializer = initializer; | 302 superInitializer = initializer; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 308 // To preserve correct evaluation order, the arguments to super call | 321 // To preserve correct evaluation order, the arguments to super call |
| 309 // must be evaluated before [initializer]. Once the super initializer | 322 // must be evaluated before [initializer]. Once the super initializer |
| 310 // has been moved once, the arguments are evaluated in the correct | 323 // has been moved once, the arguments are evaluated in the correct |
| 311 // order. | 324 // order. |
| 312 hasMovedSuperInitializer = true; | 325 hasMovedSuperInitializer = true; |
| 313 Arguments arguments = superInitializer.arguments; | 326 Arguments arguments = superInitializer.arguments; |
| 314 List<Expression> positional = arguments.positional; | 327 List<Expression> positional = arguments.positional; |
| 315 for (int i = 0; i < positional.length; i++) { | 328 for (int i = 0; i < positional.length; i++) { |
| 316 VariableDeclaration variable = | 329 VariableDeclaration variable = |
| 317 new VariableDeclaration.forValue(positional[i], isFinal: true); | 330 new VariableDeclaration.forValue(positional[i], isFinal: true); |
| 318 initializers.add( | 331 initializers |
| 319 new LocalInitializer(variable)..parent = constructor); | 332 .add(new LocalInitializer(variable)..parent = constructor); |
| 320 positional[i] = new VariableGet(variable)..parent = arguments; | 333 positional[i] = new VariableGet(variable)..parent = arguments; |
| 321 } | 334 } |
| 322 for (NamedExpression named in arguments.named) { | 335 for (NamedExpression named in arguments.named) { |
| 323 VariableDeclaration variable = | 336 VariableDeclaration variable = |
| 324 new VariableDeclaration.forValue(named.value, isFinal: true); | 337 new VariableDeclaration.forValue(named.value, isFinal: true); |
| 325 named.value = new VariableGet(variable)..parent = named; | 338 named.value = new VariableGet(variable)..parent = named; |
| 326 initializers.add( | 339 initializers |
| 327 new LocalInitializer(variable)..parent = constructor); | 340 .add(new LocalInitializer(variable)..parent = constructor); |
| 328 } | 341 } |
| 329 } | 342 } |
| 330 initializers.add(initializer..parent = constructor); | 343 initializers.add(initializer..parent = constructor); |
| 331 initializers.add(superInitializer); | 344 initializers.add(superInitializer); |
| 332 return; | 345 return; |
| 333 } | 346 } |
| 334 initializers.add(initializer); | 347 initializers.add(initializer); |
| 335 initializer.parent = constructor; | 348 initializer.parent = constructor; |
| 336 } | 349 } |
| 337 } | 350 } |
| OLD | NEW |