Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: lib/src/closure/closure_annotator.dart

Issue 1676463002: Type annotations instead of closure comments. (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 import 'package:analyzer/analyzer.dart' show ParameterKind; 5 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
6 import 'package:analyzer/src/generated/element.dart'; 6 import 'package:analyzer/src/generated/element.dart';
7 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; 7 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
8 8
9 import '../js/js_ast.dart' as JS show Node, Expression, TypeRef;
10
9 import 'closure_annotation.dart'; 11 import 'closure_annotation.dart';
10 import 'closure_type.dart';
11 12
12 /// Mixin that can generate [ClosureAnnotation]s for Dart elements and types. 13 /// Mixin that can generate [ClosureAnnotation]s for Dart elements and types.
13 abstract class ClosureAnnotator { 14 abstract class ClosureAnnotator {
14 TypeProvider get types; 15 TypeProvider get types;
15 16
16 /// Must return a JavaScript qualified name that can be used to refer to [type ]. 17 JS.TypeRef emitTypeRef(DartType type);
17 String getQualifiedName(TypeDefiningElement type);
18
19 ClosureAnnotation closureAnnotationForVariable(VariableElement e) =>
20 new ClosureAnnotation(
21 type: _closureTypeForDartType(e.type),
22 // Note: we don't set isConst here because Closure's constness and
23 // Dart's are not really compatible.
24 isFinal: e.isFinal || e.isConst);
25
26 /// We don't use Closure's `@typedef` annotations
27 ClosureAnnotation closureAnnotationForTypeDef(FunctionTypeAliasElement e) =>
28 new ClosureAnnotation(
29 type: _closureTypeForDartType(e.type, forceTypeDefExpansion: true),
30 isTypedef: true);
31
32 ClosureAnnotation closureAnnotationForDefaultConstructor(ClassElement e) =>
33 new ClosureAnnotation(
34 superType: _closureTypeForDartType(e.supertype),
35 interfaces: e.interfaces.map(_closureTypeForDartType).toList());
36 18
37 // TODO(ochafik): Handle destructured params when Closure supports it. 19 // TODO(ochafik): Handle destructured params when Closure supports it.
38 ClosureAnnotation closureAnnotationFor( 20 ClosureAnnotation closureAnnotationFor(
39 ExecutableElement e, String namedArgsMapName) { 21 JS.Node node, AstNode original, Element e, String namedArgsMapName) {
40 var paramTypes = <String, ClosureType>{}; 22 String comment;
41 var namedArgs = <String, ClosureType>{}; 23 if (original is AnnotatedNode && original.documentationComment != null) {
42 for (var param in e.parameters) { 24 comment = original.documentationComment.toSource();
43 var t = _closureTypeForDartType(param.type);
44 switch (param.parameterKind) {
45 case ParameterKind.NAMED:
46 namedArgs[param.name] = t.orUndefined();
47 break;
48 case ParameterKind.POSITIONAL:
49 paramTypes[param.name] = t.toOptional();
50 break;
51 case ParameterKind.REQUIRED:
52 paramTypes[param.name] = t;
53 break;
54 }
55 } 25 }
56 if (namedArgs.isNotEmpty) { 26 // Note: Dart and Closure privacy are not compatible: don't set `isPrivate: e.isPrivate`.
57 paramTypes[namedArgsMapName] =
58 new ClosureType.record(namedArgs).toOptional();
59 }
60
61 var returnType = e is ConstructorElement
62 ? (e.isFactory ? _closureTypeForClass(e.enclosingElement) : null)
63 : _closureTypeForDartType(e.returnType);
64
65 return new ClosureAnnotation( 27 return new ClosureAnnotation(
28 comment: comment,
29 // Note: we don't set isConst here because Closure's constness and
30 // Dart's are not really compatible.
31 isFinal: e is VariableElement && (e.isFinal || e.isConst),
32 type: e is VariableElement
33 ? emitTypeRef(e.type /*, forceTypeDefExpansion: true*/)
34 : null,
35 superType: e is ClassElement ? emitTypeRef(e.supertype) : null,
36 interfaces:
37 e is ClassElement ? e.interfaces.map(emitTypeRef).toList() : null,
66 isOverride: e.isOverride, 38 isOverride: e.isOverride,
67 // Note: Dart and Closure privacy are not compatible: don't set `isPriva te: e.isPrivate`. 39 isTypedef: e is FunctionTypeAliasElement);
68 paramTypes: paramTypes,
69 returnType: returnType);
70 } 40 }
71
72 Map<DartType, ClosureType> __commonTypes;
73 Map<DartType, ClosureType> get _commonTypes {
74 if (__commonTypes == null) {
75 var numberType = new ClosureType.number().toNullable();
76 __commonTypes = {
77 types.intType: numberType,
78 types.numType: numberType,
79 types.doubleType: numberType,
80 types.boolType: new ClosureType.boolean().toNullable(),
81 types.stringType: new ClosureType.string(),
82 };
83 }
84 return __commonTypes;
85 }
86
87 ClosureType _closureTypeForClass(ClassElement classElement, [DartType type]) {
88 ClosureType closureType = _commonTypes[type];
89 if (closureType != null) return closureType;
90
91 var fullName = _getFullName(classElement);
92 switch (fullName) {
93 // TODO(ochafik): Test DartTypes directly if possible.
94 case "dart.js.JsArray":
95 return new ClosureType.array(
96 type is InterfaceType && type.typeArguments.length == 1
97 ? _closureTypeForDartType(type.typeArguments.single)
98 : null);
99 case "dart.js.JsObject":
100 return new ClosureType.map();
101 case "dart.js.JsFunction":
102 return new ClosureType.function();
103 default:
104 return new ClosureType.type(getQualifiedName(classElement));
105 }
106 }
107
108 ClosureType _closureTypeForDartType(DartType type,
109 {bool forceTypeDefExpansion: false}) {
110 if (type == null || type.isBottom || type.isDynamic) {
111 return new ClosureType.unknown();
112 }
113 if (type.isVoid) return null;
114 if (type is FunctionType) {
115 if (!forceTypeDefExpansion && type.element.name != '') {
116 return new ClosureType.type(getQualifiedName(type.element));
117 }
118
119 var args = []
120 ..addAll(type.normalParameterTypes.map(_closureTypeForDartType))
121 ..addAll(type.optionalParameterTypes
122 .map((t) => _closureTypeForDartType(t).toOptional()));
123 if (type.namedParameterTypes.isNotEmpty) {
124 var namedArgs = <String, ClosureType>{};
125 type.namedParameterTypes.forEach((n, t) {
126 namedArgs[n] = _closureTypeForDartType(t).orUndefined();
127 });
128 args.add(new ClosureType.record(namedArgs).toOptional());
129 }
130 return new ClosureType.function(
131 args, _closureTypeForDartType(type.returnType));
132 }
133 if (type is InterfaceType) {
134 return _closureTypeForClass(type.element, type);
135 }
136 return new ClosureType.unknown();
137 }
138
139 /// TODO(ochafik): Use a package-and-file-uri-dependent naming, since librarie s can collide.
140 String _getFullName(ClassElement type) =>
141 type.library.name == '' ? type.name : '${type.library.name}.${type.name}';
142 } 41 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698