| 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 library kernel.analyzer.loader; | 4 library kernel.analyzer.loader; |
| 5 | 5 |
| 6 import 'dart:async'; | 6 import 'dart:async'; |
| 7 import 'dart:io' as io; | 7 import 'dart:io' as io; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/file_system/file_system.dart'; | 10 import 'package:analyzer/file_system/file_system.dart'; |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 for (int i = 0; i < classNode.typeParameters.length; ++i) { | 267 for (int i = 0; i < classNode.typeParameters.length; ++i) { |
| 268 var parameter = element.typeParameters[i]; | 268 var parameter = element.typeParameters[i]; |
| 269 var parameterNode = classNode.typeParameters[i]; | 269 var parameterNode = classNode.typeParameters[i]; |
| 270 parameterNode.bound = parameter.bound == null | 270 parameterNode.bound = parameter.bound == null |
| 271 ? scope.defaultTypeParameterBound | 271 ? scope.defaultTypeParameterBound |
| 272 : scope.buildType(parameter.bound); | 272 : scope.buildType(parameter.bound); |
| 273 } | 273 } |
| 274 // Initialize supertypes. | 274 // Initialize supertypes. |
| 275 Iterable<InterfaceType> mixins = element.mixins; | 275 Iterable<InterfaceType> mixins = element.mixins; |
| 276 if (element.isMixinApplication && mixins.isNotEmpty) { | 276 if (element.isMixinApplication && mixins.isNotEmpty) { |
| 277 var last = scope.buildType(mixins.last); | 277 classNode.mixedInType = scope.buildSupertype(mixins.last); |
| 278 if (last is ast.InterfaceType) { | |
| 279 classNode.mixedInType = last; | |
| 280 } | |
| 281 mixins = mixins.take(mixins.length - 1); | 278 mixins = mixins.take(mixins.length - 1); |
| 282 } | 279 } |
| 283 if (element.supertype != null) { | 280 if (element.supertype != null) { |
| 284 ast.InterfaceType supertype = scope.buildType(element.supertype); | 281 ast.Supertype supertype = scope.buildSupertype(element.supertype); |
| 285 bool useSharedMixin = true; | 282 bool useSharedMixin = true; |
| 286 for (var mixin in mixins) { | 283 for (var mixin in mixins) { |
| 287 var mixinType = scope.buildType(mixin); | 284 var mixinType = scope.buildSupertype(mixin); |
| 288 if (mixinType is ast.InterfaceType) { | 285 if (useSharedMixin && |
| 289 if (useSharedMixin && | 286 areDistinctUnboundTypeVariables(supertype, mixinType)) { |
| 290 areDistinctUnboundTypeVariables(supertype, mixinType)) { | 287 // Use a shared mixin application class for this library. |
| 291 // Use a shared mixin application class for this library. | 288 var mixinClass = getSharedMixinApplicationClass( |
| 292 var mixinClass = getSharedMixinApplicationClass( | 289 scope.currentLibrary, supertype.classNode, mixinType.classNode); |
| 293 scope.currentLibrary, supertype.classNode, mixinType.classNode); | 290 supertype = new ast.Supertype( |
| 294 supertype = new ast.InterfaceType( | 291 mixinClass, |
| 295 mixinClass, | 292 supertype.typeArguments.length > mixinType.typeArguments.length |
| 296 supertype.typeArguments.length > mixinType.typeArguments.length | 293 ? supertype.typeArguments |
| 297 ? supertype.typeArguments | 294 : mixinType.typeArguments); |
| 298 : mixinType.typeArguments); | 295 } else { |
| 299 } else { | 296 // Generate a new class specific for this mixin application. |
| 300 // Generate a new class specific for this mixin application. | 297 var freshParameters = |
| 301 var freshParameters = | 298 getFreshTypeParameters(classNode.typeParameters); |
| 302 getFreshTypeParameters(classNode.typeParameters); | 299 var mixinClass = new ast.Class( |
| 303 var mixinClass = new ast.Class( | 300 name: '${classNode.name}^${mixinType.classNode.name}', |
| 304 name: '${classNode.name}^${mixinType.classNode.name}', | 301 isAbstract: true, |
| 305 isAbstract: true, | 302 typeParameters: freshParameters.freshTypeParameters, |
| 306 typeParameters: freshParameters.freshTypeParameters, | 303 supertype: freshParameters.substituteSuper(supertype), |
| 307 supertype: freshParameters.substitute(supertype), | 304 mixedInType: freshParameters.substituteSuper(mixinType)); |
| 308 mixedInType: freshParameters.substitute(mixinType)); | 305 mixinClass.level = ast.ClassLevel.Type; |
| 309 mixinClass.level = ast.ClassLevel.Type; | 306 supertype = new ast.Supertype(mixinClass, |
| 310 supertype = new ast.InterfaceType(mixinClass, | 307 classNode.typeParameters.map(makeTypeParameterType).toList()); |
| 311 classNode.typeParameters.map(makeTypeParameterType).toList()); | 308 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); |
| 312 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); | 309 // This class cannot be used from anywhere else, so don't try to |
| 313 // This class cannot be used from anywhere else, so don't try to | 310 // generate shared mixin applications using it. |
| 314 // generate shared mixin applications using it. | 311 useSharedMixin = false; |
| 315 useSharedMixin = false; | |
| 316 } | |
| 317 } | 312 } |
| 318 } | 313 } |
| 319 classNode.supertype = supertype; | 314 classNode.supertype = supertype; |
| 320 for (var implementedType in element.interfaces) { | 315 for (var implementedType in element.interfaces) { |
| 321 classNode.implementedTypes.add(scope.buildType(implementedType)); | 316 classNode.implementedTypes.add(scope.buildSupertype(implementedType)); |
| 322 } | 317 } |
| 323 } | 318 } |
| 324 } | 319 } |
| 325 | 320 |
| 326 void promoteToHierarchyLevel(ast.Class classNode) { | 321 void promoteToHierarchyLevel(ast.Class classNode) { |
| 327 if (classNode.level.index >= ast.ClassLevel.Hierarchy.index) return; | 322 if (classNode.level.index >= ast.ClassLevel.Hierarchy.index) return; |
| 328 promoteToTypeLevel(classNode); | 323 promoteToTypeLevel(classNode); |
| 329 classNode.level = ast.ClassLevel.Hierarchy; | 324 classNode.level = ast.ClassLevel.Hierarchy; |
| 330 var element = getClassElement(classNode); | 325 var element = getClassElement(classNode); |
| 331 if (element != null) { | 326 if (element != null) { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 // ensure unary minus is called 'unary-'. | 483 // ensure unary minus is called 'unary-'. |
| 489 String name = | 484 String name = |
| 490 element is PropertyAccessorElement ? element.displayName : element.name; | 485 element is PropertyAccessorElement ? element.displayName : element.name; |
| 491 return new ast.Name(name, getLibraryReference(element.library)); | 486 return new ast.Name(name, getLibraryReference(element.library)); |
| 492 } | 487 } |
| 493 | 488 |
| 494 /// True if the two types have form `C<T1 ... Tm>` and `D<T1 ... Tn>`, and | 489 /// True if the two types have form `C<T1 ... Tm>` and `D<T1 ... Tn>`, and |
| 495 /// `T1 ... TN` are distinct type variables with no upper bound, where | 490 /// `T1 ... TN` are distinct type variables with no upper bound, where |
| 496 /// `N = max(m,n)`. | 491 /// `N = max(m,n)`. |
| 497 bool areDistinctUnboundTypeVariables( | 492 bool areDistinctUnboundTypeVariables( |
| 498 ast.InterfaceType first, ast.InterfaceType second) { | 493 ast.Supertype first, ast.Supertype second) { |
| 499 var seen = new Set<ast.TypeParameter>(); | 494 var seen = new Set<ast.TypeParameter>(); |
| 500 if (first.typeArguments.length < second.typeArguments.length) { | 495 if (first.typeArguments.length < second.typeArguments.length) { |
| 501 var tmp = first; | 496 var tmp = first; |
| 502 first = second; | 497 first = second; |
| 503 second = tmp; | 498 second = tmp; |
| 504 } | 499 } |
| 505 for (int i = 0; i < first.typeArguments.length; ++i) { | 500 for (int i = 0; i < first.typeArguments.length; ++i) { |
| 506 var firstArg = first.typeArguments[i]; | 501 var firstArg = first.typeArguments[i]; |
| 507 if (!(firstArg is ast.TypeParameterType && | 502 if (!(firstArg is ast.TypeParameterType && |
| 508 seen.add(firstArg.parameter) && | 503 seen.add(firstArg.parameter) && |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 var superArgs = typeArguments.length != superclass.typeParameters.length | 548 var superArgs = typeArguments.length != superclass.typeParameters.length |
| 554 ? typeArguments.sublist(0, superclass.typeParameters.length) | 549 ? typeArguments.sublist(0, superclass.typeParameters.length) |
| 555 : typeArguments; | 550 : typeArguments; |
| 556 var mixinArgs = typeArguments.length != mixedInClass.typeParameters.length | 551 var mixinArgs = typeArguments.length != mixedInClass.typeParameters.length |
| 557 ? typeArguments.sublist(0, mixedInClass.typeParameters.length) | 552 ? typeArguments.sublist(0, mixedInClass.typeParameters.length) |
| 558 : typeArguments; | 553 : typeArguments; |
| 559 var result = new ast.Class( | 554 var result = new ast.Class( |
| 560 name: name, | 555 name: name, |
| 561 isAbstract: true, | 556 isAbstract: true, |
| 562 typeParameters: fresh.freshTypeParameters, | 557 typeParameters: fresh.freshTypeParameters, |
| 563 supertype: new ast.InterfaceType(superclass, superArgs), | 558 supertype: new ast.Supertype(superclass, superArgs), |
| 564 mixedInType: new ast.InterfaceType(mixedInClass, mixinArgs), | 559 mixedInType: new ast.Supertype(mixedInClass, mixinArgs), |
| 565 fileUri: mixedInClass.fileUri); | 560 fileUri: mixedInClass.fileUri); |
| 566 result.level = ast.ClassLevel.Type; | 561 result.level = ast.ClassLevel.Type; |
| 567 library.addClass(result); | 562 library.addClass(result); |
| 568 return result; | 563 return result; |
| 569 }); | 564 }); |
| 570 } | 565 } |
| 571 | 566 |
| 572 String formatErrorMessage( | 567 String formatErrorMessage( |
| 573 AnalysisError error, String filename, LineInfo lines) { | 568 AnalysisError error, String filename, LineInfo lines) { |
| 574 var location = lines.getLocation(error.offset); | 569 var location = lines.getLocation(error.offset); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 811 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() | 806 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() |
| 812 ..sourceFactory = new SourceFactory(resolvers) | 807 ..sourceFactory = new SourceFactory(resolvers) |
| 813 ..analysisOptions = createAnalysisOptions(options.strongMode); | 808 ..analysisOptions = createAnalysisOptions(options.strongMode); |
| 814 | 809 |
| 815 options.declaredVariables.forEach((String name, String value) { | 810 options.declaredVariables.forEach((String name, String value) { |
| 816 context.declaredVariables.define(name, value); | 811 context.declaredVariables.define(name, value); |
| 817 }); | 812 }); |
| 818 | 813 |
| 819 return context; | 814 return context; |
| 820 } | 815 } |
| OLD | NEW |