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 dart2js.resolution.types; | 5 library dart2js.resolution.types; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart' show Resolution; | 8 import '../common/resolution.dart' show Resolution; |
9 import '../elements/resolution_types.dart'; | 9 import '../elements/resolution_types.dart'; |
10 import '../elements/elements.dart' | 10 import '../elements/elements.dart' |
11 show | 11 show |
12 AmbiguousElement, | 12 AmbiguousElement, |
13 ClassElement, | 13 ClassElement, |
14 Element, | 14 Element, |
15 Elements, | 15 Elements, |
16 ErroneousElement, | 16 ErroneousElement, |
17 PrefixElement, | 17 PrefixElement, |
18 TypedefElement, | 18 TypedefElement, |
19 TypeVariableElement; | 19 TypeVariableElement; |
20 import '../elements/modelx.dart' show ErroneousElementX; | 20 import '../elements/modelx.dart' show ErroneousElementX; |
21 import '../resolution/resolution.dart'; | 21 import '../resolution/resolution.dart'; |
22 import '../tree/tree.dart'; | 22 import '../tree/tree.dart'; |
23 import '../universe/feature.dart' show Feature; | 23 import '../universe/feature.dart' show Feature; |
24 import '../util/util.dart' show Link; | 24 import '../util/util.dart' show Link; |
25 import 'members.dart' show lookupInScope; | 25 import 'members.dart' show lookupInScope; |
26 import 'registry.dart' show ResolutionRegistry; | 26 import 'registry.dart' show ResolutionRegistry; |
27 import 'resolution_common.dart' show MappingVisitor; | 27 import 'resolution_common.dart' show MappingVisitor; |
28 import 'scope.dart' show Scope; | 28 import 'scope.dart' show Scope; |
29 | 29 |
| 30 class _FormalsTypeResolutionResult { |
| 31 final List<ResolutionDartType> requiredTypes; |
| 32 final List<ResolutionDartType> orderedTypes; |
| 33 final List<String> names; |
| 34 final List<ResolutionDartType> nameTypes; |
| 35 |
| 36 _FormalsTypeResolutionResult( |
| 37 this.requiredTypes, this.orderedTypes, this.names, this.nameTypes); |
| 38 } |
| 39 |
30 class TypeResolver { | 40 class TypeResolver { |
31 final Resolution resolution; | 41 final Resolution resolution; |
32 | 42 |
33 TypeResolver(this.resolution); | 43 TypeResolver(this.resolution); |
34 | 44 |
35 ResolverTask get resolver => resolution.resolver; | 45 ResolverTask get resolver => resolution.resolver; |
36 DiagnosticReporter get reporter => resolution.reporter; | 46 DiagnosticReporter get reporter => resolution.reporter; |
37 Types get types => resolution.types; | 47 Types get types => resolution.types; |
38 | 48 |
39 /// Tries to resolve the type name as an element. | 49 /// Tries to resolve the type name as an element. |
(...skipping 19 matching lines...) Expand all Loading... |
59 } | 69 } |
60 } else { | 70 } else { |
61 element = lookupInScope(reporter, typeName, scope, typeName.source); | 71 element = lookupInScope(reporter, typeName, scope, typeName.source); |
62 } | 72 } |
63 return element; | 73 return element; |
64 } | 74 } |
65 | 75 |
66 ResolutionDartType resolveTypeAnnotation( | 76 ResolutionDartType resolveTypeAnnotation( |
67 MappingVisitor visitor, TypeAnnotation node, | 77 MappingVisitor visitor, TypeAnnotation node, |
68 {bool malformedIsError: false, bool deferredIsMalformed: true}) { | 78 {bool malformedIsError: false, bool deferredIsMalformed: true}) { |
| 79 return _resolveTypeAnnotation( |
| 80 visitor, node, const [], malformedIsError: malformedIsError, |
| 81 deferredIsMalformed: deferredIsMalformed); |
| 82 } |
| 83 |
| 84 // TODO(floitsch): the [visibleTypeParameterNames] is a hack to put |
| 85 // type parameters in scope for the nested types. |
| 86 // |
| 87 // For example, in the following example, the generic type "A" would be stored |
| 88 // in `visibleTypeParameterNames`. |
| 89 // `typedef F = Function(List<A> Function<A>(A x))`. |
| 90 // |
| 91 // They are resolved to `dynamic` until dart2js supports generic methods. |
| 92 ResolutionDartType _resolveTypeAnnotation( |
| 93 MappingVisitor visitor, TypeAnnotation node, |
| 94 List<List<String>> visibleTypeParameterNames, |
| 95 {bool malformedIsError: false, bool deferredIsMalformed: true}) { |
| 96 |
| 97 if (node.asNominalTypeAnnotation() != null) { |
| 98 return resolveNominalTypeAnnotation( |
| 99 visitor, node, |
| 100 visibleTypeParameterNames, |
| 101 malformedIsError: malformedIsError, |
| 102 deferredIsMalformed: deferredIsMalformed); |
| 103 } |
| 104 assert(node.asFunctionTypeAnnotation() != null); |
| 105 return _resolveFunctionTypeAnnotation( |
| 106 visitor, node, visibleTypeParameterNames, |
| 107 malformedIsError: malformedIsError, |
| 108 deferredIsMalformed: deferredIsMalformed); |
| 109 } |
| 110 |
| 111 /// Resolves the types of a parameter list. |
| 112 /// |
| 113 /// This function does not accept "inline" function types. For example |
| 114 /// `foo(int bar(String x))` is not accepted. |
| 115 /// |
| 116 /// However, it does work with nested generalized function types: |
| 117 /// `foo(int Function(String) x)`. |
| 118 _FormalsTypeResolutionResult _resolveFormalTypes( |
| 119 MappingVisitor visitor, NodeList formals, |
| 120 List<List<String>> visibleTypeParameterNames) { |
| 121 |
| 122 ResolutionDartType resolvePositionalType(VariableDefinitions node) { |
| 123 return _resolveTypeAnnotation( |
| 124 visitor, node.type, visibleTypeParameterNames); |
| 125 } |
| 126 |
| 127 void fillNamedTypes(NodeList namedFormals, |
| 128 List<String> names, List<ResolutionDartType> types) { |
| 129 List<Node> nodes = namedFormals.nodes.toList(growable: false); |
| 130 |
| 131 // Sort the named arguments first. |
| 132 nodes.sort((node1, node2) { |
| 133 VariableDefinitions a = node1; |
| 134 VariableDefinitions b = node2; |
| 135 assert(a.definitions.nodes.tail.isEmpty); |
| 136 assert(b.definitions.nodes.tail.isEmpty); |
| 137 return a.definitions.nodes.head.asIdentifier().source.compareTo( |
| 138 b.definitions.nodes.head.asIdentifier().source); |
| 139 }); |
| 140 |
| 141 for (VariableDefinitions node in nodes) { |
| 142 String name = node.definitions.nodes.head.asIdentifier().source; |
| 143 ResolutionDartType type = node.type == null |
| 144 ? const ResolutionDynamicType() |
| 145 : _resolveTypeAnnotation( |
| 146 visitor, node.type, visibleTypeParameterNames); |
| 147 names.add(name); |
| 148 types.add(type); |
| 149 } |
| 150 } |
| 151 |
| 152 List<ResolutionDartType> requiredTypes = <ResolutionDartType>[]; |
| 153 NodeList optionalFormals = null; |
| 154 for (Link<Node> link = formals.nodes; !link.isEmpty; link = link.tail) { |
| 155 if (link.tail.isEmpty && link.head is NodeList) { |
| 156 optionalFormals = link.head; |
| 157 break; |
| 158 } |
| 159 requiredTypes.add(resolvePositionalType(link.head)); |
| 160 } |
| 161 |
| 162 |
| 163 List<ResolutionDartType> orderedTypes = const <ResolutionDartType>[]; |
| 164 List<String> names = const <String>[]; |
| 165 List<ResolutionDartType> namedTypes = const <ResolutionDartType>[]; |
| 166 |
| 167 if (optionalFormals != null) { |
| 168 // This must be a list of optional arguments. |
| 169 String value = optionalFormals.beginToken.stringValue; |
| 170 if ((!identical(value, '[')) && (!identical(value, '{'))) { |
| 171 reporter.internalError(optionalFormals, "expected optional parameters"); |
| 172 } |
| 173 bool optionalParametersAreNamed = (identical(value, '{')); |
| 174 |
| 175 if (optionalParametersAreNamed) { |
| 176 names = <String>[]; |
| 177 namedTypes = <ResolutionDartType>[]; |
| 178 fillNamedTypes(optionalFormals, names, namedTypes); |
| 179 } else { |
| 180 orderedTypes = <ResolutionDartType>[]; |
| 181 for (Link<Node> link = optionalFormals.nodes; |
| 182 !link.isEmpty; |
| 183 link = link.tail) { |
| 184 orderedTypes.add(resolvePositionalType(link.head)); |
| 185 } |
| 186 } |
| 187 } |
| 188 return new _FormalsTypeResolutionResult( |
| 189 requiredTypes, orderedTypes, names, namedTypes); |
| 190 } |
| 191 |
| 192 ResolutionFunctionType _resolveFunctionTypeAnnotation(MappingVisitor visitor, |
| 193 FunctionTypeAnnotation node, |
| 194 List<List<String>> visibleTypeParameterNames, |
| 195 {bool malformedIsError: false, bool deferredIsMalformed: true}) { |
| 196 |
| 197 assert(visibleTypeParameterNames != null); |
| 198 |
| 199 if (node.typeParameters != null) { |
| 200 List<String> newTypeNames = node.typeParameters.map((TypeVariable node) { |
| 201 return node.name.asIdentifier().source; |
| 202 }).toList(); |
| 203 visibleTypeParameterNames = |
| 204 visibleTypeParameterNames.toList()..add(newTypeNames); |
| 205 } |
| 206 |
| 207 ResolutionDartType returnType = node.returnType == null |
| 208 ? const ResolutionDynamicType() |
| 209 : _resolveTypeAnnotation(visitor, node.returnType, |
| 210 visibleTypeParameterNames); |
| 211 var formalTypes = |
| 212 _resolveFormalTypes(visitor, node.formals, visibleTypeParameterNames); |
| 213 var result = new ResolutionFunctionType.generalized( |
| 214 returnType, |
| 215 formalTypes.requiredTypes, |
| 216 formalTypes.orderedTypes, |
| 217 formalTypes.names, |
| 218 formalTypes.nameTypes); |
| 219 visitor.registry.useType(node, result); |
| 220 return result; |
| 221 } |
| 222 |
| 223 ResolutionDartType resolveNominalTypeAnnotation(MappingVisitor visitor, |
| 224 NominalTypeAnnotation node, |
| 225 List<List<String>> visibleTypeParameterNames, |
| 226 {bool malformedIsError: false, bool deferredIsMalformed: true}) { |
69 ResolutionRegistry registry = visitor.registry; | 227 ResolutionRegistry registry = visitor.registry; |
70 | 228 |
71 Identifier typeName; | 229 Identifier typeName; |
72 ResolutionDartType type; | 230 ResolutionDartType type; |
73 | 231 |
74 ResolutionDartType checkNoTypeArguments(ResolutionDartType type) { | 232 ResolutionDartType checkNoTypeArguments(ResolutionDartType type) { |
75 List<ResolutionDartType> arguments = new List<ResolutionDartType>(); | 233 List<ResolutionDartType> arguments = new List<ResolutionDartType>(); |
76 bool hasTypeArgumentMismatch = resolveTypeArguments( | 234 bool hasTypeArgumentMismatch = resolveTypeArguments( |
77 visitor, node, const <ResolutionDartType>[], arguments); | 235 visitor, node, const <ResolutionDartType>[], arguments, |
| 236 visibleTypeParameterNames); |
78 if (hasTypeArgumentMismatch) { | 237 if (hasTypeArgumentMismatch) { |
79 return new MalformedType( | 238 return new MalformedType( |
80 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 239 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
81 {'type': node}, typeName.source, visitor.enclosingElement), | 240 {'type': node}, typeName.source, visitor.enclosingElement), |
82 type, | 241 type, |
83 arguments); | 242 arguments); |
84 } | 243 } |
85 return type; | 244 return type; |
86 } | 245 } |
87 | 246 |
(...skipping 11 matching lines...) Expand all Loading... |
99 registry.useType(node, type); | 258 registry.useType(node, type); |
100 return type; | 259 return type; |
101 } else if (identical(typeName.source, 'dynamic')) { | 260 } else if (identical(typeName.source, 'dynamic')) { |
102 type = const ResolutionDynamicType(); | 261 type = const ResolutionDynamicType(); |
103 checkNoTypeArguments(type); | 262 checkNoTypeArguments(type); |
104 registry.useType(node, type); | 263 registry.useType(node, type); |
105 return type; | 264 return type; |
106 } | 265 } |
107 } | 266 } |
108 | 267 |
109 Element element = resolveTypeName(prefixName, typeName, visitor.scope, | |
110 deferredIsMalformed: deferredIsMalformed); | |
111 | |
112 ResolutionDartType reportFailureAndCreateType( | 268 ResolutionDartType reportFailureAndCreateType( |
113 MessageKind messageKind, Map messageArguments, | 269 MessageKind messageKind, Map messageArguments, |
114 {ResolutionDartType userProvidedBadType, | 270 {ResolutionDartType userProvidedBadType, |
115 Element erroneousElement, | 271 Element erroneousElement, |
116 List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) { | 272 List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) { |
117 if (malformedIsError) { | 273 if (malformedIsError) { |
118 reporter.reportError( | 274 reporter.reportError( |
119 reporter.createMessage(node, messageKind, messageArguments), infos); | 275 reporter.createMessage(node, messageKind, messageArguments), infos); |
120 } else { | 276 } else { |
121 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); | 277 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); |
122 reporter.reportWarning( | 278 reporter.reportWarning( |
123 reporter.createMessage(node, messageKind, messageArguments), infos); | 279 reporter.createMessage(node, messageKind, messageArguments), infos); |
124 } | 280 } |
125 if (erroneousElement == null) { | 281 if (erroneousElement == null) { |
126 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); | 282 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); |
127 erroneousElement = new ErroneousElementX(messageKind, messageArguments, | 283 erroneousElement = new ErroneousElementX(messageKind, messageArguments, |
128 typeName.source, visitor.enclosingElement); | 284 typeName.source, visitor.enclosingElement); |
129 } | 285 } |
130 List<ResolutionDartType> arguments = <ResolutionDartType>[]; | 286 List<ResolutionDartType> arguments = <ResolutionDartType>[]; |
131 resolveTypeArguments( | 287 resolveTypeArguments(visitor, node, const <ResolutionDartType>[], |
132 visitor, node, const <ResolutionDartType>[], arguments); | 288 arguments, visibleTypeParameterNames); |
133 return new MalformedType( | 289 return new MalformedType( |
134 erroneousElement, userProvidedBadType, arguments); | 290 erroneousElement, userProvidedBadType, arguments); |
135 } | 291 } |
136 | 292 |
| 293 Element element; |
| 294 // Resolve references to type names as dynamic. |
| 295 // TODO(floitsch): this hackishly resolves generic function type arguments |
| 296 // to dynamic. |
| 297 if (prefixName == null && |
| 298 visibleTypeParameterNames.any((n) => n.contains(typeName.source))) { |
| 299 type = const ResolutionDynamicType(); |
| 300 } else { |
| 301 element = resolveTypeName(prefixName, typeName, visitor.scope, |
| 302 deferredIsMalformed: deferredIsMalformed); |
| 303 } |
| 304 |
137 // Try to construct the type from the element. | 305 // Try to construct the type from the element. |
138 if (element == null) { | 306 if (type != null) { |
| 307 // Already assigned to through the visibleTypeParameterNames. |
| 308 // Just make sure that it doesn't have type arguments. |
| 309 if (node.typeArguments != null) { |
| 310 reporter.reportWarningMessage(node.typeArguments.nodes.head, |
| 311 MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
| 312 } |
| 313 } else if (element == null) { |
139 type = reportFailureAndCreateType( | 314 type = reportFailureAndCreateType( |
140 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 315 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
141 } else if (element.isAmbiguous) { | 316 } else if (element.isAmbiguous) { |
142 AmbiguousElement ambiguous = element; | 317 AmbiguousElement ambiguous = element; |
143 type = reportFailureAndCreateType( | 318 type = reportFailureAndCreateType( |
144 ambiguous.messageKind, ambiguous.messageArguments, | 319 ambiguous.messageKind, ambiguous.messageArguments, |
145 infos: ambiguous.computeInfos( | 320 infos: ambiguous.computeInfos( |
146 registry.mapping.analyzedElement, reporter)); | 321 registry.mapping.analyzedElement, reporter)); |
147 ; | 322 ; |
148 } else if (element.isMalformed) { | 323 } else if (element.isMalformed) { |
(...skipping 14 matching lines...) Expand all Loading... |
163 return type; | 338 return type; |
164 } else { | 339 } else { |
165 bool addTypeVariableBoundsCheck = false; | 340 bool addTypeVariableBoundsCheck = false; |
166 if (element.isClass) { | 341 if (element.isClass) { |
167 ClassElement cls = element; | 342 ClassElement cls = element; |
168 // TODO(johnniwinther): [ensureClassWillBeResolvedInternal] should imply | 343 // TODO(johnniwinther): [ensureClassWillBeResolvedInternal] should imply |
169 // [computeType]. | 344 // [computeType]. |
170 resolver.ensureClassWillBeResolvedInternal(cls); | 345 resolver.ensureClassWillBeResolvedInternal(cls); |
171 cls.computeType(resolution); | 346 cls.computeType(resolution); |
172 List<ResolutionDartType> arguments = <ResolutionDartType>[]; | 347 List<ResolutionDartType> arguments = <ResolutionDartType>[]; |
173 bool hasTypeArgumentMismatch = | 348 bool hasTypeArgumentMismatch = resolveTypeArguments( |
174 resolveTypeArguments(visitor, node, cls.typeVariables, arguments); | 349 visitor, node, cls.typeVariables, arguments, |
| 350 visibleTypeParameterNames); |
175 if (hasTypeArgumentMismatch) { | 351 if (hasTypeArgumentMismatch) { |
176 type = new BadInterfaceType( | 352 type = new BadInterfaceType( |
177 cls.declaration, | 353 cls.declaration, |
178 new ResolutionInterfaceType.forUserProvidedBadType( | 354 new ResolutionInterfaceType.forUserProvidedBadType( |
179 cls.declaration, arguments)); | 355 cls.declaration, arguments)); |
180 } else { | 356 } else { |
181 if (arguments.isEmpty) { | 357 if (arguments.isEmpty) { |
182 type = cls.rawType; | 358 type = cls.rawType; |
183 } else { | 359 } else { |
184 type = new ResolutionInterfaceType( | 360 type = new ResolutionInterfaceType( |
185 cls.declaration, arguments.toList(growable: false)); | 361 cls.declaration, arguments.toList(growable: false)); |
186 addTypeVariableBoundsCheck = | 362 addTypeVariableBoundsCheck = |
187 arguments.any((ResolutionDartType type) => !type.isDynamic); | 363 arguments.any((ResolutionDartType type) => !type.isDynamic); |
188 } | 364 } |
189 } | 365 } |
190 } else if (element.isTypedef) { | 366 } else if (element.isTypedef) { |
191 TypedefElement typdef = element; | 367 TypedefElement typdef = element; |
192 // TODO(johnniwinther): [ensureResolved] should imply [computeType]. | 368 // TODO(johnniwinther): [ensureResolved] should imply [computeType]. |
193 typdef.ensureResolved(resolution); | 369 typdef.ensureResolved(resolution); |
194 typdef.computeType(resolution); | 370 typdef.computeType(resolution); |
195 List<ResolutionDartType> arguments = <ResolutionDartType>[]; | 371 List<ResolutionDartType> arguments = <ResolutionDartType>[]; |
196 bool hasTypeArgumentMismatch = resolveTypeArguments( | 372 bool hasTypeArgumentMismatch = resolveTypeArguments( |
197 visitor, node, typdef.typeVariables, arguments); | 373 visitor, node, typdef.typeVariables, arguments, |
| 374 visibleTypeParameterNames); |
198 if (hasTypeArgumentMismatch) { | 375 if (hasTypeArgumentMismatch) { |
199 type = new BadTypedefType( | 376 type = new BadTypedefType( |
200 typdef, | 377 typdef, |
201 new ResolutionTypedefType.forUserProvidedBadType( | 378 new ResolutionTypedefType.forUserProvidedBadType( |
202 typdef, arguments)); | 379 typdef, arguments)); |
203 } else { | 380 } else { |
204 if (arguments.isEmpty) { | 381 if (arguments.isEmpty) { |
205 type = typdef.rawType; | 382 type = typdef.rawType; |
206 } else { | 383 } else { |
207 type = new ResolutionTypedefType( | 384 type = new ResolutionTypedefType( |
(...skipping 26 matching lines...) Expand all Loading... |
234 if (addTypeVariableBoundsCheck) { | 411 if (addTypeVariableBoundsCheck) { |
235 visitor.addDeferredAction(visitor.enclosingElement, | 412 visitor.addDeferredAction(visitor.enclosingElement, |
236 () => checkTypeVariableBounds(node, type)); | 413 () => checkTypeVariableBounds(node, type)); |
237 } | 414 } |
238 } | 415 } |
239 registry.useType(node, type); | 416 registry.useType(node, type); |
240 return type; | 417 return type; |
241 } | 418 } |
242 | 419 |
243 /// Checks the type arguments of [type] against the type variable bounds. | 420 /// Checks the type arguments of [type] against the type variable bounds. |
244 void checkTypeVariableBounds(TypeAnnotation node, GenericType type) { | 421 void checkTypeVariableBounds(NominalTypeAnnotation node, GenericType type) { |
245 void checkTypeVariableBound(_, ResolutionDartType typeArgument, | 422 void checkTypeVariableBound(_, ResolutionDartType typeArgument, |
246 ResolutionTypeVariableType typeVariable, ResolutionDartType bound) { | 423 ResolutionTypeVariableType typeVariable, ResolutionDartType bound) { |
247 if (!types.isSubtype(typeArgument, bound)) { | 424 if (!types.isSubtype(typeArgument, bound)) { |
248 reporter.reportWarningMessage( | 425 reporter.reportWarningMessage( |
249 node, MessageKind.INVALID_TYPE_VARIABLE_BOUND, { | 426 node, MessageKind.INVALID_TYPE_VARIABLE_BOUND, { |
250 'typeVariable': typeVariable, | 427 'typeVariable': typeVariable, |
251 'bound': bound, | 428 'bound': bound, |
252 'typeArgument': typeArgument, | 429 'typeArgument': typeArgument, |
253 'thisType': type.element.thisType | 430 'thisType': type.element.thisType |
254 }); | 431 }); |
255 } | 432 } |
256 } | 433 } |
257 | 434 |
258 types.checkTypeVariableBounds(type, checkTypeVariableBound); | 435 types.checkTypeVariableBounds(type, checkTypeVariableBound); |
259 } | 436 } |
260 | 437 |
261 /** | 438 /** |
262 * Resolves the type arguments of [node] and adds these to [arguments]. | 439 * Resolves the type arguments of [node] and adds these to [arguments]. |
263 * | 440 * |
264 * Returns [: true :] if the number of type arguments did not match the | 441 * Returns [: true :] if the number of type arguments did not match the |
265 * number of type variables. | 442 * number of type variables. |
266 */ | 443 */ |
267 bool resolveTypeArguments( | 444 bool resolveTypeArguments( |
268 MappingVisitor visitor, | 445 MappingVisitor visitor, |
269 TypeAnnotation node, | 446 NominalTypeAnnotation node, |
270 List<ResolutionDartType> typeVariables, | 447 List<ResolutionDartType> typeVariables, |
271 List<ResolutionDartType> arguments) { | 448 List<ResolutionDartType> arguments, |
| 449 List<List<String>> visibleTypeParameterNames) { |
272 if (node.typeArguments == null) { | 450 if (node.typeArguments == null) { |
273 return false; | 451 return false; |
274 } | 452 } |
275 int expectedVariables = typeVariables.length; | 453 int expectedVariables = typeVariables.length; |
276 int index = 0; | 454 int index = 0; |
277 bool typeArgumentCountMismatch = false; | 455 bool typeArgumentCountMismatch = false; |
278 for (Link<Node> typeArguments = node.typeArguments.nodes; | 456 for (Link<Node> typeArguments = node.typeArguments.nodes; |
279 !typeArguments.isEmpty; | 457 !typeArguments.isEmpty; |
280 typeArguments = typeArguments.tail, index++) { | 458 typeArguments = typeArguments.tail, index++) { |
281 if (index > expectedVariables - 1) { | 459 if (index > expectedVariables - 1) { |
282 reporter.reportWarningMessage( | 460 reporter.reportWarningMessage( |
283 typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 461 typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
284 typeArgumentCountMismatch = true; | 462 typeArgumentCountMismatch = true; |
285 } | 463 } |
286 ResolutionDartType argType = | 464 ResolutionDartType argType = _resolveTypeAnnotation( |
287 resolveTypeAnnotation(visitor, typeArguments.head); | 465 visitor, typeArguments.head, visibleTypeParameterNames); |
288 // TODO(karlklose): rewrite to not modify [arguments]. | 466 // TODO(karlklose): rewrite to not modify [arguments]. |
289 arguments.add(argType); | 467 arguments.add(argType); |
290 } | 468 } |
291 if (index < expectedVariables) { | 469 if (index < expectedVariables) { |
292 reporter.reportWarningMessage( | 470 reporter.reportWarningMessage( |
293 node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | 471 node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); |
294 typeArgumentCountMismatch = true; | 472 typeArgumentCountMismatch = true; |
295 } | 473 } |
296 return typeArgumentCountMismatch; | 474 return typeArgumentCountMismatch; |
297 } | 475 } |
298 } | 476 } |
OLD | NEW |