| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dev_compiler.src.closure.closure_codegen; | 5 library dev_compiler.src.closure.closure_codegen; |
| 6 | 6 |
| 7 import 'package:analyzer/analyzer.dart' show ParameterKind; | 7 import 'package:analyzer/analyzer.dart' show ParameterKind; |
| 8 import 'package:analyzer/src/generated/element.dart'; | 8 import 'package:analyzer/src/generated/element.dart'; |
| 9 | 9 |
| 10 import 'closure_annotation.dart'; | 10 import 'closure_annotation.dart'; |
| 11 import 'closure_type.dart'; | 11 import 'closure_type.dart'; |
| 12 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | 12 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; |
| 13 | 13 |
| 14 /// Mixin that can generate [ClosureAnnotation]s for Dart elements and types. | 14 /// Mixin that can generate [ClosureAnnotation]s for Dart elements and types. |
| 15 abstract class ClosureAnnotator { | 15 abstract class ClosureAnnotator { |
| 16 TypeProvider get types; | 16 TypeProvider get types; |
| 17 | 17 |
| 18 /// Must return a JavaScript qualified name that can be used to refer to [type
]. | 18 /// Must return a JavaScript qualified name that can be used to refer to [type
]. |
| 19 String getQualifiedName(TypeDefiningElement type); | 19 String getQualifiedName(TypeDefiningElement type); |
| 20 | 20 |
| 21 ClosureAnnotation closureAnnotationForVariable(VariableElement e) => | 21 ClosureAnnotation closureAnnotationForVariable(VariableElement e) => |
| 22 new ClosureAnnotation(type: _closureTypeForDartType(e.type), | 22 new ClosureAnnotation( |
| 23 type: _closureTypeForDartType(e.type), |
| 23 // Note: we don't set isConst here because Closure's constness and | 24 // Note: we don't set isConst here because Closure's constness and |
| 24 // Dart's are not really compatible. | 25 // Dart's are not really compatible. |
| 25 isFinal: e.isFinal || e.isConst); | 26 isFinal: e.isFinal || e.isConst); |
| 26 | 27 |
| 27 /// We don't use Closure's `@typedef` annotations | 28 /// We don't use Closure's `@typedef` annotations |
| 28 ClosureAnnotation closureAnnotationForTypeDef(FunctionTypeAliasElement e) => | 29 ClosureAnnotation closureAnnotationForTypeDef(FunctionTypeAliasElement e) => |
| 29 new ClosureAnnotation( | 30 new ClosureAnnotation( |
| 30 type: _closureTypeForDartType(e.type, forceTypeDefExpansion: true), | 31 type: _closureTypeForDartType(e.type, forceTypeDefExpansion: true), |
| 31 isTypedef: true); | 32 isTypedef: true); |
| 32 | 33 |
| 33 ClosureAnnotation closureAnnotationForDefaultConstructor(ClassElement e) => | 34 ClosureAnnotation closureAnnotationForDefaultConstructor(ClassElement e) => |
| 34 new ClosureAnnotation( | 35 new ClosureAnnotation( |
| 35 superType: _closureTypeForDartType(e.supertype), | 36 superType: _closureTypeForDartType(e.supertype), |
| 36 interfaces: e.interfaces.map(_closureTypeForDartType).toList()); | 37 interfaces: e.interfaces.map(_closureTypeForDartType).toList()); |
| 37 | 38 |
| 38 ClosureAnnotation closureAnnotationFor( | 39 ClosureAnnotation closureAnnotationFor( |
| 39 ExecutableElement e, String namedArgsMapName) { | 40 ExecutableElement e, String namedArgsMapName) { |
| 40 var paramTypes = <String, ClosureType>{}; | 41 var paramTypes = <String, ClosureType>{}; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 55 } | 56 } |
| 56 if (namedArgs.isNotEmpty) { | 57 if (namedArgs.isNotEmpty) { |
| 57 paramTypes[namedArgsMapName] = | 58 paramTypes[namedArgsMapName] = |
| 58 new ClosureType.record(namedArgs).toOptional(); | 59 new ClosureType.record(namedArgs).toOptional(); |
| 59 } | 60 } |
| 60 | 61 |
| 61 var returnType = e is ConstructorElement | 62 var returnType = e is ConstructorElement |
| 62 ? (e.isFactory ? _closureTypeForClass(e.enclosingElement) : null) | 63 ? (e.isFactory ? _closureTypeForClass(e.enclosingElement) : null) |
| 63 : _closureTypeForDartType(e.returnType); | 64 : _closureTypeForDartType(e.returnType); |
| 64 | 65 |
| 65 return new ClosureAnnotation(isOverride: e.isOverride, | 66 return new ClosureAnnotation( |
| 67 isOverride: e.isOverride, |
| 66 // Note: Dart and Closure privacy are not compatible: don't set `isPriva
te: e.isPrivate`. | 68 // Note: Dart and Closure privacy are not compatible: don't set `isPriva
te: e.isPrivate`. |
| 67 paramTypes: paramTypes, returnType: returnType); | 69 paramTypes: paramTypes, |
| 70 returnType: returnType); |
| 68 } | 71 } |
| 69 | 72 |
| 70 Map<DartType, ClosureType> __commonTypes; | 73 Map<DartType, ClosureType> __commonTypes; |
| 71 Map<DartType, ClosureType> get _commonTypes { | 74 Map<DartType, ClosureType> get _commonTypes { |
| 72 if (__commonTypes == null) { | 75 if (__commonTypes == null) { |
| 73 var numberType = new ClosureType.number().toNullable(); | 76 var numberType = new ClosureType.number().toNullable(); |
| 74 __commonTypes = { | 77 __commonTypes = { |
| 75 types.intType: numberType, | 78 types.intType: numberType, |
| 76 types.numType: numberType, | 79 types.numType: numberType, |
| 77 types.doubleType: numberType, | 80 types.doubleType: numberType, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 106 ClosureType _closureTypeForDartType(DartType type, | 109 ClosureType _closureTypeForDartType(DartType type, |
| 107 {bool forceTypeDefExpansion: false}) { | 110 {bool forceTypeDefExpansion: false}) { |
| 108 if (type == null || type.isBottom || type.isDynamic) { | 111 if (type == null || type.isBottom || type.isDynamic) { |
| 109 return new ClosureType.unknown(); | 112 return new ClosureType.unknown(); |
| 110 } | 113 } |
| 111 if (type.isVoid) return null; | 114 if (type.isVoid) return null; |
| 112 if (type is FunctionType) { | 115 if (type is FunctionType) { |
| 113 if (!forceTypeDefExpansion && type.element.name != '') { | 116 if (!forceTypeDefExpansion && type.element.name != '') { |
| 114 return new ClosureType.type(getQualifiedName(type.element)); | 117 return new ClosureType.type(getQualifiedName(type.element)); |
| 115 } | 118 } |
| 116 | 119 |
| 117 var args = [] | 120 var args = [] |
| 118 ..addAll(type.normalParameterTypes.map(_closureTypeForDartType)) | 121 ..addAll(type.normalParameterTypes.map(_closureTypeForDartType)) |
| 119 ..addAll(type.optionalParameterTypes | 122 ..addAll(type.optionalParameterTypes |
| 120 .map((t) => _closureTypeForDartType(t).toOptional())); | 123 .map((t) => _closureTypeForDartType(t).toOptional())); |
| 121 if (type.namedParameterTypes.isNotEmpty) { | 124 if (type.namedParameterTypes.isNotEmpty) { |
| 122 var namedArgs = <String, ClosureType>{}; | 125 var namedArgs = <String, ClosureType>{}; |
| 123 type.namedParameterTypes.forEach((n, t) { | 126 type.namedParameterTypes.forEach((n, t) { |
| 124 namedArgs[n] = _closureTypeForDartType(t).orUndefined(); | 127 namedArgs[n] = _closureTypeForDartType(t).orUndefined(); |
| 125 }); | 128 }); |
| 126 args.add(new ClosureType.record(namedArgs).toOptional()); | 129 args.add(new ClosureType.record(namedArgs).toOptional()); |
| 127 } | 130 } |
| 128 return new ClosureType.function( | 131 return new ClosureType.function( |
| 129 args, _closureTypeForDartType(type.returnType)); | 132 args, _closureTypeForDartType(type.returnType)); |
| 130 } | 133 } |
| 131 if (type is InterfaceType) { | 134 if (type is InterfaceType) { |
| 132 return _closureTypeForClass(type.element, type); | 135 return _closureTypeForClass(type.element, type); |
| 133 } | 136 } |
| 134 return new ClosureType.unknown(); | 137 return new ClosureType.unknown(); |
| 135 } | 138 } |
| 136 | 139 |
| 137 /// TODO(ochafik): Use a package-and-file-uri-dependent naming, since librarie
s can collide. | 140 /// TODO(ochafik): Use a package-and-file-uri-dependent naming, since librarie
s can collide. |
| 138 String _getFullName(ClassElement type) => | 141 String _getFullName(ClassElement type) => |
| 139 type.library.name == '' ? type.name : '${type.library.name}.${type.name}'; | 142 type.library.name == '' ? type.name : '${type.library.name}.${type.name}'; |
| 140 } | 143 } |
| OLD | NEW |