| 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 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 /// Returns the IR for a class, at a temporary loading level. | 261 /// Returns the IR for a class, at a temporary loading level. |
| 262 /// | 262 /// |
| 263 /// The returned class has the correct name, flags, type parameter arity, | 263 /// The returned class has the correct name, flags, type parameter arity, |
| 264 /// and enclosing library. | 264 /// and enclosing library. |
| 265 ast.Class getClassReference(ClassElement element) { | 265 ast.Class getClassReference(ClassElement element) { |
| 266 var classNode = _classes[element]; | 266 var classNode = _classes[element]; |
| 267 if (classNode != null) return classNode; | 267 if (classNode != null) return classNode; |
| 268 _classes[element] = classNode = new ast.Class( | 268 _classes[element] = classNode = new ast.Class( |
| 269 name: element.name, | 269 name: element.name, |
| 270 isAbstract: element.isAbstract, | 270 isAbstract: element.isAbstract, |
| 271 fileUri: '${element.source.uri}'); | 271 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; |
| 272 classNode.level = ast.ClassLevel.Temporary; | 272 classNode.level = ast.ClassLevel.Temporary; |
| 273 var library = getLibraryReference(element.library); | 273 var library = getLibraryReference(element.library); |
| 274 library.addClass(classNode); | 274 library.addClass(classNode); |
| 275 // Initialize type parameter list without bounds. | 275 // Initialize type parameter list without bounds. |
| 276 for (var parameter in element.typeParameters) { | 276 for (var parameter in element.typeParameters) { |
| 277 var parameterNode = new ast.TypeParameter(parameter.name); | 277 var parameterNode = new ast.TypeParameter(parameter.name); |
| 278 _classTypeParameters[parameter] = parameterNode; | 278 _classTypeParameters[parameter] = parameterNode; |
| 279 classNode.typeParameters.add(parameterNode); | 279 classNode.typeParameters.add(parameterNode); |
| 280 parameterNode.parent = classNode; | 280 parameterNode.parent = classNode; |
| 281 } | 281 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 311 if (element.supertype != null) { | 311 if (element.supertype != null) { |
| 312 ast.Supertype supertype = scope.buildSupertype(element.supertype); | 312 ast.Supertype supertype = scope.buildSupertype(element.supertype); |
| 313 bool useSharedMixin = true; | 313 bool useSharedMixin = true; |
| 314 for (var mixin in mixins) { | 314 for (var mixin in mixins) { |
| 315 var mixinType = scope.buildSupertype(mixin); | 315 var mixinType = scope.buildSupertype(mixin); |
| 316 if (useSharedMixin && | 316 if (useSharedMixin && |
| 317 areDistinctUnboundTypeVariables(supertype, mixinType)) { | 317 areDistinctUnboundTypeVariables(supertype, mixinType)) { |
| 318 // Use a shared mixin application class for this library. | 318 // Use a shared mixin application class for this library. |
| 319 var mixinClass = getSharedMixinApplicationClass( | 319 var mixinClass = getSharedMixinApplicationClass( |
| 320 scope.currentLibrary, supertype.classNode, mixinType.classNode); | 320 scope.currentLibrary, supertype.classNode, mixinType.classNode); |
| 321 if (mixinClass.fileOffset < 0) { |
| 322 mixinClass.fileOffset = element.nameOffset; |
| 323 } |
| 321 supertype = new ast.Supertype( | 324 supertype = new ast.Supertype( |
| 322 mixinClass, | 325 mixinClass, |
| 323 supertype.typeArguments.length > mixinType.typeArguments.length | 326 supertype.typeArguments.length > mixinType.typeArguments.length |
| 324 ? supertype.typeArguments | 327 ? supertype.typeArguments |
| 325 : mixinType.typeArguments); | 328 : mixinType.typeArguments); |
| 326 } else { | 329 } else { |
| 327 // Generate a new class specific for this mixin application. | 330 // Generate a new class specific for this mixin application. |
| 328 var freshParameters = | 331 var freshParameters = |
| 329 getFreshTypeParameters(classNode.typeParameters); | 332 getFreshTypeParameters(classNode.typeParameters); |
| 330 var mixinClass = new ast.Class( | 333 var mixinClass = new ast.Class( |
| 331 name: '${classNode.name}^${mixinType.classNode.name}', | 334 name: '${classNode.name}^${mixinType.classNode.name}', |
| 332 isAbstract: true, | 335 isAbstract: true, |
| 333 typeParameters: freshParameters.freshTypeParameters, | 336 typeParameters: freshParameters.freshTypeParameters, |
| 334 supertype: freshParameters.substituteSuper(supertype), | 337 supertype: freshParameters.substituteSuper(supertype), |
| 335 mixedInType: freshParameters.substituteSuper(mixinType), | 338 mixedInType: freshParameters.substituteSuper(mixinType), |
| 336 fileUri: classNode.fileUri); | 339 fileUri: classNode.fileUri)..fileOffset = element.nameOffset; |
| 337 mixinClass.level = ast.ClassLevel.Type; | 340 mixinClass.level = ast.ClassLevel.Type; |
| 338 supertype = new ast.Supertype(mixinClass, | 341 supertype = new ast.Supertype(mixinClass, |
| 339 classNode.typeParameters.map(makeTypeParameterType).toList()); | 342 classNode.typeParameters.map(makeTypeParameterType).toList()); |
| 340 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); | 343 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); |
| 341 // This class cannot be used from anywhere else, so don't try to | 344 // This class cannot be used from anywhere else, so don't try to |
| 342 // generate shared mixin applications using it. | 345 // generate shared mixin applications using it. |
| 343 useSharedMixin = false; | 346 useSharedMixin = false; |
| 344 } | 347 } |
| 345 } | 348 } |
| 346 classNode.supertype = supertype; | 349 classNode.supertype = supertype; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 ConstructorElement constructor = element; | 442 ConstructorElement constructor = element; |
| 440 if (constructor.isFactory) { | 443 if (constructor.isFactory) { |
| 441 return new ast.Procedure( | 444 return new ast.Procedure( |
| 442 _nameOfMember(constructor), | 445 _nameOfMember(constructor), |
| 443 ast.ProcedureKind.Factory, | 446 ast.ProcedureKind.Factory, |
| 444 scope.buildFunctionInterface(constructor), | 447 scope.buildFunctionInterface(constructor), |
| 445 isAbstract: false, | 448 isAbstract: false, |
| 446 isStatic: true, | 449 isStatic: true, |
| 447 isExternal: constructor.isExternal, | 450 isExternal: constructor.isExternal, |
| 448 isConst: constructor.isConst, | 451 isConst: constructor.isConst, |
| 449 fileUri: '${element.source.uri}'); | 452 fileUri: '${element.source.uri}') |
| 453 ..fileOffset = element.nameOffset; |
| 450 } | 454 } |
| 451 return new ast.Constructor(scope.buildFunctionInterface(constructor), | 455 return new ast.Constructor(scope.buildFunctionInterface(constructor), |
| 452 name: _nameOfMember(element), | 456 name: _nameOfMember(element), |
| 453 isConst: constructor.isConst, | 457 isConst: constructor.isConst, |
| 454 isExternal: constructor.isExternal); | 458 isExternal: constructor.isExternal) |
| 459 ..fileOffset = element.nameOffset; |
| 455 | 460 |
| 456 case ElementKind.FIELD: | 461 case ElementKind.FIELD: |
| 457 case ElementKind.TOP_LEVEL_VARIABLE: | 462 case ElementKind.TOP_LEVEL_VARIABLE: |
| 458 VariableElement variable = element; | 463 VariableElement variable = element; |
| 459 return new ast.Field(_nameOfMember(variable), | 464 return new ast.Field(_nameOfMember(variable), |
| 460 isStatic: variable.isStatic, | 465 isStatic: variable.isStatic, |
| 461 isFinal: variable.isFinal, | 466 isFinal: variable.isFinal, |
| 462 isConst: variable.isConst, | 467 isConst: variable.isConst, |
| 463 type: scope.buildType(variable.type), | 468 type: scope.buildType(variable.type), |
| 464 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; | 469 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; |
| 465 | 470 |
| 466 case ElementKind.METHOD: | 471 case ElementKind.METHOD: |
| 467 case ElementKind.GETTER: | 472 case ElementKind.GETTER: |
| 468 case ElementKind.SETTER: | 473 case ElementKind.SETTER: |
| 469 case ElementKind.FUNCTION: | 474 case ElementKind.FUNCTION: |
| 470 if (element is FunctionElement && | 475 if (element is FunctionElement && |
| 471 element.enclosingElement is! CompilationUnitElement) { | 476 element.enclosingElement is! CompilationUnitElement) { |
| 472 throw 'Function $element is nested in ${element.enclosingElement} ' | 477 throw 'Function $element is nested in ${element.enclosingElement} ' |
| 473 'and hence is not a member'; | 478 'and hence is not a member'; |
| 474 } | 479 } |
| 475 ExecutableElement executable = element; | 480 ExecutableElement executable = element; |
| 476 return new ast.Procedure( | 481 return new ast.Procedure( |
| 477 _nameOfMember(element), | 482 _nameOfMember(element), |
| 478 _procedureKindOf(executable), | 483 _procedureKindOf(executable), |
| 479 scope.buildFunctionInterface(executable), | 484 scope.buildFunctionInterface(executable), |
| 480 isAbstract: executable.isAbstract, | 485 isAbstract: executable.isAbstract, |
| 481 isStatic: executable.isStatic, | 486 isStatic: executable.isStatic, |
| 482 isExternal: executable.isExternal, | 487 isExternal: executable.isExternal, |
| 483 fileUri: '${element.source.uri}'); | 488 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; |
| 484 | 489 |
| 485 default: | 490 default: |
| 486 throw 'Unexpected member kind: $element'; | 491 throw 'Unexpected member kind: $element'; |
| 487 } | 492 } |
| 488 } | 493 } |
| 489 | 494 |
| 490 ast.ProcedureKind _procedureKindOf(ExecutableElement element) { | 495 ast.ProcedureKind _procedureKindOf(ExecutableElement element) { |
| 491 if (element is PropertyAccessorElement) { | 496 if (element is PropertyAccessorElement) { |
| 492 return element.isGetter | 497 return element.isGetter |
| 493 ? ast.ProcedureKind.Getter | 498 ? ast.ProcedureKind.Getter |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() | 867 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() |
| 863 ..sourceFactory = new SourceFactory(resolvers) | 868 ..sourceFactory = new SourceFactory(resolvers) |
| 864 ..analysisOptions = createAnalysisOptions(options.strongMode); | 869 ..analysisOptions = createAnalysisOptions(options.strongMode); |
| 865 | 870 |
| 866 options.declaredVariables.forEach((String name, String value) { | 871 options.declaredVariables.forEach((String name, String value) { |
| 867 context.declaredVariables.define(name, value); | 872 context.declaredVariables.define(name, value); |
| 868 }); | 873 }); |
| 869 | 874 |
| 870 return context; | 875 return context; |
| 871 } | 876 } |
| OLD | NEW |