| Index: lib/src/closure/closure_annotator.dart
|
| diff --git a/lib/src/closure/closure_annotator.dart b/lib/src/closure/closure_annotator.dart
|
| index 7229a1da9983d0bcd6ee110fca69d112d8ab61a9..d527b3df035ca75b72828c69142e1bf662403ea6 100644
|
| --- a/lib/src/closure/closure_annotator.dart
|
| +++ b/lib/src/closure/closure_annotator.dart
|
| @@ -2,141 +2,40 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| -import 'package:analyzer/analyzer.dart' show ParameterKind;
|
| +import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
|
| import 'package:analyzer/src/generated/element.dart';
|
| import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
|
|
|
| +import '../js/js_ast.dart' as JS show Node, Expression, TypeRef;
|
| +
|
| import 'closure_annotation.dart';
|
| -import 'closure_type.dart';
|
|
|
| /// Mixin that can generate [ClosureAnnotation]s for Dart elements and types.
|
| abstract class ClosureAnnotator {
|
| TypeProvider get types;
|
|
|
| - /// Must return a JavaScript qualified name that can be used to refer to [type].
|
| - String getQualifiedName(TypeDefiningElement type);
|
| -
|
| - ClosureAnnotation closureAnnotationForVariable(VariableElement e) =>
|
| - new ClosureAnnotation(
|
| - type: _closureTypeForDartType(e.type),
|
| - // Note: we don't set isConst here because Closure's constness and
|
| - // Dart's are not really compatible.
|
| - isFinal: e.isFinal || e.isConst);
|
| -
|
| - /// We don't use Closure's `@typedef` annotations
|
| - ClosureAnnotation closureAnnotationForTypeDef(FunctionTypeAliasElement e) =>
|
| - new ClosureAnnotation(
|
| - type: _closureTypeForDartType(e.type, forceTypeDefExpansion: true),
|
| - isTypedef: true);
|
| -
|
| - ClosureAnnotation closureAnnotationForDefaultConstructor(ClassElement e) =>
|
| - new ClosureAnnotation(
|
| - superType: _closureTypeForDartType(e.supertype),
|
| - interfaces: e.interfaces.map(_closureTypeForDartType).toList());
|
| + JS.TypeRef emitTypeRef(DartType type);
|
|
|
| // TODO(ochafik): Handle destructured params when Closure supports it.
|
| ClosureAnnotation closureAnnotationFor(
|
| - ExecutableElement e, String namedArgsMapName) {
|
| - var paramTypes = <String, ClosureType>{};
|
| - var namedArgs = <String, ClosureType>{};
|
| - for (var param in e.parameters) {
|
| - var t = _closureTypeForDartType(param.type);
|
| - switch (param.parameterKind) {
|
| - case ParameterKind.NAMED:
|
| - namedArgs[param.name] = t.orUndefined();
|
| - break;
|
| - case ParameterKind.POSITIONAL:
|
| - paramTypes[param.name] = t.toOptional();
|
| - break;
|
| - case ParameterKind.REQUIRED:
|
| - paramTypes[param.name] = t;
|
| - break;
|
| - }
|
| - }
|
| - if (namedArgs.isNotEmpty) {
|
| - paramTypes[namedArgsMapName] =
|
| - new ClosureType.record(namedArgs).toOptional();
|
| + JS.Node node, AstNode original, Element e, String namedArgsMapName) {
|
| + String comment;
|
| + if (original is AnnotatedNode && original.documentationComment != null) {
|
| + comment = original.documentationComment.toSource();
|
| }
|
| -
|
| - var returnType = e is ConstructorElement
|
| - ? (e.isFactory ? _closureTypeForClass(e.enclosingElement) : null)
|
| - : _closureTypeForDartType(e.returnType);
|
| -
|
| + // Note: Dart and Closure privacy are not compatible: don't set `isPrivate: e.isPrivate`.
|
| return new ClosureAnnotation(
|
| + comment: comment,
|
| + // Note: we don't set isConst here because Closure's constness and
|
| + // Dart's are not really compatible.
|
| + isFinal: e is VariableElement && (e.isFinal || e.isConst),
|
| + type: e is VariableElement
|
| + ? emitTypeRef(e.type /*, forceTypeDefExpansion: true*/)
|
| + : null,
|
| + superType: e is ClassElement ? emitTypeRef(e.supertype) : null,
|
| + interfaces:
|
| + e is ClassElement ? e.interfaces.map(emitTypeRef).toList() : null,
|
| isOverride: e.isOverride,
|
| - // Note: Dart and Closure privacy are not compatible: don't set `isPrivate: e.isPrivate`.
|
| - paramTypes: paramTypes,
|
| - returnType: returnType);
|
| + isTypedef: e is FunctionTypeAliasElement);
|
| }
|
| -
|
| - Map<DartType, ClosureType> __commonTypes;
|
| - Map<DartType, ClosureType> get _commonTypes {
|
| - if (__commonTypes == null) {
|
| - var numberType = new ClosureType.number().toNullable();
|
| - __commonTypes = {
|
| - types.intType: numberType,
|
| - types.numType: numberType,
|
| - types.doubleType: numberType,
|
| - types.boolType: new ClosureType.boolean().toNullable(),
|
| - types.stringType: new ClosureType.string(),
|
| - };
|
| - }
|
| - return __commonTypes;
|
| - }
|
| -
|
| - ClosureType _closureTypeForClass(ClassElement classElement, [DartType type]) {
|
| - ClosureType closureType = _commonTypes[type];
|
| - if (closureType != null) return closureType;
|
| -
|
| - var fullName = _getFullName(classElement);
|
| - switch (fullName) {
|
| - // TODO(ochafik): Test DartTypes directly if possible.
|
| - case "dart.js.JsArray":
|
| - return new ClosureType.array(
|
| - type is InterfaceType && type.typeArguments.length == 1
|
| - ? _closureTypeForDartType(type.typeArguments.single)
|
| - : null);
|
| - case "dart.js.JsObject":
|
| - return new ClosureType.map();
|
| - case "dart.js.JsFunction":
|
| - return new ClosureType.function();
|
| - default:
|
| - return new ClosureType.type(getQualifiedName(classElement));
|
| - }
|
| - }
|
| -
|
| - ClosureType _closureTypeForDartType(DartType type,
|
| - {bool forceTypeDefExpansion: false}) {
|
| - if (type == null || type.isBottom || type.isDynamic) {
|
| - return new ClosureType.unknown();
|
| - }
|
| - if (type.isVoid) return null;
|
| - if (type is FunctionType) {
|
| - if (!forceTypeDefExpansion && type.element.name != '') {
|
| - return new ClosureType.type(getQualifiedName(type.element));
|
| - }
|
| -
|
| - var args = []
|
| - ..addAll(type.normalParameterTypes.map(_closureTypeForDartType))
|
| - ..addAll(type.optionalParameterTypes
|
| - .map((t) => _closureTypeForDartType(t).toOptional()));
|
| - if (type.namedParameterTypes.isNotEmpty) {
|
| - var namedArgs = <String, ClosureType>{};
|
| - type.namedParameterTypes.forEach((n, t) {
|
| - namedArgs[n] = _closureTypeForDartType(t).orUndefined();
|
| - });
|
| - args.add(new ClosureType.record(namedArgs).toOptional());
|
| - }
|
| - return new ClosureType.function(
|
| - args, _closureTypeForDartType(type.returnType));
|
| - }
|
| - if (type is InterfaceType) {
|
| - return _closureTypeForClass(type.element, type);
|
| - }
|
| - return new ClosureType.unknown();
|
| - }
|
| -
|
| - /// TODO(ochafik): Use a package-and-file-uri-dependent naming, since libraries can collide.
|
| - String _getFullName(ClassElement type) =>
|
| - type.library.name == '' ? type.name : '${type.library.name}.${type.name}';
|
| }
|
|
|