OLD | NEW |
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 /** A formal parameter to a [Method]. */ | 5 /** A formal parameter to a [Method]. */ |
6 class Parameter { | 6 class Parameter { |
7 FormalNode definition; | 7 FormalNode definition; |
8 Member method; | 8 Member method; |
9 | 9 |
10 String name; | 10 String name; |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 if (isFinal) { | 326 if (isFinal) { |
327 world.error('duplicate final modifier', mod.span); | 327 world.error('duplicate final modifier', mod.span); |
328 } | 328 } |
329 isFinal = true; | 329 isFinal = true; |
330 } else { | 330 } else { |
331 world.error('${mod} modifier not allowed on field', mod.span); | 331 world.error('${mod} modifier not allowed on field', mod.span); |
332 } | 332 } |
333 } | 333 } |
334 } | 334 } |
335 type = resolveType(definition.type, false); | 335 type = resolveType(definition.type, false); |
336 if (isStatic && type.hasTypeParams) { | 336 if (isStatic && !isFactory && type.hasTypeParams) { |
337 world.error('using type parameter in static context', | 337 world.error('using type parameter in static context', |
338 definition.type.span); | 338 definition.type.span); |
339 } | 339 } |
340 | 340 |
341 if (isStatic && isFinal && value == null) { | 341 if (isStatic && isFinal && value == null) { |
342 world.error('static final field is missing initializer', span); | 342 world.error('static final field is missing initializer', span); |
343 } | 343 } |
344 | 344 |
345 library._addMember(this); | 345 library._addMember(this); |
346 } | 346 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 } | 384 } |
385 | 385 |
386 Value _get(MethodGenerator context, Node node, Value target, | 386 Value _get(MethodGenerator context, Node node, Value target, |
387 [bool isDynamic=false]) { | 387 [bool isDynamic=false]) { |
388 if (isNative && returnType != null) { | 388 if (isNative && returnType != null) { |
389 returnType.markUsed(); | 389 returnType.markUsed(); |
390 if (returnType is DefinedType) { | 390 if (returnType is DefinedType) { |
391 // TODO(jmesserly): this handles native fields that return types like | 391 // TODO(jmesserly): this handles native fields that return types like |
392 // "List". Is there a better solution for fields? Unlike methods we have | 392 // "List". Is there a better solution for fields? Unlike methods we have |
393 // no good way to annotate them. | 393 // no good way to annotate them. |
394 var factory_ = returnType.genericType.factory_; | 394 var defaultType = returnType.genericType.defaultType; |
395 if (factory_ != null && factory_.isNative) { | 395 if (defaultType != null && defaultType.isNative) { |
396 factory_.markUsed(); | 396 defaultType.markUsed(); |
397 } | 397 } |
398 } | 398 } |
399 } | 399 } |
400 | 400 |
401 if (isStatic) { | 401 if (isStatic) { |
402 // TODO(jmesserly): can we avoid generating the whole type? | 402 // TODO(jmesserly): can we avoid generating the whole type? |
403 declaringType.markUsed(); | 403 declaringType.markUsed(); |
404 | 404 |
405 // Make sure to compute the value of all static fields, even if we don't | 405 // Make sure to compute the value of all static fields, even if we don't |
406 // use this value immediately. | 406 // use this value immediately. |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 } | 668 } |
669 } | 669 } |
670 | 670 |
671 | 671 |
672 /** Represents a Dart method or top-level function. */ | 672 /** Represents a Dart method or top-level function. */ |
673 class MethodMember extends Member { | 673 class MethodMember extends Member { |
674 FunctionDefinition definition; | 674 FunctionDefinition definition; |
675 Type returnType; | 675 Type returnType; |
676 List<Parameter> parameters; | 676 List<Parameter> parameters; |
677 | 677 |
678 // Could support generic methods in general. Right now only used for | |
679 // strange corner case of factory methods for generic types. | |
680 List<ParameterType> typeParameters; | |
681 | |
682 | |
683 Type _functionType; | 678 Type _functionType; |
684 bool isStatic = false; | 679 bool isStatic = false; |
685 bool isAbstract = false; | 680 bool isAbstract = false; |
686 | 681 |
687 // Note: these two modifiers are only legal on constructors | 682 // Note: these two modifiers are only legal on constructors |
688 bool isConst = false; | 683 bool isConst = false; |
689 bool isFactory = false; | 684 bool isFactory = false; |
690 | 685 |
691 /** True if this is a function defined inside another method. */ | 686 /** True if this is a function defined inside another method. */ |
692 bool isLambda = false; | 687 bool isLambda = false; |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 } else { | 1387 } else { |
1393 world.error('${mod} modifier not allowed on method', mod.span); | 1388 world.error('${mod} modifier not allowed on method', mod.span); |
1394 } | 1389 } |
1395 } | 1390 } |
1396 } | 1391 } |
1397 | 1392 |
1398 if (isFactory) { | 1393 if (isFactory) { |
1399 isStatic = true; | 1394 isStatic = true; |
1400 } | 1395 } |
1401 | 1396 |
1402 if (definition.typeParameters != null) { | |
1403 if (!isFactory) { | |
1404 world.error( | |
1405 'Only factories are allowed to have explicit type parameters', | |
1406 definition.typeParameters[0].span); | |
1407 } else { | |
1408 typeParameters = definition.typeParameters; | |
1409 for (var tp in definition.typeParameters) { | |
1410 tp.enclosingElement = this; | |
1411 tp.resolve(); | |
1412 } | |
1413 } | |
1414 } | |
1415 | |
1416 // TODO(jimhug): need a better annotation for being an operator method | 1397 // TODO(jimhug): need a better annotation for being an operator method |
1417 if (isOperator && isStatic && !isCallMethod) { | 1398 if (isOperator && isStatic && !isCallMethod) { |
1418 world.error('operator method may not be static "${name}"', span); | 1399 world.error('operator method may not be static "${name}"', span); |
1419 } | 1400 } |
1420 | 1401 |
1421 if (isAbstract) { | 1402 if (isAbstract) { |
1422 if (definition.body != null && | 1403 if (definition.body != null && |
1423 declaringType.definition is! FunctionTypeDefinition) { | 1404 declaringType.definition is! FunctionTypeDefinition) { |
1424 // TODO(jimhug): Creating function types for concrete methods is | 1405 // TODO(jimhug): Creating function types for concrete methods is |
1425 // steadily feeling uglier... | 1406 // steadily feeling uglier... |
(...skipping 23 matching lines...) Expand all Loading... |
1449 } | 1430 } |
1450 | 1431 |
1451 if (!isLambda) { | 1432 if (!isLambda) { |
1452 library._addMember(this); | 1433 library._addMember(this); |
1453 } | 1434 } |
1454 } | 1435 } |
1455 | 1436 |
1456 /** Overriden to ensure that type arguments aren't used in static methods. */ | 1437 /** Overriden to ensure that type arguments aren't used in static methods. */ |
1457 Type resolveType(TypeReference node, bool typeErrors) { | 1438 Type resolveType(TypeReference node, bool typeErrors) { |
1458 Type t = super.resolveType(node, typeErrors); | 1439 Type t = super.resolveType(node, typeErrors); |
1459 if (isStatic && t is ParameterType && | 1440 if (isStatic && !isFactory && t is ParameterType) { |
1460 (typeParameters == null || !typeParameters.some((p) => p === t))) { | |
1461 world.error('using type parameter in static context.', node.span); | 1441 world.error('using type parameter in static context.', node.span); |
1462 } | 1442 } |
1463 return t; | 1443 return t; |
1464 } | 1444 } |
1465 } | 1445 } |
1466 | 1446 |
1467 | 1447 |
1468 class MemberSet { | 1448 class MemberSet { |
1469 final String name; | 1449 final String name; |
1470 final List<Member> members; | 1450 final List<Member> members; |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 } | 1770 } |
1791 | 1771 |
1792 void forEach(void f(Member member)) { | 1772 void forEach(void f(Member member)) { |
1793 factories.forEach((_, Map constructors) { | 1773 factories.forEach((_, Map constructors) { |
1794 constructors.forEach((_, Member member) { | 1774 constructors.forEach((_, Member member) { |
1795 f(member); | 1775 f(member); |
1796 }); | 1776 }); |
1797 }); | 1777 }); |
1798 } | 1778 } |
1799 } | 1779 } |
OLD | NEW |