| 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 this.applicationRoot = options.applicationRoot; | 113 this.applicationRoot = options.applicationRoot; |
| 114 | 114 |
| 115 String getLibraryName(LibraryElement element) { | 115 String getLibraryName(LibraryElement element) { |
| 116 return element.name.isEmpty ? null : element.name; | 116 return element.name.isEmpty ? null : element.name; |
| 117 } | 117 } |
| 118 | 118 |
| 119 ast.Library getLibraryReference(LibraryElement element) { | 119 ast.Library getLibraryReference(LibraryElement element) { |
| 120 var uri = applicationRoot.relativeUri(element.source.uri); | 120 var uri = applicationRoot.relativeUri(element.source.uri); |
| 121 return repository.getLibraryReference(uri) | 121 return repository.getLibraryReference(uri) |
| 122 ..name ??= getLibraryName(element) | 122 ..name ??= getLibraryName(element) |
| 123 ..fileUri = "file://${element.source.fullName}"; | 123 ..fileUri = '${element.source.uri}'; |
| 124 } | 124 } |
| 125 | 125 |
| 126 void _buildTopLevelMember( | 126 void _buildTopLevelMember( |
| 127 ast.Member member, Element element, Declaration astNode) { | 127 ast.Member member, Element element, Declaration astNode) { |
| 128 assert(member.parent != null); | 128 assert(member.parent != null); |
| 129 new MemberBodyBuilder(this, member, element).build(astNode); | 129 new MemberBodyBuilder(this, member, element).build(astNode); |
| 130 } | 130 } |
| 131 | 131 |
| 132 /// True if [element] is in the process of being loaded by | 132 /// True if [element] is in the process of being loaded by |
| 133 /// [_buildLibraryBody]. | 133 /// [_buildLibraryBody]. |
| (...skipping 127 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: "file://${element.source.fullName}"); | 271 fileUri: '${element.source.uri}'); |
| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 : mixinType.typeArguments); | 325 : mixinType.typeArguments); |
| 326 } else { | 326 } else { |
| 327 // Generate a new class specific for this mixin application. | 327 // Generate a new class specific for this mixin application. |
| 328 var freshParameters = | 328 var freshParameters = |
| 329 getFreshTypeParameters(classNode.typeParameters); | 329 getFreshTypeParameters(classNode.typeParameters); |
| 330 var mixinClass = new ast.Class( | 330 var mixinClass = new ast.Class( |
| 331 name: '${classNode.name}^${mixinType.classNode.name}', | 331 name: '${classNode.name}^${mixinType.classNode.name}', |
| 332 isAbstract: true, | 332 isAbstract: true, |
| 333 typeParameters: freshParameters.freshTypeParameters, | 333 typeParameters: freshParameters.freshTypeParameters, |
| 334 supertype: freshParameters.substituteSuper(supertype), | 334 supertype: freshParameters.substituteSuper(supertype), |
| 335 mixedInType: freshParameters.substituteSuper(mixinType)); | 335 mixedInType: freshParameters.substituteSuper(mixinType), |
| 336 fileUri: classNode.fileUri); |
| 336 mixinClass.level = ast.ClassLevel.Type; | 337 mixinClass.level = ast.ClassLevel.Type; |
| 337 supertype = new ast.Supertype(mixinClass, | 338 supertype = new ast.Supertype(mixinClass, |
| 338 classNode.typeParameters.map(makeTypeParameterType).toList()); | 339 classNode.typeParameters.map(makeTypeParameterType).toList()); |
| 339 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); | 340 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); |
| 340 // This class cannot be used from anywhere else, so don't try to | 341 // This class cannot be used from anywhere else, so don't try to |
| 341 // generate shared mixin applications using it. | 342 // generate shared mixin applications using it. |
| 342 useSharedMixin = false; | 343 useSharedMixin = false; |
| 343 } | 344 } |
| 344 } | 345 } |
| 345 classNode.supertype = supertype; | 346 classNode.supertype = supertype; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 ConstructorElement constructor = element; | 439 ConstructorElement constructor = element; |
| 439 if (constructor.isFactory) { | 440 if (constructor.isFactory) { |
| 440 return new ast.Procedure( | 441 return new ast.Procedure( |
| 441 _nameOfMember(constructor), | 442 _nameOfMember(constructor), |
| 442 ast.ProcedureKind.Factory, | 443 ast.ProcedureKind.Factory, |
| 443 scope.buildFunctionInterface(constructor), | 444 scope.buildFunctionInterface(constructor), |
| 444 isAbstract: false, | 445 isAbstract: false, |
| 445 isStatic: true, | 446 isStatic: true, |
| 446 isExternal: constructor.isExternal, | 447 isExternal: constructor.isExternal, |
| 447 isConst: constructor.isConst, | 448 isConst: constructor.isConst, |
| 448 fileUri: "file://${element.source.fullName}"); | 449 fileUri: '${element.source.uri}'); |
| 449 } | 450 } |
| 450 return new ast.Constructor(scope.buildFunctionInterface(constructor), | 451 return new ast.Constructor(scope.buildFunctionInterface(constructor), |
| 451 name: _nameOfMember(element), | 452 name: _nameOfMember(element), |
| 452 isConst: constructor.isConst, | 453 isConst: constructor.isConst, |
| 453 isExternal: constructor.isExternal); | 454 isExternal: constructor.isExternal); |
| 454 | 455 |
| 455 case ElementKind.FIELD: | 456 case ElementKind.FIELD: |
| 456 case ElementKind.TOP_LEVEL_VARIABLE: | 457 case ElementKind.TOP_LEVEL_VARIABLE: |
| 457 VariableElement variable = element; | 458 VariableElement variable = element; |
| 458 return new ast.Field(_nameOfMember(variable), | 459 return new ast.Field(_nameOfMember(variable), |
| 459 isStatic: variable.isStatic, | 460 isStatic: variable.isStatic, |
| 460 isFinal: variable.isFinal, | 461 isFinal: variable.isFinal, |
| 461 isConst: variable.isConst, | 462 isConst: variable.isConst, |
| 462 type: scope.buildType(variable.type), | 463 type: scope.buildType(variable.type), |
| 463 fileUri: "file://${element.source.fullName}") | 464 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; |
| 464 ..fileOffset = element.nameOffset; | |
| 465 | 465 |
| 466 case ElementKind.METHOD: | 466 case ElementKind.METHOD: |
| 467 case ElementKind.GETTER: | 467 case ElementKind.GETTER: |
| 468 case ElementKind.SETTER: | 468 case ElementKind.SETTER: |
| 469 case ElementKind.FUNCTION: | 469 case ElementKind.FUNCTION: |
| 470 if (element is FunctionElement && | 470 if (element is FunctionElement && |
| 471 element.enclosingElement is! CompilationUnitElement) { | 471 element.enclosingElement is! CompilationUnitElement) { |
| 472 throw 'Function $element is nested in ${element.enclosingElement} ' | 472 throw 'Function $element is nested in ${element.enclosingElement} ' |
| 473 'and hence is not a member'; | 473 'and hence is not a member'; |
| 474 } | 474 } |
| 475 ExecutableElement executable = element; | 475 ExecutableElement executable = element; |
| 476 return new ast.Procedure( | 476 return new ast.Procedure( |
| 477 _nameOfMember(element), | 477 _nameOfMember(element), |
| 478 _procedureKindOf(executable), | 478 _procedureKindOf(executable), |
| 479 scope.buildFunctionInterface(executable), | 479 scope.buildFunctionInterface(executable), |
| 480 isAbstract: executable.isAbstract, | 480 isAbstract: executable.isAbstract, |
| 481 isStatic: executable.isStatic, | 481 isStatic: executable.isStatic, |
| 482 isExternal: executable.isExternal, | 482 isExternal: executable.isExternal, |
| 483 fileUri: "file://${element.source.fullName}"); | 483 fileUri: '${element.source.uri}'); |
| 484 | 484 |
| 485 default: | 485 default: |
| 486 throw 'Unexpected member kind: $element'; | 486 throw 'Unexpected member kind: $element'; |
| 487 } | 487 } |
| 488 } | 488 } |
| 489 | 489 |
| 490 ast.ProcedureKind _procedureKindOf(ExecutableElement element) { | 490 ast.ProcedureKind _procedureKindOf(ExecutableElement element) { |
| 491 if (element is PropertyAccessorElement) { | 491 if (element is PropertyAccessorElement) { |
| 492 return element.isGetter | 492 return element.isGetter |
| 493 ? ast.ProcedureKind.Getter | 493 ? ast.ProcedureKind.Getter |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 : typeArguments; | 579 : typeArguments; |
| 580 var mixinArgs = typeArguments.length != mixedInClass.typeParameters.length | 580 var mixinArgs = typeArguments.length != mixedInClass.typeParameters.length |
| 581 ? typeArguments.sublist(0, mixedInClass.typeParameters.length) | 581 ? typeArguments.sublist(0, mixedInClass.typeParameters.length) |
| 582 : typeArguments; | 582 : typeArguments; |
| 583 var result = new ast.Class( | 583 var result = new ast.Class( |
| 584 name: name, | 584 name: name, |
| 585 isAbstract: true, | 585 isAbstract: true, |
| 586 typeParameters: fresh.freshTypeParameters, | 586 typeParameters: fresh.freshTypeParameters, |
| 587 supertype: new ast.Supertype(superclass, superArgs), | 587 supertype: new ast.Supertype(superclass, superArgs), |
| 588 mixedInType: new ast.Supertype(mixedInClass, mixinArgs), | 588 mixedInType: new ast.Supertype(mixedInClass, mixinArgs), |
| 589 fileUri: mixedInClass.fileUri); | 589 fileUri: library.fileUri); |
| 590 result.level = ast.ClassLevel.Type; | 590 result.level = ast.ClassLevel.Type; |
| 591 library.addClass(result); | 591 library.addClass(result); |
| 592 return result; | 592 return result; |
| 593 }); | 593 }); |
| 594 } | 594 } |
| 595 | 595 |
| 596 String formatErrorMessage( | 596 String formatErrorMessage( |
| 597 AnalysisError error, String filename, LineInfo lines) { | 597 AnalysisError error, String filename, LineInfo lines) { |
| 598 var location = lines.getLocation(error.offset); | 598 var location = lines.getLocation(error.offset); |
| 599 return '[error] ${error.message} ($filename, ' | 599 return '[error] ${error.message} ($filename, ' |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 loadEverything(target: target, compileSdk: compileSdk); | 687 loadEverything(target: target, compileSdk: compileSdk); |
| 688 var program = new ast.Program(repository.libraries); | 688 var program = new ast.Program(repository.libraries); |
| 689 program.mainMethod = library.procedures.firstWhere( | 689 program.mainMethod = library.procedures.firstWhere( |
| 690 (member) => member.name?.name == 'main', | 690 (member) => member.name?.name == 'main', |
| 691 orElse: () => null); | 691 orElse: () => null); |
| 692 for (LibraryElement libraryElement in libraryElements) { | 692 for (LibraryElement libraryElement in libraryElements) { |
| 693 for (CompilationUnitElement compilationUnitElement | 693 for (CompilationUnitElement compilationUnitElement |
| 694 in libraryElement.units) { | 694 in libraryElement.units) { |
| 695 var source = compilationUnitElement.source; | 695 var source = compilationUnitElement.source; |
| 696 LineInfo lineInfo = context.computeLineInfo(source); | 696 LineInfo lineInfo = context.computeLineInfo(source); |
| 697 program.uriToLineStarts["file://${source.fullName}"] = | 697 String sourceCode; |
| 698 new List<int>.generate(lineInfo.lineCount, lineInfo.getOffsetOfLine, | 698 try { |
| 699 growable: false); | 699 sourceCode = context.getContents(source).data; |
| 700 } catch (e) { |
| 701 // The source's contents could not be accessed. |
| 702 sourceCode = ''; |
| 703 } |
| 704 program.uriToSource['${source.uri}'] = |
| 705 new ast.Source(lineInfo.lineStarts, sourceCode); |
| 700 } | 706 } |
| 701 } | 707 } |
| 702 return program; | 708 return program; |
| 703 } | 709 } |
| 704 | 710 |
| 705 ast.Library loadLibrary(Uri uri) { | 711 ast.Library loadLibrary(Uri uri) { |
| 706 ast.Library library = | 712 ast.Library library = |
| 707 repository.getLibraryReference(applicationRoot.relativeUri(uri)); | 713 repository.getLibraryReference(applicationRoot.relativeUri(uri)); |
| 708 ensureLibraryIsLoaded(library); | 714 ensureLibraryIsLoaded(library); |
| 709 return library; | 715 return library; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() | 862 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() |
| 857 ..sourceFactory = new SourceFactory(resolvers) | 863 ..sourceFactory = new SourceFactory(resolvers) |
| 858 ..analysisOptions = createAnalysisOptions(options.strongMode); | 864 ..analysisOptions = createAnalysisOptions(options.strongMode); |
| 859 | 865 |
| 860 options.declaredVariables.forEach((String name, String value) { | 866 options.declaredVariables.forEach((String name, String value) { |
| 861 context.declaredVariables.define(name, value); | 867 context.declaredVariables.define(name, value); |
| 862 }); | 868 }); |
| 863 | 869 |
| 864 return context; | 870 return context; |
| 865 } | 871 } |
| OLD | NEW |