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 import 'closure_type.dart'; | 5 import '../js/js_ast.dart' as JS show TypeRef, JsTypeRef, ClosureTypePrinter; |
6 | 6 |
7 /// Set of closure annotations that can be [toString]ed to a single JsDoc commen
t. | 7 /// Set of closure annotations that can be [toString]ed to a single JsDoc commen
t. |
8 /// See https://developers.google.com/closure/compiler/docs/js-for-compiler | 8 /// See https://developers.google.com/closure/compiler/docs/js-for-compiler |
9 /// | 9 /// |
10 /// TODO(ochafik): Support inclusion of 'normal' comments (including @param comm
ents). | 10 /// TODO(ochafik): Support inclusion of 'normal' comments (including @param comm
ents). |
11 class ClosureAnnotation { | 11 class ClosureAnnotation { |
| 12 final String comment; |
12 final bool isConst; | 13 final bool isConst; |
13 final bool isConstructor; | 14 final bool isConstructor; |
14 final bool isFinal; | 15 final bool isFinal; |
15 final bool isNoCollapse; | 16 final bool isNoCollapse; |
16 final bool isNoSideEffects; | 17 final bool isNoSideEffects; |
17 final bool isOverride; | 18 final bool isOverride; |
18 final bool isPrivate; | 19 final bool isPrivate; |
19 final bool isProtected; | 20 final bool isProtected; |
20 final bool isStruct; | 21 final bool isStruct; |
21 final bool isTypedef; | 22 final bool isTypedef; |
22 final ClosureType lendsToType; | 23 final JS.TypeRef lendsToType; |
23 final ClosureType returnType; | 24 final JS.TypeRef returnType; |
24 final ClosureType superType; | 25 final JS.TypeRef superType; |
25 final ClosureType thisType; | 26 final JS.TypeRef thisType; |
26 final ClosureType throwsType; | 27 final JS.TypeRef throwsType; |
27 final ClosureType type; | 28 final JS.TypeRef type; |
28 final List<ClosureType> interfaces; | 29 final List<JS.TypeRef> interfaces; |
29 final List<String> templates; | 30 final List<String> templates; |
30 final Map<String, ClosureType> paramTypes; | 31 final Map<String, JS.TypeRef> paramTypes; |
31 | 32 |
32 ClosureAnnotation( | 33 ClosureAnnotation( |
33 {this.interfaces: const [], | 34 {this.comment, |
| 35 this.interfaces: const [], |
34 this.isConst: false, | 36 this.isConst: false, |
35 this.isConstructor: false, | 37 this.isConstructor: false, |
36 this.isFinal: false, | 38 this.isFinal: false, |
37 this.isNoCollapse: false, | 39 this.isNoCollapse: false, |
38 this.isNoSideEffects: false, | 40 this.isNoSideEffects: false, |
39 this.isOverride: false, | 41 this.isOverride: false, |
40 this.isPrivate: false, | 42 this.isPrivate: false, |
41 this.isProtected: false, | 43 this.isProtected: false, |
42 this.isStruct: false, | 44 this.isStruct: false, |
43 this.isTypedef: false, | 45 this.isTypedef: false, |
(...skipping 10 matching lines...) Expand all Loading... |
54 int get hashCode => _cachedString.hashCode; | 56 int get hashCode => _cachedString.hashCode; |
55 | 57 |
56 @override | 58 @override |
57 bool operator ==(other) => | 59 bool operator ==(other) => |
58 other is ClosureAnnotation && _cachedString == other._cachedString; | 60 other is ClosureAnnotation && _cachedString == other._cachedString; |
59 | 61 |
60 @override | 62 @override |
61 String toString([String indent = '']) => | 63 String toString([String indent = '']) => |
62 _cachedString.replaceAll('\n', '\n$indent'); | 64 _cachedString.replaceAll('\n', '\n$indent'); |
63 | 65 |
| 66 String _print(JS.TypeRef t) => |
| 67 (new JS.ClosureTypePrinter()..visit(t)).toString(); |
| 68 |
64 String __cachedString; | 69 String __cachedString; |
65 String get _cachedString { | 70 String get _cachedString { |
66 if (__cachedString == null) { | 71 if (__cachedString == null) { |
67 bool isNonWildcard(ClosureType t) => | 72 bool isNonWildcard(JS.TypeRef t) => t != null && !t.isAny && !t.isUnknown; |
68 t != null && !t.isAll && !t.isUnknown; | |
69 | 73 |
70 var lines = <String>[]; | 74 var lines = <String>[]; |
| 75 if (comment != null) lines.addAll(comment.split('\n')); |
71 if (templates != null && templates.isNotEmpty) { | 76 if (templates != null && templates.isNotEmpty) { |
72 lines.add('@template ${templates.join(', ')}'); | 77 lines.add('@template ${templates.join(', ')}'); |
73 } | 78 } |
74 if (thisType != null) lines.add('@this {$thisType}'); | 79 if (thisType != null) lines.add('@this {${_print(thisType)}}'); |
75 if (isOverride) lines.add('@override'); | 80 if (isOverride) lines.add('@override'); |
76 if (isNoSideEffects) lines.add('@nosideeffects'); | 81 if (isNoSideEffects) lines.add('@nosideeffects'); |
77 if (isNoCollapse) lines.add('@nocollapse'); | 82 if (isNoCollapse) lines.add('@nocollapse'); |
78 if (lendsToType != null) lines.add('@lends {$lendsToType}'); | 83 if (lendsToType != null) lines.add('@lends {${_print(lendsToType)}}'); |
79 | 84 |
80 { | 85 { |
81 var typeHolders = <String>[]; | 86 var typeHolders = <String>[]; |
82 if (isPrivate) typeHolders.add('@private'); | 87 if (isPrivate) typeHolders.add('@private'); |
83 if (isProtected) typeHolders.add('@protected'); | 88 if (isProtected) typeHolders.add('@protected'); |
84 if (isFinal) typeHolders.add('@final'); | 89 if (isFinal) typeHolders.add('@final'); |
85 if (isConst) typeHolders.add('@const'); | 90 if (isConst) typeHolders.add('@const'); |
86 if (isTypedef) typeHolders.add('@typedef'); | 91 if (isTypedef) typeHolders.add('@typedef'); |
87 if (isNonWildcard(type)) { | 92 if (isNonWildcard(type)) { |
88 if (typeHolders.isEmpty) typeHolders.add('@type'); | 93 if (typeHolders.isEmpty) typeHolders.add('@type'); |
89 typeHolders.add('{$type}'); | 94 typeHolders.add('{${_print(type)}}'); |
90 } | 95 } |
91 if (!typeHolders.isEmpty) lines.add(typeHolders.join(' ')); | 96 if (!typeHolders.isEmpty) lines.add(typeHolders.join(' ')); |
92 } | 97 } |
93 | 98 |
94 { | 99 { |
95 List constructorLine = []; | 100 List constructorLine = []; |
96 if (isConstructor) constructorLine.add('@constructor'); | 101 if (isConstructor) constructorLine.add('@constructor'); |
97 if (isStruct) constructorLine.add('@struct'); | 102 if (isStruct) constructorLine.add('@struct'); |
98 if (isNonWildcard(superType)) { | 103 if (isNonWildcard(superType)) { |
99 constructorLine.add('@extends {$superType}'); | 104 constructorLine.add('@extends {${_print(superType)}}'); |
100 } | 105 } |
101 | 106 |
102 if (constructorLine.isNotEmpty) lines.add(constructorLine.join(' ')); | 107 if (constructorLine.isNotEmpty) lines.add(constructorLine.join(' ')); |
103 } | 108 } |
104 | 109 |
105 for (var interface in interfaces) { | 110 if (interfaces != null) { |
106 if (isNonWildcard(interface)) lines.add('@implements {$interface}'); | 111 for (var interface in interfaces) { |
| 112 if (isNonWildcard(interface)) |
| 113 lines.add('@implements {${_print(interface)}}'); |
| 114 } |
107 } | 115 } |
108 | 116 |
109 paramTypes.forEach((String paramName, ClosureType paramType) { | 117 if (paramTypes != null) { |
110 // Must output params even with wildcard type. | 118 paramTypes.forEach((String paramName, JS.TypeRef paramType) { |
111 lines.add('@param {$paramType} $paramName'); | 119 // Must output params even with wildcard type. |
112 }); | 120 lines.add('@param {${_print(paramType)}} $paramName'); |
113 if (isNonWildcard(returnType)) lines.add('@return {$returnType}'); | 121 }); |
114 if (isNonWildcard(throwsType)) lines.add('@throws {$throwsType}'); | 122 } |
| 123 if (isNonWildcard(returnType)) |
| 124 lines.add('@return {${_print(returnType)}}'); |
| 125 if (isNonWildcard(throwsType)) |
| 126 lines.add('@throws {${_print(throwsType)}}'); |
115 | 127 |
116 if (lines.length == 0) return ''; | 128 if (lines.length == 0) return ''; |
117 if (lines.length == 1) return '/** ${lines.single} */'; | 129 if (lines.length == 1) return '/** ${lines.single} */'; |
118 __cachedString = '/**\n' + lines.map((l) => ' * $l').join('\n') + '\n */'; | 130 __cachedString = '/**\n' + lines.map((l) => ' * $l').join('\n') + '\n */'; |
119 } | 131 } |
120 return __cachedString; | 132 return __cachedString; |
121 } | 133 } |
122 } | 134 } |
OLD | NEW |