Chromium Code Reviews| 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 28 matching lines...) Expand all Loading... | |
| 310 } | 310 } |
| 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 ..fileOffset = element.nameOffset; | |
|
asgerf
2017/01/04 14:20:01
What is the class offset used for?
Is it okay tha
jensj
2017/01/05 09:07:55
In general class offsets is used by Observatory to
asgerf
2017/01/05 11:37:41
Thanks for the clarification. Looks good to me the
| |
| 321 supertype = new ast.Supertype( | 322 supertype = new ast.Supertype( |
| 322 mixinClass, | 323 mixinClass, |
| 323 supertype.typeArguments.length > mixinType.typeArguments.length | 324 supertype.typeArguments.length > mixinType.typeArguments.length |
| 324 ? supertype.typeArguments | 325 ? supertype.typeArguments |
| 325 : mixinType.typeArguments); | 326 : mixinType.typeArguments); |
| 326 } else { | 327 } else { |
| 327 // Generate a new class specific for this mixin application. | 328 // Generate a new class specific for this mixin application. |
| 328 var freshParameters = | 329 var freshParameters = |
| 329 getFreshTypeParameters(classNode.typeParameters); | 330 getFreshTypeParameters(classNode.typeParameters); |
| 330 var mixinClass = new ast.Class( | 331 var mixinClass = new ast.Class( |
| 331 name: '${classNode.name}^${mixinType.classNode.name}', | 332 name: '${classNode.name}^${mixinType.classNode.name}', |
| 332 isAbstract: true, | 333 isAbstract: true, |
| 333 typeParameters: freshParameters.freshTypeParameters, | 334 typeParameters: freshParameters.freshTypeParameters, |
| 334 supertype: freshParameters.substituteSuper(supertype), | 335 supertype: freshParameters.substituteSuper(supertype), |
| 335 mixedInType: freshParameters.substituteSuper(mixinType), | 336 mixedInType: freshParameters.substituteSuper(mixinType), |
| 336 fileUri: classNode.fileUri); | 337 fileUri: classNode.fileUri)..fileOffset = element.nameOffset; |
| 337 mixinClass.level = ast.ClassLevel.Type; | 338 mixinClass.level = ast.ClassLevel.Type; |
| 338 supertype = new ast.Supertype(mixinClass, | 339 supertype = new ast.Supertype(mixinClass, |
| 339 classNode.typeParameters.map(makeTypeParameterType).toList()); | 340 classNode.typeParameters.map(makeTypeParameterType).toList()); |
| 340 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); | 341 addMixinClassToLibrary(mixinClass, classNode.enclosingLibrary); |
| 341 // This class cannot be used from anywhere else, so don't try to | 342 // This class cannot be used from anywhere else, so don't try to |
| 342 // generate shared mixin applications using it. | 343 // generate shared mixin applications using it. |
| 343 useSharedMixin = false; | 344 useSharedMixin = false; |
| 344 } | 345 } |
| 345 } | 346 } |
| 346 classNode.supertype = supertype; | 347 classNode.supertype = supertype; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 ConstructorElement constructor = element; | 440 ConstructorElement constructor = element; |
| 440 if (constructor.isFactory) { | 441 if (constructor.isFactory) { |
| 441 return new ast.Procedure( | 442 return new ast.Procedure( |
| 442 _nameOfMember(constructor), | 443 _nameOfMember(constructor), |
| 443 ast.ProcedureKind.Factory, | 444 ast.ProcedureKind.Factory, |
| 444 scope.buildFunctionInterface(constructor), | 445 scope.buildFunctionInterface(constructor), |
| 445 isAbstract: false, | 446 isAbstract: false, |
| 446 isStatic: true, | 447 isStatic: true, |
| 447 isExternal: constructor.isExternal, | 448 isExternal: constructor.isExternal, |
| 448 isConst: constructor.isConst, | 449 isConst: constructor.isConst, |
| 449 fileUri: '${element.source.uri}'); | 450 fileUri: '${element.source.uri}') |
| 451 ..fileOffset = element.nameOffset; | |
| 450 } | 452 } |
| 451 return new ast.Constructor(scope.buildFunctionInterface(constructor), | 453 return new ast.Constructor(scope.buildFunctionInterface(constructor), |
| 452 name: _nameOfMember(element), | 454 name: _nameOfMember(element), |
| 453 isConst: constructor.isConst, | 455 isConst: constructor.isConst, |
| 454 isExternal: constructor.isExternal); | 456 isExternal: constructor.isExternal) |
| 457 ..fileOffset = element.nameOffset; | |
| 455 | 458 |
| 456 case ElementKind.FIELD: | 459 case ElementKind.FIELD: |
| 457 case ElementKind.TOP_LEVEL_VARIABLE: | 460 case ElementKind.TOP_LEVEL_VARIABLE: |
| 458 VariableElement variable = element; | 461 VariableElement variable = element; |
| 459 return new ast.Field(_nameOfMember(variable), | 462 return new ast.Field(_nameOfMember(variable), |
| 460 isStatic: variable.isStatic, | 463 isStatic: variable.isStatic, |
| 461 isFinal: variable.isFinal, | 464 isFinal: variable.isFinal, |
| 462 isConst: variable.isConst, | 465 isConst: variable.isConst, |
| 463 type: scope.buildType(variable.type), | 466 type: scope.buildType(variable.type), |
| 464 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; | 467 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; |
| 465 | 468 |
| 466 case ElementKind.METHOD: | 469 case ElementKind.METHOD: |
| 467 case ElementKind.GETTER: | 470 case ElementKind.GETTER: |
| 468 case ElementKind.SETTER: | 471 case ElementKind.SETTER: |
| 469 case ElementKind.FUNCTION: | 472 case ElementKind.FUNCTION: |
| 470 if (element is FunctionElement && | 473 if (element is FunctionElement && |
| 471 element.enclosingElement is! CompilationUnitElement) { | 474 element.enclosingElement is! CompilationUnitElement) { |
| 472 throw 'Function $element is nested in ${element.enclosingElement} ' | 475 throw 'Function $element is nested in ${element.enclosingElement} ' |
| 473 'and hence is not a member'; | 476 'and hence is not a member'; |
| 474 } | 477 } |
| 475 ExecutableElement executable = element; | 478 ExecutableElement executable = element; |
| 476 return new ast.Procedure( | 479 return new ast.Procedure( |
| 477 _nameOfMember(element), | 480 _nameOfMember(element), |
| 478 _procedureKindOf(executable), | 481 _procedureKindOf(executable), |
| 479 scope.buildFunctionInterface(executable), | 482 scope.buildFunctionInterface(executable), |
| 480 isAbstract: executable.isAbstract, | 483 isAbstract: executable.isAbstract, |
| 481 isStatic: executable.isStatic, | 484 isStatic: executable.isStatic, |
| 482 isExternal: executable.isExternal, | 485 isExternal: executable.isExternal, |
| 483 fileUri: '${element.source.uri}'); | 486 fileUri: '${element.source.uri}')..fileOffset = element.nameOffset; |
| 484 | 487 |
| 485 default: | 488 default: |
| 486 throw 'Unexpected member kind: $element'; | 489 throw 'Unexpected member kind: $element'; |
| 487 } | 490 } |
| 488 } | 491 } |
| 489 | 492 |
| 490 ast.ProcedureKind _procedureKindOf(ExecutableElement element) { | 493 ast.ProcedureKind _procedureKindOf(ExecutableElement element) { |
| 491 if (element is PropertyAccessorElement) { | 494 if (element is PropertyAccessorElement) { |
| 492 return element.isGetter | 495 return element.isGetter |
| 493 ? ast.ProcedureKind.Getter | 496 ? ast.ProcedureKind.Getter |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 862 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() | 865 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext() |
| 863 ..sourceFactory = new SourceFactory(resolvers) | 866 ..sourceFactory = new SourceFactory(resolvers) |
| 864 ..analysisOptions = createAnalysisOptions(options.strongMode); | 867 ..analysisOptions = createAnalysisOptions(options.strongMode); |
| 865 | 868 |
| 866 options.declaredVariables.forEach((String name, String value) { | 869 options.declaredVariables.forEach((String name, String value) { |
| 867 context.declaredVariables.define(name, value); | 870 context.declaredVariables.define(name, value); |
| 868 }); | 871 }); |
| 869 | 872 |
| 870 return context; | 873 return context; |
| 871 } | 874 } |
| OLD | NEW |