| 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 |