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

Side by Side Diff: frog/leg/elements/elements.dart

Issue 9243011: Implement named constructors and resolving of redirecting constructors and super-initializers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Move constructor name creation to lookup function. Created 8 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | frog/leg/emitter.dart » ('j') | frog/leg/scanner/class_element_parser.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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('elements'); 5 #library('elements');
6 6
7 #import('../tree/tree.dart'); 7 #import('../tree/tree.dart');
8 #import('../scanner/scannerlib.dart'); 8 #import('../scanner/scannerlib.dart');
9 #import('../leg.dart'); // TODO(karlklose): we only need type. 9 #import('../leg.dart'); // TODO(karlklose): we only need type.
10 #import('../util/util.dart'); 10 #import('../util/util.dart');
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 return element.computeType(compiler); 202 return element.computeType(compiler);
203 } 203 }
204 return types.lookup(name); 204 return types.lookup(name);
205 } 205 }
206 206
207 class FunctionElement extends Element { 207 class FunctionElement extends Element {
208 Link<Element> parameters; 208 Link<Element> parameters;
209 FunctionExpression cachedNode; 209 FunctionExpression cachedNode;
210 Type type; 210 Type type;
211 final Modifiers modifiers; 211 final Modifiers modifiers;
212 int cachedParameterCount;
212 213
213 FunctionElement(SourceString name, 214 FunctionElement(SourceString name,
214 ElementKind kind, 215 ElementKind kind,
215 Modifiers this.modifiers, 216 Modifiers this.modifiers,
216 Element enclosing, 217 Element enclosing,
217 [Node node]) 218 [Node node])
218 : super(name, kind, enclosing), cachedNode = node; 219 : super(name, kind, enclosing), cachedNode = node;
219 FunctionElement.node(FunctionExpression node, 220 FunctionElement.node(SourceString name,
221 FunctionExpression node,
220 ElementKind kind, 222 ElementKind kind,
221 Modifiers this.modifiers, 223 Modifiers this.modifiers,
222 Element enclosing) 224 Element enclosing)
223 : super(node.name.asIdentifier().source, kind, enclosing), 225 : super(name, kind, enclosing),
224 this.cachedNode = node; 226 this.cachedNode = node;
225 227
226 bool isInstanceMember() { 228 bool isInstanceMember() {
227 return isMember() 229 return isMember()
228 && kind != ElementKind.GENERATIVE_CONSTRUCTOR 230 && kind != ElementKind.GENERATIVE_CONSTRUCTOR
229 && !modifiers.isFactory() 231 && !modifiers.isFactory()
230 && !modifiers.isStatic(); 232 && !modifiers.isStatic();
231 } 233 }
232 234
235 int parameterCount(Compiler compiler) {
236 if (cachedParameterCount === null) {
237 cachedParameterCount = 0;
238 if (parameters == null) compiler.resolveSignature(this);
239 for (Link l = parameters; !l.isEmpty(); l = l.tail) {
240 cachedParameterCount++;
241 }
242 }
243 return cachedParameterCount;
244 }
245
233 FunctionType computeType(Compiler compiler) { 246 FunctionType computeType(Compiler compiler) {
234 if (type != null) return type; 247 if (type != null) return type;
235 if (parameters == null) compiler.resolveSignature(this); 248 if (parameters == null) compiler.resolveSignature(this);
236 Types types = compiler.types; 249 Types types = compiler.types;
237 FunctionExpression node = 250 FunctionExpression node =
238 compiler.parser.measure(() => parseNode(compiler, compiler)); 251 compiler.parser.measure(() => parseNode(compiler, compiler));
239 Type returnType = getType(node.returnType, compiler, types); 252 Type returnType = getType(node.returnType, compiler, types);
240 if (returnType === null) returnType = types.dynamicType; 253 if (returnType === null) returnType = types.dynamicType;
241 254
242 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); 255 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 new Block(new NodeList.empty()), 309 new Block(new NodeList.empty()),
297 null, null, null); 310 null, null, null);
298 return cachedNode; 311 return cachedNode;
299 } 312 }
300 } 313 }
301 314
302 class ClassElement extends Element { 315 class ClassElement extends Element {
303 Type type; 316 Type type;
304 Type supertype; 317 Type supertype;
305 Link<Element> members = const EmptyLink<Element>(); 318 Link<Element> members = const EmptyLink<Element>();
319 Map<SourceString, Element> localMembers;
320 Map<SourceString, Element> constructors;
306 Link<Type> interfaces = const EmptyLink<Type>(); 321 Link<Type> interfaces = const EmptyLink<Type>();
307 bool isResolved = false; 322 bool isResolved = false;
308 // backendMembers are members that have been added by the backend to simplify 323 // backendMembers are members that have been added by the backend to simplify
309 // compilation. They don't have any user-side counter-part. 324 // compilation. They don't have any user-side counter-part.
310 Link<Element> backendMembers = const EmptyLink<Element>(); 325 Link<Element> backendMembers = const EmptyLink<Element>();
311 SynthesizedConstructorElement synthesizedConstructor; 326 SynthesizedConstructorElement synthesizedConstructor;
312 327
313 ClassElement(SourceString name, CompilationUnitElement enclosing) 328 ClassElement(SourceString name, CompilationUnitElement enclosing)
314 : super(name, ElementKind.CLASS, enclosing); 329 : localMembers = new Map<SourceString, Element>(),
330 constructors = new Map<SourceString, Element>(),
331 super(name, ElementKind.CLASS, enclosing);
315 332
316 void addMember(Element element) { 333 void addMember(Element element) {
317 members = members.prepend(element); 334 members = members.prepend(element);
335 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
336 element.modifiers.isFactory()) {
337 constructors[element.name] = element;
338 } else {
339 localMembers[element.name] = element;
340 }
318 } 341 }
319 342
320 Type computeType(compiler) { 343 Type computeType(compiler) {
321 if (type === null) { 344 if (type === null) {
322 type = new SimpleType(name, this); 345 type = new SimpleType(name, this);
323 } 346 }
324 return type; 347 return type;
325 } 348 }
326 349
327 ClassElement resolve(Compiler compiler) { 350 ClassElement resolve(Compiler compiler) {
328 if (!isResolved) { 351 if (!isResolved) {
329 compiler.resolveType(this); 352 compiler.resolveType(this);
330 isResolved = true; 353 isResolved = true;
331 } 354 }
332 return this; 355 return this;
333 } 356 }
334 357
335 Element lookupLocalElement(SourceString name, bool matches(Element)) { 358 Element lookupLocalMember(SourceString name) {
336 // TODO(karlklose): replace with more efficient solution. 359 return localMembers[name];
337 for (Link<Element> link = members;
338 link !== null && !link.isEmpty();
339 link = link.tail) {
340 Element element = link.head;
341 if (matches(element)) return element;
342 }
343 return null;
344 } 360 }
345 361
346 Element lookupLocalMember(SourceString name) { 362 Element lookupConstructor(SourceString className,
347 bool matches(Element element) { 363 [SourceString constructor = const SourceString(''),
ngeoffray 2012/01/20 13:54:17 constructor -> constructorName?
karlklose 2012/01/20 14:11:36 Done.
348 return element.name == name 364 Element noMatch(Element)]) {
349 && element.kind != ElementKind.GENERATIVE_CONSTRUCTOR; 365 // TODO(karlklose): have a map from class names to a map of constructors
366 // instead of creating the name here?
367 SourceString name;
368 if (constructor !== const SourceString('')) {
369 name = new SourceString('$className.$constructor');
370 } else {
371 name = className;
350 } 372 }
351 return lookupLocalElement(name, matches); 373 Element result = constructors[name];
374 if (result === null && noMatch !== null) {
375 result = noMatch(lookupLocalMember(name));
ngeoffray 2012/01/20 13:54:17 Shouldn't you check for constructorName if it is n
karlklose 2012/01/20 14:11:36 Done.
376 }
377 return result;
352 } 378 }
353 379
354 Element lookupConstructor(SourceString name) { 380 bool canHaveDefaultConstructor() => constructors.length == 0;
355 bool matches(Element element) {
356 return element.name == name
357 && (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR
358 || element.modifiers.isFactory());
359 }
360 return lookupLocalElement(name, matches);
361 }
362
363 // TODO(ngeoffray): Implement these.
364 bool canHaveDefaultConstructor() => true;
365 381
366 SynthesizedConstructorElement getSynthesizedConstructor() { 382 SynthesizedConstructorElement getSynthesizedConstructor() {
367 if (synthesizedConstructor === null && canHaveDefaultConstructor()) { 383 if (synthesizedConstructor === null && canHaveDefaultConstructor()) {
368 synthesizedConstructor = new SynthesizedConstructorElement(this); 384 synthesizedConstructor = new SynthesizedConstructorElement(this);
369 } 385 }
370 return synthesizedConstructor; 386 return synthesizedConstructor;
371 } 387 }
372 388
373 /** 389 /**
374 * Returns the super class, if any. 390 * Returns the super class, if any.
(...skipping 29 matching lines...) Expand all
404 if (send.isPropertyAccess) return false; 420 if (send.isPropertyAccess) return false;
405 if (send.receiver !== null) return false; 421 if (send.receiver !== null) return false;
406 Element element = elements[send]; 422 Element element = elements[send];
407 // (o)() or foo()(). 423 // (o)() or foo()().
408 if (element === null && send.selector.asIdentifier() === null) return true; 424 if (element === null && send.selector.asIdentifier() === null) return true;
409 if (element === null) return false; 425 if (element === null) return false;
410 // foo() with foo a local or a parameter. 426 // foo() with foo a local or a parameter.
411 return element.isVariable() || element.isParameter(); 427 return element.isVariable() || element.isParameter();
412 } 428 }
413 } 429 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/emitter.dart » ('j') | frog/leg/scanner/class_element_parser.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698