| 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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 if (isFinal) { | 328 if (isFinal) { |
| 329 world.error('duplicate final modifier', mod.span); | 329 world.error('duplicate final modifier', mod.span); |
| 330 } | 330 } |
| 331 isFinal = true; | 331 isFinal = true; |
| 332 } else { | 332 } else { |
| 333 world.error('${mod} modifier not allowed on field', mod.span); | 333 world.error('${mod} modifier not allowed on field', mod.span); |
| 334 } | 334 } |
| 335 } | 335 } |
| 336 } | 336 } |
| 337 type = resolveType(definition.type, false); | 337 type = resolveType(definition.type, false); |
| 338 if (isStatic && type.hasTypeParams) { | 338 if (isStatic && !isFactory && type.hasTypeParams) { |
| 339 world.error('using type parameter in static context', | 339 world.error('using type parameter in static context', |
| 340 definition.type.span); | 340 definition.type.span); |
| 341 } | 341 } |
| 342 | 342 |
| 343 if (isStatic && isFinal && value == null) { | 343 if (isStatic && isFinal && value == null) { |
| 344 world.error('static final field is missing initializer', span); | 344 world.error('static final field is missing initializer', span); |
| 345 } | 345 } |
| 346 | 346 |
| 347 library._addMember(this); | 347 library._addMember(this); |
| 348 } | 348 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 } | 386 } |
| 387 | 387 |
| 388 Value _get(MethodGenerator context, Node node, Value target, | 388 Value _get(MethodGenerator context, Node node, Value target, |
| 389 [bool isDynamic=false]) { | 389 [bool isDynamic=false]) { |
| 390 if (isNative && returnType != null) { | 390 if (isNative && returnType != null) { |
| 391 returnType.markUsed(); | 391 returnType.markUsed(); |
| 392 if (returnType is DefinedType) { | 392 if (returnType is DefinedType) { |
| 393 // TODO(jmesserly): this handles native fields that return types like | 393 // TODO(jmesserly): this handles native fields that return types like |
| 394 // "List". Is there a better solution for fields? Unlike methods we have | 394 // "List". Is there a better solution for fields? Unlike methods we have |
| 395 // no good way to annotate them. | 395 // no good way to annotate them. |
| 396 var factory_ = returnType.genericType.factory_; | 396 var defaultType = returnType.genericType.defaultType; |
| 397 if (factory_ != null && factory_.isNative) { | 397 if (defaultType != null && defaultType.isNative) { |
| 398 factory_.markUsed(); | 398 defaultType.markUsed(); |
| 399 } | 399 } |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 | 402 |
| 403 if (isStatic) { | 403 if (isStatic) { |
| 404 // TODO(jmesserly): can we avoid generating the whole type? | 404 // TODO(jmesserly): can we avoid generating the whole type? |
| 405 declaringType.markUsed(); | 405 declaringType.markUsed(); |
| 406 | 406 |
| 407 // Make sure to compute the value of all static fields, even if we don't | 407 // Make sure to compute the value of all static fields, even if we don't |
| 408 // use this value immediately. | 408 // use this value immediately. |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 } | 664 } |
| 665 } | 665 } |
| 666 | 666 |
| 667 | 667 |
| 668 /** Represents a Dart method or top-level function. */ | 668 /** Represents a Dart method or top-level function. */ |
| 669 class MethodMember extends Member { | 669 class MethodMember extends Member { |
| 670 FunctionDefinition definition; | 670 FunctionDefinition definition; |
| 671 Type returnType; | 671 Type returnType; |
| 672 List<Parameter> parameters; | 672 List<Parameter> parameters; |
| 673 | 673 |
| 674 // Could support generic methods in general. Right now only used for | |
| 675 // strange corner case of factory methods for generic types. | |
| 676 List<ParameterType> typeParameters; | |
| 677 | |
| 678 | |
| 679 Type _functionType; | 674 Type _functionType; |
| 680 bool isStatic = false; | 675 bool isStatic = false; |
| 681 bool isAbstract = false; | 676 bool isAbstract = false; |
| 682 | 677 |
| 683 // Note: these two modifiers are only legal on constructors | 678 // Note: these two modifiers are only legal on constructors |
| 684 bool isConst = false; | 679 bool isConst = false; |
| 685 bool isFactory = false; | 680 bool isFactory = false; |
| 686 | 681 |
| 687 /** True if this is a function defined inside another method. */ | 682 /** True if this is a function defined inside another method. */ |
| 688 bool isLambda = false; | 683 bool isLambda = false; |
| (...skipping 703 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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1797 } | 1777 } |
| 1798 | 1778 |
| 1799 void forEach(void f(Member member)) { | 1779 void forEach(void f(Member member)) { |
| 1800 factories.forEach((_, Map constructors) { | 1780 factories.forEach((_, Map constructors) { |
| 1801 constructors.forEach((_, Member member) { | 1781 constructors.forEach((_, Member member) { |
| 1802 f(member); | 1782 f(member); |
| 1803 }); | 1783 }); |
| 1804 }); | 1784 }); |
| 1805 } | 1785 } |
| 1806 } | 1786 } |
| OLD | NEW |