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/resolution.dart' show | 7 import '../common/resolution.dart' show |
8 Resolution; | 8 Resolution; |
9 import '../compiler.dart' show | 9 import '../compiler.dart' show |
10 Compiler; | 10 Compiler; |
11 import '../dart_backend/dart_backend.dart' show | 11 import '../dart_backend/dart_backend.dart' show |
12 DartBackend; | 12 DartBackend; |
13 import '../dart_types.dart'; | 13 import '../dart_types.dart'; |
14 import '../diagnostics/diagnostic_listener.dart' show | 14 import '../diagnostics/diagnostic_listener.dart' show |
15 DiagnosticListener, | 15 DiagnosticReporter, |
16 DiagnosticMessage; | 16 DiagnosticMessage; |
17 import '../diagnostics/messages.dart' show | 17 import '../diagnostics/messages.dart' show |
18 MessageKind; | 18 MessageKind; |
19 import '../elements/elements.dart' show | 19 import '../elements/elements.dart' show |
20 AmbiguousElement, | 20 AmbiguousElement, |
21 ClassElement, | 21 ClassElement, |
22 Element, | 22 Element, |
23 Elements, | 23 Elements, |
24 ErroneousElement, | 24 ErroneousElement, |
25 PrefixElement, | 25 PrefixElement, |
(...skipping 12 matching lines...) Expand all Loading... |
38 import 'resolution_common.dart' show | 38 import 'resolution_common.dart' show |
39 MappingVisitor; | 39 MappingVisitor; |
40 import 'scope.dart' show | 40 import 'scope.dart' show |
41 Scope; | 41 Scope; |
42 | 42 |
43 class TypeResolver { | 43 class TypeResolver { |
44 final Compiler compiler; | 44 final Compiler compiler; |
45 | 45 |
46 TypeResolver(this.compiler); | 46 TypeResolver(this.compiler); |
47 | 47 |
48 DiagnosticListener get listener => compiler; | 48 DiagnosticReporter get reporter => compiler.reporter; |
| 49 |
49 Resolution get resolution => compiler.resolution; | 50 Resolution get resolution => compiler.resolution; |
50 | 51 |
51 /// Tries to resolve the type name as an element. | 52 /// Tries to resolve the type name as an element. |
52 Element resolveTypeName(Identifier prefixName, | 53 Element resolveTypeName(Identifier prefixName, |
53 Identifier typeName, | 54 Identifier typeName, |
54 Scope scope, | 55 Scope scope, |
55 {bool deferredIsMalformed: true}) { | 56 {bool deferredIsMalformed: true}) { |
56 Element element; | 57 Element element; |
57 if (prefixName != null) { | 58 if (prefixName != null) { |
58 Element prefixElement = | 59 Element prefixElement = |
59 lookupInScope(compiler, prefixName, scope, prefixName.source); | 60 lookupInScope(reporter, prefixName, scope, prefixName.source); |
60 if (prefixElement != null && prefixElement.isPrefix) { | 61 if (prefixElement != null && prefixElement.isPrefix) { |
61 // The receiver is a prefix. Lookup in the imported members. | 62 // The receiver is a prefix. Lookup in the imported members. |
62 PrefixElement prefix = prefixElement; | 63 PrefixElement prefix = prefixElement; |
63 element = prefix.lookupLocalMember(typeName.source); | 64 element = prefix.lookupLocalMember(typeName.source); |
64 // TODO(17260, sigurdm): The test for DartBackend is there because | 65 // TODO(17260, sigurdm): The test for DartBackend is there because |
65 // dart2dart outputs malformed types with prefix. | 66 // dart2dart outputs malformed types with prefix. |
66 if (element != null && | 67 if (element != null && |
67 prefix.isDeferred && | 68 prefix.isDeferred && |
68 deferredIsMalformed && | 69 deferredIsMalformed && |
69 compiler.backend is! DartBackend) { | 70 compiler.backend is! DartBackend) { |
70 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION, | 71 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION, |
71 {'node': typeName}, | 72 {'node': typeName}, |
72 element.name, | 73 element.name, |
73 element); | 74 element); |
74 } | 75 } |
75 } else { | 76 } else { |
76 // The caller of this method will create the ErroneousElement for | 77 // The caller of this method will create the ErroneousElement for |
77 // the MalformedType. | 78 // the MalformedType. |
78 element = null; | 79 element = null; |
79 } | 80 } |
80 } else { | 81 } else { |
81 element = lookupInScope(compiler, typeName, scope, typeName.source); | 82 element = lookupInScope(reporter, typeName, scope, typeName.source); |
82 } | 83 } |
83 return element; | 84 return element; |
84 } | 85 } |
85 | 86 |
86 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, | 87 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, |
87 {bool malformedIsError: false, | 88 {bool malformedIsError: false, |
88 bool deferredIsMalformed: true}) { | 89 bool deferredIsMalformed: true}) { |
89 ResolutionRegistry registry = visitor.registry; | 90 ResolutionRegistry registry = visitor.registry; |
90 | 91 |
91 Identifier typeName; | 92 Identifier typeName; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 Element element = resolveTypeName(prefixName, typeName, visitor.scope, | 129 Element element = resolveTypeName(prefixName, typeName, visitor.scope, |
129 deferredIsMalformed: deferredIsMalformed); | 130 deferredIsMalformed: deferredIsMalformed); |
130 | 131 |
131 DartType reportFailureAndCreateType( | 132 DartType reportFailureAndCreateType( |
132 MessageKind messageKind, | 133 MessageKind messageKind, |
133 Map messageArguments, | 134 Map messageArguments, |
134 {DartType userProvidedBadType, | 135 {DartType userProvidedBadType, |
135 Element erroneousElement, | 136 Element erroneousElement, |
136 List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) { | 137 List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) { |
137 if (malformedIsError) { | 138 if (malformedIsError) { |
138 listener.reportError( | 139 reporter.reportError( |
139 listener.createMessage(node, messageKind, messageArguments), | 140 reporter.createMessage(node, messageKind, messageArguments), |
140 infos); | 141 infos); |
141 } else { | 142 } else { |
142 registry.registerThrowRuntimeError(); | 143 registry.registerThrowRuntimeError(); |
143 listener.reportWarning( | 144 reporter.reportWarning( |
144 listener.createMessage(node, messageKind, messageArguments), | 145 reporter.createMessage(node, messageKind, messageArguments), |
145 infos); | 146 infos); |
146 } | 147 } |
147 if (erroneousElement == null) { | 148 if (erroneousElement == null) { |
148 registry.registerThrowRuntimeError(); | 149 registry.registerThrowRuntimeError(); |
149 erroneousElement = new ErroneousElementX( | 150 erroneousElement = new ErroneousElementX( |
150 messageKind, messageArguments, typeName.source, | 151 messageKind, messageArguments, typeName.source, |
151 visitor.enclosingElement); | 152 visitor.enclosingElement); |
152 } | 153 } |
153 List<DartType> arguments = <DartType>[]; | 154 List<DartType> arguments = <DartType>[]; |
154 resolveTypeArguments(visitor, node, const <DartType>[], arguments); | 155 resolveTypeArguments(visitor, node, const <DartType>[], arguments); |
155 return new MalformedType(erroneousElement, | 156 return new MalformedType(erroneousElement, |
156 userProvidedBadType, arguments); | 157 userProvidedBadType, arguments); |
157 } | 158 } |
158 | 159 |
159 // Try to construct the type from the element. | 160 // Try to construct the type from the element. |
160 if (element == null) { | 161 if (element == null) { |
161 type = reportFailureAndCreateType( | 162 type = reportFailureAndCreateType( |
162 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 163 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
163 } else if (element.isAmbiguous) { | 164 } else if (element.isAmbiguous) { |
164 AmbiguousElement ambiguous = element; | 165 AmbiguousElement ambiguous = element; |
165 type = reportFailureAndCreateType( | 166 type = reportFailureAndCreateType( |
166 ambiguous.messageKind, | 167 ambiguous.messageKind, |
167 ambiguous.messageArguments, | 168 ambiguous.messageArguments, |
168 infos: ambiguous.computeInfos( | 169 infos: ambiguous.computeInfos( |
169 registry.mapping.analyzedElement, compiler)); | 170 registry.mapping.analyzedElement, reporter)); |
170 ; | 171 ; |
171 } else if (element.isErroneous) { | 172 } else if (element.isErroneous) { |
172 if (element is ErroneousElement) { | 173 if (element is ErroneousElement) { |
173 type = reportFailureAndCreateType( | 174 type = reportFailureAndCreateType( |
174 element.messageKind, element.messageArguments, | 175 element.messageKind, element.messageArguments, |
175 erroneousElement: element); | 176 erroneousElement: element); |
176 } else { | 177 } else { |
177 type = const DynamicType(); | 178 type = const DynamicType(); |
178 } | 179 } |
179 } else if (!element.impliesType) { | 180 } else if (!element.impliesType) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 registry.registerThrowRuntimeError(); | 233 registry.registerThrowRuntimeError(); |
233 type = reportFailureAndCreateType( | 234 type = reportFailureAndCreateType( |
234 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 235 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
235 {'typeVariableName': node}, | 236 {'typeVariableName': node}, |
236 userProvidedBadType: typeVariable.type); | 237 userProvidedBadType: typeVariable.type); |
237 } else { | 238 } else { |
238 type = typeVariable.type; | 239 type = typeVariable.type; |
239 } | 240 } |
240 type = checkNoTypeArguments(type); | 241 type = checkNoTypeArguments(type); |
241 } else { | 242 } else { |
242 compiler.internalError(node, | 243 reporter.internalError(node, |
243 "Unexpected element kind ${element.kind}."); | 244 "Unexpected element kind ${element.kind}."); |
244 } | 245 } |
245 if (addTypeVariableBoundsCheck) { | 246 if (addTypeVariableBoundsCheck) { |
246 registry.registerTypeVariableBoundCheck(); | 247 registry.registerTypeVariableBoundCheck(); |
247 visitor.addDeferredAction( | 248 visitor.addDeferredAction( |
248 visitor.enclosingElement, | 249 visitor.enclosingElement, |
249 () => checkTypeVariableBounds(node, type)); | 250 () => checkTypeVariableBounds(node, type)); |
250 } | 251 } |
251 } | 252 } |
252 registry.useType(node, type); | 253 registry.useType(node, type); |
253 return type; | 254 return type; |
254 } | 255 } |
255 | 256 |
256 /// Checks the type arguments of [type] against the type variable bounds. | 257 /// Checks the type arguments of [type] against the type variable bounds. |
257 void checkTypeVariableBounds(TypeAnnotation node, GenericType type) { | 258 void checkTypeVariableBounds(TypeAnnotation node, GenericType type) { |
258 void checkTypeVariableBound(_, DartType typeArgument, | 259 void checkTypeVariableBound(_, DartType typeArgument, |
259 TypeVariableType typeVariable, | 260 TypeVariableType typeVariable, |
260 DartType bound) { | 261 DartType bound) { |
261 if (!compiler.types.isSubtype(typeArgument, bound)) { | 262 if (!compiler.types.isSubtype(typeArgument, bound)) { |
262 compiler.reportWarningMessage( | 263 reporter.reportWarningMessage( |
263 node, | 264 node, |
264 MessageKind.INVALID_TYPE_VARIABLE_BOUND, | 265 MessageKind.INVALID_TYPE_VARIABLE_BOUND, |
265 {'typeVariable': typeVariable, | 266 {'typeVariable': typeVariable, |
266 'bound': bound, | 267 'bound': bound, |
267 'typeArgument': typeArgument, | 268 'typeArgument': typeArgument, |
268 'thisType': type.element.thisType}); | 269 'thisType': type.element.thisType}); |
269 } | 270 } |
270 }; | 271 }; |
271 | 272 |
272 compiler.types.checkTypeVariableBounds(type, checkTypeVariableBound); | 273 compiler.types.checkTypeVariableBounds(type, checkTypeVariableBound); |
(...skipping 12 matching lines...) Expand all Loading... |
285 if (node.typeArguments == null) { | 286 if (node.typeArguments == null) { |
286 return false; | 287 return false; |
287 } | 288 } |
288 int expectedVariables = typeVariables.length; | 289 int expectedVariables = typeVariables.length; |
289 int index = 0; | 290 int index = 0; |
290 bool typeArgumentCountMismatch = false; | 291 bool typeArgumentCountMismatch = false; |
291 for (Link<Node> typeArguments = node.typeArguments.nodes; | 292 for (Link<Node> typeArguments = node.typeArguments.nodes; |
292 !typeArguments.isEmpty; | 293 !typeArguments.isEmpty; |
293 typeArguments = typeArguments.tail, index++) { | 294 typeArguments = typeArguments.tail, index++) { |
294 if (index > expectedVariables - 1) { | 295 if (index > expectedVariables - 1) { |
295 compiler.reportWarningMessage( | 296 reporter.reportWarningMessage( |
296 typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 297 typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
297 typeArgumentCountMismatch = true; | 298 typeArgumentCountMismatch = true; |
298 } | 299 } |
299 DartType argType = resolveTypeAnnotation(visitor, typeArguments.head); | 300 DartType argType = resolveTypeAnnotation(visitor, typeArguments.head); |
300 // TODO(karlklose): rewrite to not modify [arguments]. | 301 // TODO(karlklose): rewrite to not modify [arguments]. |
301 arguments.add(argType); | 302 arguments.add(argType); |
302 } | 303 } |
303 if (index < expectedVariables) { | 304 if (index < expectedVariables) { |
304 compiler.reportWarningMessage( | 305 reporter.reportWarningMessage( |
305 node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | 306 node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); |
306 typeArgumentCountMismatch = true; | 307 typeArgumentCountMismatch = true; |
307 } | 308 } |
308 return typeArgumentCountMismatch; | 309 return typeArgumentCountMismatch; |
309 } | 310 } |
310 } | 311 } |
OLD | NEW |