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

Side by Side Diff: pkg/compiler/lib/src/resolution/constructors.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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 library dart2js.resolution.constructors; 5 library dart2js.resolution.constructors;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/resolution.dart' show 8 import '../common/resolution.dart' show Feature;
9 Feature; 9 import '../compiler.dart' show Compiler;
10 import '../compiler.dart' show 10 import '../constants/constructors.dart'
11 Compiler; 11 show
12 import '../constants/constructors.dart' show 12 GenerativeConstantConstructor,
13 GenerativeConstantConstructor, 13 RedirectingGenerativeConstantConstructor;
14 RedirectingGenerativeConstantConstructor;
15 import '../constants/expressions.dart'; 14 import '../constants/expressions.dart';
16 import '../dart_types.dart'; 15 import '../dart_types.dart';
17 import '../elements/elements.dart'; 16 import '../elements/elements.dart';
18 import '../elements/modelx.dart' show 17 import '../elements/modelx.dart'
19 ConstructorElementX, 18 show
20 ErroneousConstructorElementX, 19 ConstructorElementX,
21 ErroneousElementX, 20 ErroneousConstructorElementX,
22 ErroneousFieldElementX, 21 ErroneousElementX,
23 FieldElementX, 22 ErroneousFieldElementX,
24 InitializingFormalElementX, 23 FieldElementX,
25 ParameterElementX; 24 InitializingFormalElementX,
25 ParameterElementX;
26 import '../tree/tree.dart'; 26 import '../tree/tree.dart';
27 import '../util/util.dart' show 27 import '../util/util.dart' show Link;
28 Link; 28 import '../universe/call_structure.dart' show CallStructure;
29 import '../universe/call_structure.dart' show 29 import '../universe/use.dart' show StaticUse;
30 CallStructure;
31 import '../universe/use.dart' show
32 StaticUse;
33 30
34 import 'members.dart' show 31 import 'members.dart' show lookupInScope, ResolverVisitor;
35 lookupInScope, 32 import 'registry.dart' show ResolutionRegistry;
36 ResolverVisitor; 33 import 'resolution_common.dart' show CommonResolverVisitor;
37 import 'registry.dart' show
38 ResolutionRegistry;
39 import 'resolution_common.dart' show
40 CommonResolverVisitor;
41 import 'resolution_result.dart'; 34 import 'resolution_result.dart';
42 35
43 class InitializerResolver { 36 class InitializerResolver {
44 final ResolverVisitor visitor; 37 final ResolverVisitor visitor;
45 final ConstructorElementX constructor; 38 final ConstructorElementX constructor;
46 final FunctionExpression functionNode; 39 final FunctionExpression functionNode;
47 final Map<FieldElement, Node> initialized = <FieldElement, Node>{}; 40 final Map<FieldElement, Node> initialized = <FieldElement, Node>{};
48 final Map<FieldElement, ConstantExpression> fieldInitializers = 41 final Map<FieldElement, ConstantExpression> fieldInitializers =
49 <FieldElement, ConstantExpression>{}; 42 <FieldElement, ConstantExpression>{};
50 Link<Node> initializers; 43 Link<Node> initializers;
51 bool hasSuper = false; 44 bool hasSuper = false;
52 bool isValidAsConstant = true; 45 bool isValidAsConstant = true;
53 46
54 bool get isConst => constructor.isConst; 47 bool get isConst => constructor.isConst;
55 48
56 InitializerResolver(this.visitor, this.constructor, this.functionNode); 49 InitializerResolver(this.visitor, this.constructor, this.functionNode);
57 50
58 ResolutionRegistry get registry => visitor.registry; 51 ResolutionRegistry get registry => visitor.registry;
59 52
60 DiagnosticReporter get reporter => visitor.reporter; 53 DiagnosticReporter get reporter => visitor.reporter;
61 54
62 bool isFieldInitializer(SendSet node) { 55 bool isFieldInitializer(SendSet node) {
63 if (node.selector.asIdentifier() == null) return false; 56 if (node.selector.asIdentifier() == null) return false;
64 if (node.receiver == null) return true; 57 if (node.receiver == null) return true;
65 if (node.receiver.asIdentifier() == null) return false; 58 if (node.receiver.asIdentifier() == null) return false;
66 return node.receiver.asIdentifier().isThis(); 59 return node.receiver.asIdentifier().isThis();
67 } 60 }
68 61
69 reportDuplicateInitializerError(Element field, 62 reportDuplicateInitializerError(
70 Node init, 63 Element field, Node init, Spannable existing) {
71 Spannable existing) {
72 reporter.reportError( 64 reporter.reportError(
73 reporter.createMessage( 65 reporter.createMessage(
74 init, 66 init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': field.name}),
75 MessageKind.DUPLICATE_INITIALIZER,
76 {'fieldName': field.name}),
77 <DiagnosticMessage>[ 67 <DiagnosticMessage>[
78 reporter.createMessage( 68 reporter.createMessage(existing, MessageKind.ALREADY_INITIALIZED,
79 existing, 69 {'fieldName': field.name}),
80 MessageKind.ALREADY_INITIALIZED,
81 {'fieldName': field.name}),
82 ]); 70 ]);
83 isValidAsConstant = false; 71 isValidAsConstant = false;
84 } 72 }
85 73
86 void checkForDuplicateInitializers(FieldElementX field, Node init) { 74 void checkForDuplicateInitializers(FieldElementX field, Node init) {
87 // [field] can be null if it could not be resolved. 75 // [field] can be null if it could not be resolved.
88 if (field == null) return; 76 if (field == null) return;
89 if (initialized.containsKey(field)) { 77 if (initialized.containsKey(field)) {
90 reportDuplicateInitializerError(field, init, initialized[field]); 78 reportDuplicateInitializerError(field, init, initialized[field]);
91 } else if (field.isFinal) { 79 } else if (field.isFinal) {
92 field.parseNode(visitor.resolution.parsing); 80 field.parseNode(visitor.resolution.parsing);
93 Expression initializer = field.initializer; 81 Expression initializer = field.initializer;
94 if (initializer != null) { 82 if (initializer != null) {
95 reportDuplicateInitializerError(field, init, 83 reportDuplicateInitializerError(
96 reporter.withCurrentElement(field, 84 field,
97 () => reporter.spanFromSpannable(initializer))); 85 init,
86 reporter.withCurrentElement(
87 field, () => reporter.spanFromSpannable(initializer)));
98 } 88 }
99 } 89 }
100 initialized[field] = init; 90 initialized[field] = init;
101 } 91 }
102 92
103 void resolveFieldInitializer(SendSet init) { 93 void resolveFieldInitializer(SendSet init) {
104 // init is of the form [this.]field = value. 94 // init is of the form [this.]field = value.
105 final Node selector = init.selector; 95 final Node selector = init.selector;
106 final String name = selector.asIdentifier().source; 96 final String name = selector.asIdentifier().source;
107 // Lookup target field. 97 // Lookup target field.
(...skipping 22 matching lines...) Expand all
130 init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); 120 init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
131 } 121 }
132 if (target != null) { 122 if (target != null) {
133 registry.useElement(init, target); 123 registry.useElement(init, target);
134 checkForDuplicateInitializers(target, init); 124 checkForDuplicateInitializers(target, init);
135 } 125 }
136 if (field != null) { 126 if (field != null) {
137 registry.registerStaticUse(new StaticUse.fieldInit(field)); 127 registry.registerStaticUse(new StaticUse.fieldInit(field));
138 } 128 }
139 // Resolve initializing value. 129 // Resolve initializing value.
140 ResolutionResult result = visitor.visitInStaticContext( 130 ResolutionResult result = visitor.visitInStaticContext(init.arguments.head,
141 init.arguments.head,
142 inConstantInitializer: isConst); 131 inConstantInitializer: isConst);
143 if (isConst) { 132 if (isConst) {
144 if (result.isConstant && field != null) { 133 if (result.isConstant && field != null) {
145 // TODO(johnniwinther): Report error if `result.constant` is `null`. 134 // TODO(johnniwinther): Report error if `result.constant` is `null`.
146 fieldInitializers[field] = result.constant; 135 fieldInitializers[field] = result.constant;
147 } else { 136 } else {
148 isValidAsConstant = false; 137 isValidAsConstant = false;
149 } 138 }
150 } 139 }
151 } 140 }
152 141
153 InterfaceType getSuperOrThisLookupTarget(Node diagnosticNode, 142 InterfaceType getSuperOrThisLookupTarget(Node diagnosticNode,
154 {bool isSuperCall}) { 143 {bool isSuperCall}) {
155 if (isSuperCall) { 144 if (isSuperCall) {
156 // Calculate correct lookup target and constructor name. 145 // Calculate correct lookup target and constructor name.
157 if (constructor.enclosingClass.isObject) { 146 if (constructor.enclosingClass.isObject) {
158 reporter.reportErrorMessage( 147 reporter.reportErrorMessage(
159 diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT); 148 diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
160 isValidAsConstant = false; 149 isValidAsConstant = false;
161 } else { 150 } else {
162 return constructor.enclosingClass.supertype; 151 return constructor.enclosingClass.supertype;
163 } 152 }
164 } 153 }
165 return constructor.enclosingClass.thisType; 154 return constructor.enclosingClass.thisType;
166 } 155 }
167 156
168 ResolutionResult resolveSuperOrThisForSend(Send node) { 157 ResolutionResult resolveSuperOrThisForSend(Send node) {
169 // Resolve the selector and the arguments. 158 // Resolve the selector and the arguments.
170 ArgumentsResult argumentsResult = visitor.inStaticContext(() { 159 ArgumentsResult argumentsResult = visitor.inStaticContext(() {
171 // TODO(johnniwinther): Remove this when [SendStructure] is used directly. 160 // TODO(johnniwinther): Remove this when [SendStructure] is used directly.
172 visitor.resolveSelector(node, null); 161 visitor.resolveSelector(node, null);
173 return visitor.resolveArguments(node.argumentsNode); 162 return visitor.resolveArguments(node.argumentsNode);
174 }, inConstantInitializer: isConst); 163 }, inConstantInitializer: isConst);
175 164
176 bool isSuperCall = Initializers.isSuperConstructorCall(node); 165 bool isSuperCall = Initializers.isSuperConstructorCall(node);
177 InterfaceType targetType = 166 InterfaceType targetType =
178 getSuperOrThisLookupTarget(node, isSuperCall: isSuperCall); 167 getSuperOrThisLookupTarget(node, isSuperCall: isSuperCall);
179 ClassElement lookupTarget = targetType.element; 168 ClassElement lookupTarget = targetType.element;
180 String constructorName = 169 String constructorName =
181 visitor.getRedirectingThisOrSuperConstructorName(node).text; 170 visitor.getRedirectingThisOrSuperConstructorName(node).text;
182 ConstructorElement foundConstructor = findConstructor( 171 ConstructorElement foundConstructor =
183 constructor.library, lookupTarget, constructorName); 172 findConstructor(constructor.library, lookupTarget, constructorName);
184 173
185 final bool isImplicitSuperCall = false; 174 final bool isImplicitSuperCall = false;
186 final String className = lookupTarget.name; 175 final String className = lookupTarget.name;
187 CallStructure callStructure = argumentsResult.callStructure; 176 CallStructure callStructure = argumentsResult.callStructure;
188 ConstructorElement calledConstructor = verifyThatConstructorMatchesCall( 177 ConstructorElement calledConstructor = verifyThatConstructorMatchesCall(
189 node, 178 node, foundConstructor, callStructure, className,
190 foundConstructor,
191 callStructure,
192 className,
193 constructorName: constructorName, 179 constructorName: constructorName,
194 isThisCall: !isSuperCall, 180 isThisCall: !isSuperCall,
195 isImplicitSuperCall: false); 181 isImplicitSuperCall: false);
196 // TODO(johnniwinther): Remove this when information is pulled from an 182 // TODO(johnniwinther): Remove this when information is pulled from an
197 // [InitializerStructure]. 183 // [InitializerStructure].
198 registry.useElement(node, calledConstructor); 184 registry.useElement(node, calledConstructor);
199 if (!calledConstructor.isError) { 185 if (!calledConstructor.isError) {
200 registry.registerStaticUse( 186 registry.registerStaticUse(new StaticUse.superConstructorInvoke(
201 new StaticUse.superConstructorInvoke( 187 calledConstructor, callStructure));
202 calledConstructor, callStructure));
203 } 188 }
204 if (isConst) { 189 if (isConst) {
205 if (isValidAsConstant && 190 if (isValidAsConstant &&
206 calledConstructor.isConst && 191 calledConstructor.isConst &&
207 argumentsResult.isValidAsConstant) { 192 argumentsResult.isValidAsConstant) {
208 List<ConstantExpression> arguments = argumentsResult.constantArguments; 193 List<ConstantExpression> arguments = argumentsResult.constantArguments;
209 return new ConstantResult( 194 return new ConstantResult(
210 node, 195 node,
211 new ConstructedConstantExpression( 196 new ConstructedConstantExpression(
212 targetType, 197 targetType, calledConstructor, callStructure, arguments),
213 calledConstructor,
214 callStructure,
215 arguments),
216 element: calledConstructor); 198 element: calledConstructor);
217 } else { 199 } else {
218 isValidAsConstant = false; 200 isValidAsConstant = false;
219 } 201 }
220 } 202 }
221 return new ResolutionResult.forElement(calledConstructor); 203 return new ResolutionResult.forElement(calledConstructor);
222 } 204 }
223 205
224 ConstructedConstantExpression resolveImplicitSuperConstructorSend() { 206 ConstructedConstantExpression resolveImplicitSuperConstructorSend() {
225 // If the class has a super resolve the implicit super call. 207 // If the class has a super resolve the implicit super call.
226 ClassElement classElement = constructor.enclosingClass; 208 ClassElement classElement = constructor.enclosingClass;
227 ClassElement superClass = classElement.superclass; 209 ClassElement superClass = classElement.superclass;
228 if (!classElement.isObject) { 210 if (!classElement.isObject) {
229 assert(superClass != null); 211 assert(superClass != null);
230 assert(superClass.isResolved); 212 assert(superClass.isResolved);
231 213
232 InterfaceType targetType = 214 InterfaceType targetType =
233 getSuperOrThisLookupTarget(functionNode, isSuperCall: true); 215 getSuperOrThisLookupTarget(functionNode, isSuperCall: true);
234 ClassElement lookupTarget = targetType.element; 216 ClassElement lookupTarget = targetType.element;
235 ConstructorElement calledConstructor = 217 ConstructorElement calledConstructor =
236 findConstructor(constructor.library, lookupTarget, ''); 218 findConstructor(constructor.library, lookupTarget, '');
237 219
238 final String className = lookupTarget.name; 220 final String className = lookupTarget.name;
239 CallStructure callStructure = CallStructure.NO_ARGS; 221 CallStructure callStructure = CallStructure.NO_ARGS;
240 ConstructorElement result = verifyThatConstructorMatchesCall( 222 ConstructorElement result = verifyThatConstructorMatchesCall(
241 functionNode, 223 functionNode, calledConstructor, callStructure, className,
242 calledConstructor,
243 callStructure,
244 className,
245 isImplicitSuperCall: true); 224 isImplicitSuperCall: true);
246 if (!result.isError) { 225 if (!result.isError) {
247 registry.registerStaticUse( 226 registry.registerStaticUse(
248 new StaticUse.constructorInvoke(calledConstructor, callStructure)); 227 new StaticUse.constructorInvoke(calledConstructor, callStructure));
249 } 228 }
250 229
251 if (isConst && isValidAsConstant) { 230 if (isConst && isValidAsConstant) {
252 return new ConstructedConstantExpression( 231 return new ConstructedConstantExpression(targetType, result,
253 targetType, 232 CallStructure.NO_ARGS, const <ConstantExpression>[]);
254 result,
255 CallStructure.NO_ARGS,
256 const <ConstantExpression>[]);
257 } 233 }
258 } 234 }
259 return null; 235 return null;
260 } 236 }
261 237
262 ConstructorElement reportAndCreateErroneousConstructor( 238 ConstructorElement reportAndCreateErroneousConstructor(
263 Spannable diagnosticNode, 239 Spannable diagnosticNode, String name, MessageKind kind, Map arguments) {
264 String name,
265 MessageKind kind,
266 Map arguments) {
267 isValidAsConstant = false; 240 isValidAsConstant = false;
268 reporter.reportErrorMessage( 241 reporter.reportErrorMessage(diagnosticNode, kind, arguments);
269 diagnosticNode, kind, arguments);
270 return new ErroneousConstructorElementX( 242 return new ErroneousConstructorElementX(
271 kind, arguments, name, visitor.currentClass); 243 kind, arguments, name, visitor.currentClass);
272 } 244 }
273 245
274 /// Checks that [lookedupConstructor] is valid as a target for the super/this 246 /// Checks that [lookedupConstructor] is valid as a target for the super/this
275 /// constructor call using with the given [callStructure]. 247 /// constructor call using with the given [callStructure].
276 /// 248 ///
277 /// If [lookedupConstructor] is valid it is returned, otherwise an error is 249 /// If [lookedupConstructor] is valid it is returned, otherwise an error is
278 /// reported and an [ErroneousConstructorElement] is returned. 250 /// reported and an [ErroneousConstructorElement] is returned.
279 ConstructorElement verifyThatConstructorMatchesCall( 251 ConstructorElement verifyThatConstructorMatchesCall(
280 Node node, 252 Node node,
281 ConstructorElementX lookedupConstructor, 253 ConstructorElementX lookedupConstructor,
282 CallStructure callStructure, 254 CallStructure callStructure,
283 String className, 255 String className,
284 {String constructorName: '', 256 {String constructorName: '',
285 bool isImplicitSuperCall: false, 257 bool isImplicitSuperCall: false,
286 bool isThisCall: false}) { 258 bool isThisCall: false}) {
287 Element result = lookedupConstructor; 259 Element result = lookedupConstructor;
288 if (lookedupConstructor == null) { 260 if (lookedupConstructor == null) {
289 String fullConstructorName = 261 String fullConstructorName =
290 Elements.constructorNameForDiagnostics(className, constructorName); 262 Elements.constructorNameForDiagnostics(className, constructorName);
291 MessageKind kind = isImplicitSuperCall 263 MessageKind kind = isImplicitSuperCall
292 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT 264 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
293 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; 265 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
294 result = reportAndCreateErroneousConstructor( 266 result = reportAndCreateErroneousConstructor(node, constructorName, kind,
295 node, constructorName, 267 {'constructorName': fullConstructorName});
296 kind, {'constructorName': fullConstructorName});
297 } else if (!lookedupConstructor.isGenerativeConstructor) { 268 } else if (!lookedupConstructor.isGenerativeConstructor) {
298 MessageKind kind = isThisCall 269 MessageKind kind = isThisCall
299 ? MessageKind.THIS_CALL_TO_FACTORY 270 ? MessageKind.THIS_CALL_TO_FACTORY
300 : MessageKind.SUPER_CALL_TO_FACTORY; 271 : MessageKind.SUPER_CALL_TO_FACTORY;
301 result = reportAndCreateErroneousConstructor( 272 result =
302 node, constructorName, kind, {}); 273 reportAndCreateErroneousConstructor(node, constructorName, kind, {});
303 } else { 274 } else {
304 lookedupConstructor.computeType(visitor.resolution); 275 lookedupConstructor.computeType(visitor.resolution);
305 if (!callStructure.signatureApplies( 276 if (!callStructure
306 lookedupConstructor.functionSignature)) { 277 .signatureApplies(lookedupConstructor.functionSignature)) {
307 MessageKind kind = isImplicitSuperCall 278 MessageKind kind = isImplicitSuperCall
308 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT 279 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
309 : MessageKind.NO_MATCHING_CONSTRUCTOR; 280 : MessageKind.NO_MATCHING_CONSTRUCTOR;
310 result = reportAndCreateErroneousConstructor( 281 result = reportAndCreateErroneousConstructor(
311 node, constructorName, kind, {}); 282 node, constructorName, kind, {});
312 } else if (constructor.isConst && !lookedupConstructor.isConst) { 283 } else if (constructor.isConst && !lookedupConstructor.isConst) {
313 MessageKind kind = isImplicitSuperCall 284 MessageKind kind = isImplicitSuperCall
314 ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT 285 ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
315 : MessageKind.CONST_CALLS_NON_CONST; 286 : MessageKind.CONST_CALLS_NON_CONST;
316 result = reportAndCreateErroneousConstructor( 287 result = reportAndCreateErroneousConstructor(
317 node, constructorName, kind, {}); 288 node, constructorName, kind, {});
318 } 289 }
319 } 290 }
320 return result; 291 return result;
321 } 292 }
322 293
323 /** 294 /**
324 * Resolve all initializers of this constructor. In the case of a redirecting 295 * Resolve all initializers of this constructor. In the case of a redirecting
325 * constructor, the resolved constructor's function element is returned. 296 * constructor, the resolved constructor's function element is returned.
326 */ 297 */
327 ConstructorElement resolveInitializers() { 298 ConstructorElement resolveInitializers() {
328 Map<dynamic/*String|int*/, ConstantExpression> defaultValues = 299 Map<dynamic /*String|int*/, ConstantExpression> defaultValues =
329 <dynamic/*String|int*/, ConstantExpression>{}; 300 <dynamic /*String|int*/, ConstantExpression>{};
330 ConstructedConstantExpression constructorInvocation; 301 ConstructedConstantExpression constructorInvocation;
331 // Keep track of all "this.param" parameters specified for constructor so 302 // Keep track of all "this.param" parameters specified for constructor so
332 // that we can ensure that fields are initialized only once. 303 // that we can ensure that fields are initialized only once.
333 FunctionSignature functionParameters = constructor.functionSignature; 304 FunctionSignature functionParameters = constructor.functionSignature;
334 functionParameters.forEachParameter((ParameterElementX element) { 305 functionParameters.forEachParameter((ParameterElementX element) {
335 if (isConst) { 306 if (isConst) {
336 if (element.isOptional) { 307 if (element.isOptional) {
337 if (element.constantCache == null) { 308 if (element.constantCache == null) {
338 // TODO(johnniwinther): Remove this when all constant expressions 309 // TODO(johnniwinther): Remove this when all constant expressions
339 // can be computed during resolution. 310 // can be computed during resolution.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 ResolutionResult result = resolveSuperOrThisForSend(call); 401 ResolutionResult result = resolveSuperOrThisForSend(call);
431 if (isConst) { 402 if (isConst) {
432 if (result.isConstant) { 403 if (result.isConstant) {
433 constructorInvocation = result.constant; 404 constructorInvocation = result.constant;
434 } else { 405 } else {
435 isValidAsConstant = false; 406 isValidAsConstant = false;
436 } 407 }
437 if (isConst && isValidAsConstant) { 408 if (isConst && isValidAsConstant) {
438 constructor.constantConstructor = 409 constructor.constantConstructor =
439 new RedirectingGenerativeConstantConstructor( 410 new RedirectingGenerativeConstantConstructor(
440 defaultValues, 411 defaultValues, constructorInvocation);
441 constructorInvocation);
442 } 412 }
443 } 413 }
444 return result.element; 414 return result.element;
445 } else { 415 } else {
446 reporter.reportErrorMessage( 416 reporter.reportErrorMessage(
447 call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); 417 call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
448 return null; 418 return null;
449 } 419 }
450 } else { 420 } else {
451 reporter.reportErrorMessage( 421 reporter.reportErrorMessage(link.head, MessageKind.INVALID_INITIALIZER);
452 link.head, MessageKind.INVALID_INITIALIZER);
453 } 422 }
454 } 423 }
455 if (!resolvedSuper) { 424 if (!resolvedSuper) {
456 constructorInvocation = resolveImplicitSuperConstructorSend(); 425 constructorInvocation = resolveImplicitSuperConstructorSend();
457 } 426 }
458 if (isConst && isValidAsConstant) { 427 if (isConst && isValidAsConstant) {
459 constructor.constantConstructor = new GenerativeConstantConstructor( 428 constructor.constantConstructor = new GenerativeConstantConstructor(
460 constructor.enclosingClass.thisType, 429 constructor.enclosingClass.thisType,
461 defaultValues, 430 defaultValues,
462 fieldInitializers, 431 fieldInitializers,
463 constructorInvocation); 432 constructorInvocation);
464 } 433 }
465 return null; // If there was no redirection always return null. 434 return null; // If there was no redirection always return null.
466 } 435 }
467 } 436 }
468 437
469 class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> { 438 class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
470 final ResolverVisitor resolver; 439 final ResolverVisitor resolver;
471 final bool inConstContext; 440 final bool inConstContext;
472 441
473 ConstructorResolver(Compiler compiler, this.resolver, 442 ConstructorResolver(Compiler compiler, this.resolver,
474 {bool this.inConstContext: false}) 443 {bool this.inConstContext: false})
475 : super(compiler); 444 : super(compiler);
476 445
477 ResolutionRegistry get registry => resolver.registry; 446 ResolutionRegistry get registry => resolver.registry;
478 447
479 visitNode(Node node) { 448 visitNode(Node node) {
480 throw 'not supported'; 449 throw 'not supported';
481 } 450 }
482 451
483 ConstructorResult reportAndCreateErroneousConstructorElement( 452 ConstructorResult reportAndCreateErroneousConstructorElement(
484 Spannable diagnosticNode, 453 Spannable diagnosticNode,
485 ConstructorResultKind resultKind, 454 ConstructorResultKind resultKind,
486 DartType type, 455 DartType type,
487 Element enclosing, 456 Element enclosing,
488 String name, 457 String name,
489 MessageKind kind, 458 MessageKind kind,
490 Map arguments, 459 Map arguments,
491 {bool isError: false, 460 {bool isError: false,
492 bool missingConstructor: false, 461 bool missingConstructor: false,
493 List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) { 462 List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) {
494 if (missingConstructor) { 463 if (missingConstructor) {
495 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); 464 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
496 } else { 465 } else {
497 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); 466 registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
498 } 467 }
499 DiagnosticMessage message = 468 DiagnosticMessage message =
500 reporter.createMessage(diagnosticNode, kind, arguments); 469 reporter.createMessage(diagnosticNode, kind, arguments);
501 if (isError || inConstContext) { 470 if (isError || inConstContext) {
502 reporter.reportError(message, infos); 471 reporter.reportError(message, infos);
503 } else { 472 } else {
504 reporter.reportWarning(message, infos); 473 reporter.reportWarning(message, infos);
505 } 474 }
506 ErroneousElement error = new ErroneousConstructorElementX( 475 ErroneousElement error =
507 kind, arguments, name, enclosing); 476 new ErroneousConstructorElementX(kind, arguments, name, enclosing);
508 if (type == null) { 477 if (type == null) {
509 type = new MalformedType(error, null); 478 type = new MalformedType(error, null);
510 } 479 }
511 return new ConstructorResult.forError(resultKind, error, type); 480 return new ConstructorResult.forError(resultKind, error, type);
512 } 481 }
513 482
514 ConstructorResult resolveConstructor( 483 ConstructorResult resolveConstructor(PrefixElement prefix, InterfaceType type,
515 PrefixElement prefix, 484 Node diagnosticNode, String constructorName) {
516 InterfaceType type,
517 Node diagnosticNode,
518 String constructorName) {
519 ClassElement cls = type.element; 485 ClassElement cls = type.element;
520 cls.ensureResolved(resolution); 486 cls.ensureResolved(resolution);
521 ConstructorElement constructor = findConstructor( 487 ConstructorElement constructor = findConstructor(
522 resolver.enclosingElement.library, cls, constructorName); 488 resolver.enclosingElement.library, cls, constructorName);
523 if (constructor == null) { 489 if (constructor == null) {
524 MessageKind kind = constructorName.isEmpty 490 MessageKind kind = constructorName.isEmpty
525 ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR 491 ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR
526 : MessageKind.CANNOT_FIND_CONSTRUCTOR; 492 : MessageKind.CANNOT_FIND_CONSTRUCTOR;
527 return reportAndCreateErroneousConstructorElement( 493 return reportAndCreateErroneousConstructorElement(
528 diagnosticNode, 494 diagnosticNode,
529 ConstructorResultKind.UNRESOLVED_CONSTRUCTOR, type, 495 ConstructorResultKind.UNRESOLVED_CONSTRUCTOR,
530 cls, constructorName, kind, 496 type,
497 cls,
498 constructorName,
499 kind,
531 {'className': cls.name, 'constructorName': constructorName}, 500 {'className': cls.name, 'constructorName': constructorName},
532 missingConstructor: true); 501 missingConstructor: true);
533 } else if (inConstContext && !constructor.isConst) { 502 } else if (inConstContext && !constructor.isConst) {
534 reporter.reportErrorMessage( 503 reporter.reportErrorMessage(
535 diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); 504 diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
536 return new ConstructorResult( 505 return new ConstructorResult(
537 ConstructorResultKind.NON_CONSTANT, prefix, constructor, type); 506 ConstructorResultKind.NON_CONSTANT, prefix, constructor, type);
538 } else { 507 } else {
539 if (cls.isEnumClass && resolver.currentClass != cls) { 508 if (cls.isEnumClass && resolver.currentClass != cls) {
540 return reportAndCreateErroneousConstructorElement( 509 return reportAndCreateErroneousConstructorElement(
541 diagnosticNode, 510 diagnosticNode,
542 ConstructorResultKind.INVALID_TYPE, type, 511 ConstructorResultKind.INVALID_TYPE,
543 cls, constructorName, 512 type,
513 cls,
514 constructorName,
544 MessageKind.CANNOT_INSTANTIATE_ENUM, 515 MessageKind.CANNOT_INSTANTIATE_ENUM,
545 {'enumName': cls.name}, 516 {'enumName': cls.name},
546 isError: true); 517 isError: true);
547 } 518 }
548 if (constructor.isGenerativeConstructor) { 519 if (constructor.isGenerativeConstructor) {
549 if (cls.isAbstract) { 520 if (cls.isAbstract) {
550 reporter.reportWarningMessage( 521 reporter.reportWarningMessage(
551 diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION); 522 diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
552 registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION); 523 registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
553 return new ConstructorResult( 524 return new ConstructorResult(
(...skipping 15 matching lines...) Expand all
569 Node selector = node.send.selector; 540 Node selector = node.send.selector;
570 ConstructorResult result = visit(selector); 541 ConstructorResult result = visit(selector);
571 assert(invariant(selector, result != null, 542 assert(invariant(selector, result != null,
572 message: 'No result returned for $selector.')); 543 message: 'No result returned for $selector.'));
573 return finishConstructorReference(result, node.send.selector, node); 544 return finishConstructorReference(result, node.send.selector, node);
574 } 545 }
575 546
576 /// Finishes resolution of a constructor reference and records the 547 /// Finishes resolution of a constructor reference and records the
577 /// type of the constructed instance on [expression]. 548 /// type of the constructed instance on [expression].
578 ConstructorResult finishConstructorReference( 549 ConstructorResult finishConstructorReference(
579 ConstructorResult result, 550 ConstructorResult result, Node diagnosticNode, Node expression) {
580 Node diagnosticNode,
581 Node expression) {
582 assert(invariant(diagnosticNode, result != null, 551 assert(invariant(diagnosticNode, result != null,
583 message: 'No result returned for $diagnosticNode.')); 552 message: 'No result returned for $diagnosticNode.'));
584 553
585 if (result.kind != null) { 554 if (result.kind != null) {
586 resolver.registry.setType(expression, result.type); 555 resolver.registry.setType(expression, result.type);
587 return result; 556 return result;
588 } 557 }
589 558
590 // Find the unnamed constructor if the reference resolved to a 559 // Find the unnamed constructor if the reference resolved to a
591 // class. 560 // class.
592 if (result.type != null) { 561 if (result.type != null) {
593 // The unnamed constructor may not exist, so [e] may become unresolved. 562 // The unnamed constructor may not exist, so [e] may become unresolved.
594 result = resolveConstructor( 563 result =
595 result.prefix, result.type, diagnosticNode, ''); 564 resolveConstructor(result.prefix, result.type, diagnosticNode, '');
596 } else { 565 } else {
597 Element element = result.element; 566 Element element = result.element;
598 if (element.isMalformed) { 567 if (element.isMalformed) {
599 result = constructorResultForErroneous(diagnosticNode, element); 568 result = constructorResultForErroneous(diagnosticNode, element);
600 } else { 569 } else {
601 result = reportAndCreateErroneousConstructorElement( 570 result = reportAndCreateErroneousConstructorElement(
602 diagnosticNode, 571 diagnosticNode,
603 ConstructorResultKind.INVALID_TYPE, null, 572 ConstructorResultKind.INVALID_TYPE,
604 element, element.name, 573 null,
605 MessageKind.NOT_A_TYPE, {'node': diagnosticNode}); 574 element,
575 element.name,
576 MessageKind.NOT_A_TYPE,
577 {'node': diagnosticNode});
606 } 578 }
607 } 579 }
608 resolver.registry.setType(expression, result.type); 580 resolver.registry.setType(expression, result.type);
609 return result; 581 return result;
610 } 582 }
611 583
612 ConstructorResult visitTypeAnnotation(TypeAnnotation node) { 584 ConstructorResult visitTypeAnnotation(TypeAnnotation node) {
613 // This is not really resolving a type-annotation, but the name of the 585 // This is not really resolving a type-annotation, but the name of the
614 // constructor. Therefore we allow deferred types. 586 // constructor. Therefore we allow deferred types.
615 DartType type = resolver.resolveTypeAnnotation( 587 DartType type = resolver.resolveTypeAnnotation(node,
616 node, 588 malformedIsError: inConstContext, deferredIsMalformed: false);
617 malformedIsError: inConstContext,
618 deferredIsMalformed: false);
619 Send send = node.typeName.asSend(); 589 Send send = node.typeName.asSend();
620 PrefixElement prefix; 590 PrefixElement prefix;
621 if (send != null) { 591 if (send != null) {
622 // The type name is of the form [: prefix . identifier :]. 592 // The type name is of the form [: prefix . identifier :].
623 String name = send.receiver.asIdentifier().source; 593 String name = send.receiver.asIdentifier().source;
624 Element element = lookupInScope(reporter, send, resolver.scope, name); 594 Element element = lookupInScope(reporter, send, resolver.scope, name);
625 if (element != null && element.isPrefix) { 595 if (element != null && element.isPrefix) {
626 prefix = element; 596 prefix = element;
627 } 597 }
628 } 598 }
(...skipping 17 matching lines...) Expand all
646 } 616 }
647 617
648 if (receiver.type != null) { 618 if (receiver.type != null) {
649 if (receiver.type.isInterfaceType) { 619 if (receiver.type.isInterfaceType) {
650 return resolveConstructor( 620 return resolveConstructor(
651 receiver.prefix, receiver.type, name, name.source); 621 receiver.prefix, receiver.type, name, name.source);
652 } else { 622 } else {
653 // TODO(johnniwinther): Update the message for the different types. 623 // TODO(johnniwinther): Update the message for the different types.
654 return reportAndCreateErroneousConstructorElement( 624 return reportAndCreateErroneousConstructorElement(
655 name, 625 name,
656 ConstructorResultKind.INVALID_TYPE, null, 626 ConstructorResultKind.INVALID_TYPE,
657 resolver.enclosingElement, name.source, 627 null,
658 MessageKind.NOT_A_TYPE, {'node': name}); 628 resolver.enclosingElement,
629 name.source,
630 MessageKind.NOT_A_TYPE,
631 {'node': name});
659 } 632 }
660 } else if (receiver.element.isPrefix) { 633 } else if (receiver.element.isPrefix) {
661 PrefixElement prefix = receiver.element; 634 PrefixElement prefix = receiver.element;
662 Element member = prefix.lookupLocalMember(name.source); 635 Element member = prefix.lookupLocalMember(name.source);
663 return constructorResultForElement( 636 return constructorResultForElement(node, name.source, member,
664 node, name.source, member, prefix: prefix); 637 prefix: prefix);
665 } else { 638 } else {
666 return reporter.internalError( 639 return reporter.internalError(
667 node.receiver, 'unexpected receiver $receiver'); 640 node.receiver, 'unexpected receiver $receiver');
668 } 641 }
669 } 642 }
670 643
671 ConstructorResult visitIdentifier(Identifier node) { 644 ConstructorResult visitIdentifier(Identifier node) {
672 String name = node.source; 645 String name = node.source;
673 Element element = lookupInScope(reporter, node, resolver.scope, name); 646 Element element = lookupInScope(reporter, node, resolver.scope, name);
674 registry.useElement(node, element); 647 registry.useElement(node, element);
675 return constructorResultForElement(node, name, element); 648 return constructorResultForElement(node, name, element);
676 } 649 }
677 650
678 /// Assumed to be called by [resolveRedirectingFactory]. 651 /// Assumed to be called by [resolveRedirectingFactory].
679 ConstructorResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { 652 ConstructorResult visitRedirectingFactoryBody(RedirectingFactoryBody node) {
680 Node constructorReference = node.constructorReference; 653 Node constructorReference = node.constructorReference;
681 return finishConstructorReference(visit(constructorReference), 654 return finishConstructorReference(
682 constructorReference, node); 655 visit(constructorReference), constructorReference, node);
683 } 656 }
684 657
685 ConstructorResult constructorResultForElement( 658 ConstructorResult constructorResultForElement(
686 Node node, String name, Element element, 659 Node node, String name, Element element,
687 {PrefixElement prefix}) { 660 {PrefixElement prefix}) {
688 element = Elements.unwrap(element, reporter, node); 661 element = Elements.unwrap(element, reporter, node);
689 if (element == null) { 662 if (element == null) {
690 return reportAndCreateErroneousConstructorElement( 663 return reportAndCreateErroneousConstructorElement(
691 node, 664 node,
692 ConstructorResultKind.INVALID_TYPE, null, 665 ConstructorResultKind.INVALID_TYPE,
693 resolver.enclosingElement, name, 666 null,
667 resolver.enclosingElement,
668 name,
694 MessageKind.CANNOT_RESOLVE, 669 MessageKind.CANNOT_RESOLVE,
695 {'name': name}); 670 {'name': name});
696 } else if (element.isAmbiguous) { 671 } else if (element.isAmbiguous) {
697 AmbiguousElement ambiguous = element; 672 AmbiguousElement ambiguous = element;
698 return reportAndCreateErroneousConstructorElement( 673 return reportAndCreateErroneousConstructorElement(
699 node, 674 node,
700 ConstructorResultKind.INVALID_TYPE, null, 675 ConstructorResultKind.INVALID_TYPE,
701 resolver.enclosingElement, name, 676 null,
677 resolver.enclosingElement,
678 name,
702 ambiguous.messageKind, 679 ambiguous.messageKind,
703 ambiguous.messageArguments, 680 ambiguous.messageArguments,
704 infos: ambiguous.computeInfos(resolver.enclosingElement, reporter)); 681 infos: ambiguous.computeInfos(resolver.enclosingElement, reporter));
705 } else if (element.isMalformed) { 682 } else if (element.isMalformed) {
706 return constructorResultForErroneous(node, element); 683 return constructorResultForErroneous(node, element);
707 } else if (element.isClass) { 684 } else if (element.isClass) {
708 ClassElement cls = element; 685 ClassElement cls = element;
709 cls.computeType(resolution); 686 cls.computeType(resolution);
710 return constructorResultForType(node, cls.rawType, prefix: prefix); 687 return constructorResultForType(node, cls.rawType, prefix: prefix);
711 } else if (element.isPrefix) { 688 } else if (element.isPrefix) {
712 return new ConstructorResult.forPrefix(element); 689 return new ConstructorResult.forPrefix(element);
713 } else if (element.isTypedef) { 690 } else if (element.isTypedef) {
714 TypedefElement typdef = element; 691 TypedefElement typdef = element;
715 typdef.ensureResolved(resolution); 692 typdef.ensureResolved(resolution);
716 return constructorResultForType(node, typdef.rawType); 693 return constructorResultForType(node, typdef.rawType);
717 } else if (element.isTypeVariable) { 694 } else if (element.isTypeVariable) {
718 TypeVariableElement typeVariableElement = element; 695 TypeVariableElement typeVariableElement = element;
719 return constructorResultForType(node, typeVariableElement.type); 696 return constructorResultForType(node, typeVariableElement.type);
720 } else { 697 } else {
721 return reportAndCreateErroneousConstructorElement( 698 return reportAndCreateErroneousConstructorElement(
722 node, 699 node,
723 ConstructorResultKind.INVALID_TYPE, null, 700 ConstructorResultKind.INVALID_TYPE,
724 resolver.enclosingElement, name, 701 null,
725 MessageKind.NOT_A_TYPE, {'node': name}); 702 resolver.enclosingElement,
703 name,
704 MessageKind.NOT_A_TYPE,
705 {'node': name});
726 } 706 }
727 } 707 }
728 708
729 ConstructorResult constructorResultForErroneous( 709 ConstructorResult constructorResultForErroneous(Node node, Element error) {
730 Node node, Element error) {
731 if (error is! ErroneousElementX) { 710 if (error is! ErroneousElementX) {
732 // Parser error. The error has already been reported. 711 // Parser error. The error has already been reported.
733 error = new ErroneousConstructorElementX( 712 error = new ErroneousConstructorElementX(
734 MessageKind.NOT_A_TYPE, {'node': node}, 713 MessageKind.NOT_A_TYPE, {'node': node}, error.name, error);
735 error.name, error);
736 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); 714 registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
737 } 715 }
738 return new ConstructorResult.forError( 716 return new ConstructorResult.forError(ConstructorResultKind.INVALID_TYPE,
739 ConstructorResultKind.INVALID_TYPE, 717 error, new MalformedType(error, null));
740 error,
741 new MalformedType(error, null));
742 } 718 }
743 719
744 ConstructorResult constructorResultForType( 720 ConstructorResult constructorResultForType(Node node, DartType type,
745 Node node,
746 DartType type,
747 {PrefixElement prefix}) { 721 {PrefixElement prefix}) {
748 String name = type.name; 722 String name = type.name;
749 if (type.isMalformed) { 723 if (type.isMalformed) {
750 return new ConstructorResult.forError( 724 return new ConstructorResult.forError(
751 ConstructorResultKind.INVALID_TYPE, type.element, type); 725 ConstructorResultKind.INVALID_TYPE, type.element, type);
752 } else if (type.isInterfaceType) { 726 } else if (type.isInterfaceType) {
753 return new ConstructorResult.forType(prefix, type); 727 return new ConstructorResult.forType(prefix, type);
754 } else if (type.isTypedef) { 728 } else if (type.isTypedef) {
755 return reportAndCreateErroneousConstructorElement( 729 return reportAndCreateErroneousConstructorElement(
756 node, 730 node,
757 ConstructorResultKind.INVALID_TYPE, type, 731 ConstructorResultKind.INVALID_TYPE,
758 resolver.enclosingElement, name, 732 type,
759 MessageKind.CANNOT_INSTANTIATE_TYPEDEF, {'typedefName': name}); 733 resolver.enclosingElement,
734 name,
735 MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
736 {'typedefName': name});
760 } else if (type.isTypeVariable) { 737 } else if (type.isTypeVariable) {
761 return reportAndCreateErroneousConstructorElement( 738 return reportAndCreateErroneousConstructorElement(
762 node, 739 node,
763 ConstructorResultKind.INVALID_TYPE, type, 740 ConstructorResultKind.INVALID_TYPE,
764 resolver.enclosingElement, name, 741 type,
742 resolver.enclosingElement,
743 name,
765 MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, 744 MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
766 {'typeVariableName': name}); 745 {'typeVariableName': name});
767 } 746 }
768 return reporter.internalError(node, "Unexpected constructor type $type"); 747 return reporter.internalError(node, "Unexpected constructor type $type");
769 } 748 }
770
771 } 749 }
772 750
773 /// The kind of constructor found by the [ConstructorResolver]. 751 /// The kind of constructor found by the [ConstructorResolver].
774 enum ConstructorResultKind { 752 enum ConstructorResultKind {
775 /// A generative or redirecting generative constructor. 753 /// A generative or redirecting generative constructor.
776 GENERATIVE, 754 GENERATIVE,
755
777 /// A factory or redirecting factory constructor. 756 /// A factory or redirecting factory constructor.
778 FACTORY, 757 FACTORY,
758
779 /// A generative or redirecting generative constructor on an abstract class. 759 /// A generative or redirecting generative constructor on an abstract class.
780 ABSTRACT, 760 ABSTRACT,
761
781 /// No constructor was found because the type was invalid, for instance 762 /// No constructor was found because the type was invalid, for instance
782 /// unresolved, an enum class, a type variable, a typedef or a non-type. 763 /// unresolved, an enum class, a type variable, a typedef or a non-type.
783 INVALID_TYPE, 764 INVALID_TYPE,
765
784 /// No constructor of the sought name was found on the class. 766 /// No constructor of the sought name was found on the class.
785 UNRESOLVED_CONSTRUCTOR, 767 UNRESOLVED_CONSTRUCTOR,
768
786 /// A non-constant constructor was found for a const constructor invocation. 769 /// A non-constant constructor was found for a const constructor invocation.
787 NON_CONSTANT, 770 NON_CONSTANT,
788 } 771 }
789 772
790 /// The (partial) result of the resolution of a new expression used in 773 /// The (partial) result of the resolution of a new expression used in
791 /// [ConstructorResolver]. 774 /// [ConstructorResolver].
792 class ConstructorResult { 775 class ConstructorResult {
793 /// The prefix used to access the constructor. For instance `prefix` in `new 776 /// The prefix used to access the constructor. For instance `prefix` in `new
794 /// prefix.Class.constructorName()`. 777 /// prefix.Class.constructorName()`.
795 final PrefixElement prefix; 778 final PrefixElement prefix;
796 779
797 /// The kind of the found constructor. 780 /// The kind of the found constructor.
798 final ConstructorResultKind kind; 781 final ConstructorResultKind kind;
799 782
800 /// The currently found element. Since [ConstructorResult] is used for partial 783 /// The currently found element. Since [ConstructorResult] is used for partial
801 /// results, this might be a [PrefixElement], a [ClassElement], a 784 /// results, this might be a [PrefixElement], a [ClassElement], a
802 /// [ConstructorElement] or in the negative cases an [ErroneousElement]. 785 /// [ConstructorElement] or in the negative cases an [ErroneousElement].
803 final Element element; 786 final Element element;
804 787
805 /// The type of the new expression. For instance `Foo<String>` in 788 /// The type of the new expression. For instance `Foo<String>` in
806 /// `new prefix.Foo<String>.constructorName()`. 789 /// `new prefix.Foo<String>.constructorName()`.
807 final DartType type; 790 final DartType type;
808 791
809 /// Creates a fully resolved constructor access where [element] is resolved 792 /// Creates a fully resolved constructor access where [element] is resolved
810 /// to a constructor and [type] to an interface type. 793 /// to a constructor and [type] to an interface type.
811 ConstructorResult(this.kind, 794 ConstructorResult(this.kind, this.prefix, ConstructorElement this.element,
812 this.prefix, 795 InterfaceType this.type);
813 ConstructorElement this.element,
814 InterfaceType this.type);
815 796
816 /// Creates a fully resolved constructor access where [element] is an 797 /// Creates a fully resolved constructor access where [element] is an
817 /// [ErroneousElement]. 798 /// [ErroneousElement].
818 // TODO(johnniwinther): Do we still need the prefix for cases like 799 // TODO(johnniwinther): Do we still need the prefix for cases like
819 // `new deferred.Class.unresolvedConstructor()` ? 800 // `new deferred.Class.unresolvedConstructor()` ?
820 ConstructorResult.forError( 801 ConstructorResult.forError(
821 this.kind, ErroneousElement this.element, this.type) 802 this.kind, ErroneousElement this.element, this.type)
822 : prefix = null; 803 : prefix = null;
823 804
824 /// Creates a constructor access that is partially resolved to a prefix. For 805 /// Creates a constructor access that is partially resolved to a prefix. For
(...skipping 30 matching lines...) Expand all
855 sb.write('type=$type'); 836 sb.write('type=$type');
856 } 837 }
857 sb.write(')'); 838 sb.write(')');
858 return sb.toString(); 839 return sb.toString();
859 } 840 }
860 } 841 }
861 842
862 /// Lookup the [constructorName] constructor in [cls] and normalize the result 843 /// Lookup the [constructorName] constructor in [cls] and normalize the result
863 /// with respect to privacy and patching. 844 /// with respect to privacy and patching.
864 ConstructorElement findConstructor( 845 ConstructorElement findConstructor(
865 LibraryElement currentLibrary, 846 LibraryElement currentLibrary, ClassElement cls, String constructorName) {
866 ClassElement cls,
867 String constructorName) {
868 if (Name.isPrivateName(constructorName) && 847 if (Name.isPrivateName(constructorName) &&
869 currentLibrary.library != cls.library) { 848 currentLibrary.library != cls.library) {
870 // TODO(johnniwinther): Report a special error on unaccessible private 849 // TODO(johnniwinther): Report a special error on unaccessible private
871 // constructors. 850 // constructors.
872 return null; 851 return null;
873 } 852 }
874 // TODO(johnniwinther): Use [Name] for lookup. 853 // TODO(johnniwinther): Use [Name] for lookup.
875 ConstructorElement constructor = cls.lookupConstructor(constructorName); 854 ConstructorElement constructor = cls.lookupConstructor(constructorName);
876 if (constructor != null) { 855 if (constructor != null) {
877 constructor = constructor.declaration; 856 constructor = constructor.declaration;
878 } 857 }
879 return constructor; 858 return constructor;
880 } 859 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/class_members.dart ('k') | pkg/compiler/lib/src/resolution/enum_creator.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698