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

Side by Side Diff: frog/member.dart

Issue 8478025: Restore r1383: Fix method resolution to warn about things that don't exist on the declared type. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month 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
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 /** 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 8
9 String name; 9 String name;
10 Type type; 10 Type type;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 Library get library() => declaringType.library; 108 Library get library() => declaringType.library;
109 109
110 bool get isPrivate() => name.startsWith('_'); 110 bool get isPrivate() => name.startsWith('_');
111 111
112 bool get isConstructor() => false; 112 bool get isConstructor() => false;
113 bool get isField() => false; 113 bool get isField() => false;
114 bool get isMethod() => false; 114 bool get isMethod() => false;
115 bool get isProperty() => false; 115 bool get isProperty() => false;
116 bool get isAbstract() => false; 116 bool get isAbstract() => false;
117 117
118 // TODO(jmesserly): these only makes sense on methods, but because of
119 // ConcreteMember we need to support them on Member.
120 bool get isConst() => false;
121 bool get isFactory() => false;
122
118 bool get prefersPropertySyntax() => true; 123 bool get prefersPropertySyntax() => true;
119 bool get requiresFieldSyntax() => false; 124 bool get requiresFieldSyntax() => false;
120 125
121 bool get isNative() => false; 126 bool get isNative() => false;
122 String get constructorName() => 127 String get constructorName() =>
123 world.internalError('can not be a constructor', span); 128 world.internalError('can not be a constructor', span);
124 129
125 void provideFieldSyntax() => world.internalError('can not be field', span); 130 void provideFieldSyntax() => world.internalError('can not be field', span);
126 void providePropertySyntax() => 131 void providePropertySyntax() =>
127 world.internalError('can not be property', span); 132 world.internalError('can not be property', span);
133
134 Definition get initDelegate() =>
135 world.internalError('cannot have initializers', span);
136 Definition set initDelegate(ctor) =>
137 world.internalError('cannot have initializers', span);
128 138
129 Definition get definition() => null; 139 Definition get definition() => null;
130 140
131 List<Parameter> get parameters() => []; 141 List<Parameter> get parameters() => [];
132 142
133 // TODO(jimhug): Fix these names once get/set are truly pseudo-keywords. 143 // TODO(jimhug): Fix these names once get/set are truly pseudo-keywords.
134 // TODO(jmesserly): isDynamic isn't a great name for this, something better? 144 // TODO(jmesserly): isDynamic isn't a great name for this, something better?
135 abstract Value get_(MethodGenerator context, Node node, Value target, 145 abstract Value get_(MethodGenerator context, Node node, Value target,
136 [bool isDynamic]); 146 [bool isDynamic]);
137 147
(...skipping 24 matching lines...) Expand all
162 172
163 String get generatedFactoryName() { 173 String get generatedFactoryName() {
164 assert(this.isFactory); 174 assert(this.isFactory);
165 String prefix = '${declaringType.jsname}.${constructorName}\$'; 175 String prefix = '${declaringType.jsname}.${constructorName}\$';
166 if (name == '') { 176 if (name == '') {
167 return '${prefix}factory'; 177 return '${prefix}factory';
168 } else { 178 } else {
169 return '${prefix}$name\$factory'; 179 return '${prefix}$name\$factory';
170 } 180 }
171 } 181 }
182
183 Type resolveType(TypeReference node, bool isRequired) {
184 var type = declaringType.resolveType(node, isRequired);
185 if (isStatic && type.hasTypeParams) {
186 // TODO(jimhug): Is this really so hard?
187 world.error('using type parameter in static context',
188 node.span);
189 }
190 return type;
191 }
172 } 192 }
173 193
174 194
175 /** 195 /**
176 * Types are treated as first class members of their library's top type. 196 * Types are treated as first class members of their library's top type.
177 */ 197 */
178 // TODO(jmesserly): perhaps Type should extend Member, but that can get 198 // TODO(jmesserly): perhaps Type should extend Member, but that can get
179 // complicated. 199 // complicated.
180 class TypeMember extends Member { 200 class TypeMember extends Member {
181 final DefinedType type; 201 final DefinedType type;
182 202
183 TypeMember(DefinedType type) 203 TypeMember(DefinedType type)
184 : super(type.name, type.library.topType), 204 : super(type.name, type.library.topType),
185 this.type = type; 205 this.type = type;
186 206
187 SourceSpan get span() => type.definition.span; 207 SourceSpan get span() => type.definition.span;
188 208
189 bool get isStatic() => true; 209 bool get isStatic() => true;
190 210
191 // If this really becomes first class, this should return typeof(Type) 211 // If this really becomes first class, this should return typeof(Type)
192 Type get returnType() => world.isVar; 212 Type get returnType() => world.varType;
193 213
194 bool canInvoke(MethodGenerator context, Arguments args) => false; 214 bool canInvoke(MethodGenerator context, Arguments args) => false;
195 bool get canGet() => true; 215 bool get canGet() => true;
196 bool get canSet() => false; 216 bool get canSet() => false;
197 217
198 void resolve(Type inType) {} 218 void resolve(Type inType) {}
199 219
200 Value get_(MethodGenerator context, Node node, Value target, 220 Value get_(MethodGenerator context, Node node, Value target,
201 [bool isDynamic=false]) { 221 [bool isDynamic=false]) {
202 assert(target == null || target.type.isTop); 222 assert(target == null || target.type.isTop);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 if (isFinal) { 379 if (isFinal) {
360 return cv; 380 return cv;
361 } 381 }
362 if (declaringType.isTop) { 382 if (declaringType.isTop) {
363 return new Value(type, '$jsname'); 383 return new Value(type, '$jsname');
364 } else { 384 } else {
365 return new Value(type, '${declaringType.jsname}.$jsname'); 385 return new Value(type, '${declaringType.jsname}.$jsname');
366 } 386 }
367 } else if (target.isConst && isFinal) { 387 } else if (target.isConst && isFinal) {
368 // take advantage of consts and retrieve the value directly if possible 388 // take advantage of consts and retrieve the value directly if possible
369 var constTarget = target is GlobalValue ? target.exp : target; 389 var constTarget = target is GlobalValue ? target.dynamic.exp : target;
370 if (constTarget is ConstObjectValue) { 390 if (constTarget is ConstObjectValue) {
371 return constTarget.fields[name]; 391 return constTarget.fields[name];
372 } else if (constTarget.type == world.stringType && name == 'length') { 392 } else if (constTarget.type == world.stringType && name == 'length') {
373 return new Value(type, '${constTarget.actualValue.length}'); 393 return new Value(type, '${constTarget.actualValue.length}');
374 } 394 }
375 } 395 }
376 return new Value(type, '${target.code}.$jsname'); 396 return new Value(type, '${target.code}.$jsname');
377 } 397 }
378 398
379 Value set_(MethodGenerator context, Node node, Value target, Value value, 399 Value set_(MethodGenerator context, Node node, Value target, Value value,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 } 471 }
452 return target.invokeNoSuchMethod(context, 'set:$name', node, 472 return target.invokeNoSuchMethod(context, 'set:$name', node,
453 new Arguments(null, [value])); 473 new Arguments(null, [value]));
454 } 474 }
455 return setter.invoke(context, node, target, new Arguments(null, [value]), 475 return setter.invoke(context, node, target, new Arguments(null, [value]),
456 isDynamic); 476 isDynamic);
457 } 477 }
458 478
459 addFromParent(Member parentMember) { 479 addFromParent(Member parentMember) {
460 // TODO(jimhug): Egregious Hack! 480 // TODO(jimhug): Egregious Hack!
481 PropertyMember parent;
461 if (parentMember is ConcreteMember) { 482 if (parentMember is ConcreteMember) {
462 parentMember = parentMember.baseMember; 483 ConcreteMember c = parentMember;
484 parent = c.baseMember;
485 } else {
486 parent = parentMember;
463 } 487 }
464 488
465 if (getter == null) getter = parentMember.getter; 489 if (getter == null) getter = parent.getter;
466 if (setter == null) setter = parentMember.setter; 490 if (setter == null) setter = parent.setter;
467 } 491 }
468 492
469 resolve(Type inType) { 493 resolve(Type inType) {
470 if (getter != null) getter.resolve(inType); 494 if (getter != null) getter.resolve(inType);
471 if (setter != null) setter.resolve(inType); 495 if (setter != null) setter.resolve(inType);
472 496
473 library._addMember(this); 497 library._addMember(this);
474 } 498 }
475 } 499 }
476 500
(...skipping 16 matching lines...) Expand all
493 parameters.add(p); 517 parameters.add(p);
494 } 518 }
495 } 519 }
496 } 520 }
497 521
498 SourceSpan get span() => baseMember.span; 522 SourceSpan get span() => baseMember.span;
499 523
500 bool get isStatic() => baseMember.isStatic; 524 bool get isStatic() => baseMember.isStatic;
501 bool get isAbstract() => baseMember.isAbstract; 525 bool get isAbstract() => baseMember.isAbstract;
502 bool get isConst() => baseMember.isConst; 526 bool get isConst() => baseMember.isConst;
527 bool get isFactory() => baseMember.isFactory;
503 528
504 String get jsname() => baseMember.jsname; 529 String get jsname() => baseMember.jsname;
505 set jsname(String name) => 530 set jsname(String name) =>
506 world.internalError('bad set of jsname on ConcreteMember'); 531 world.internalError('bad set of jsname on ConcreteMember');
507 532
508 bool get isFactory() => baseMember.isFactory;
509 533
510 bool get canGet() => baseMember.canGet; 534 bool get canGet() => baseMember.canGet;
511 bool get canSet() => baseMember.canSet; 535 bool get canSet() => baseMember.canSet;
512 bool canInvoke(MethodGenerator context, Arguments args) => 536 bool canInvoke(MethodGenerator context, Arguments args) =>
513 baseMember.canInvoke(context, args); 537 baseMember.canInvoke(context, args);
514 538
515 bool get isField() => baseMember.isField; 539 bool get isField() => baseMember.isField;
516 bool get isMethod() => baseMember.isMethod; 540 bool get isMethod() => baseMember.isMethod;
517 bool get isProperty() => baseMember.isProperty; 541 bool get isProperty() => baseMember.isProperty;
518 542
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 bool get isMethod() => !isConstructor; 633 bool get isMethod() => !isConstructor;
610 634
611 bool get isNative() => definition.body is NativeStatement; 635 bool get isNative() => definition.body is NativeStatement;
612 636
613 bool get canGet() => false; // TODO(jimhug): get bound method support. 637 bool get canGet() => false; // TODO(jimhug): get bound method support.
614 bool get canSet() => false; 638 bool get canSet() => false;
615 639
616 SourceSpan get span() => definition == null ? null : definition.span; 640 SourceSpan get span() => definition == null ? null : definition.span;
617 641
618 String get constructorName() { 642 String get constructorName() {
619 if (definition.returnType == null) return ''; 643 NameTypeReference returnType = definition.returnType;
644 if (returnType == null) return '';
620 645
621 // TODO(jmesserly): make this easier? 646 // TODO(jmesserly): make this easier?
622 if (definition.returnType.names != null) { 647 if (returnType.names != null) {
623 return definition.returnType.names[0].name; 648 return returnType.names[0].name;
624 } else if (definition.returnType.name != null) { 649 } else if (returnType.name != null) {
625 return definition.returnType.name.name; 650 return returnType.name.name;
626 } 651 }
627 world.internalError('no valid constructor name', definition.span); 652 world.internalError('no valid constructor name', definition.span);
628 } 653 }
629 654
630 Type get functionType() { 655 Type get functionType() {
631 if (_functionType == null) { 656 if (_functionType == null) {
632 _functionType = library.getOrAddFunctionType(name, 657 _functionType = library.getOrAddFunctionType(name,
633 definition, declaringType); 658 definition, declaringType);
634 // TODO(jimhug): Better resolution checks. 659 // TODO(jimhug): Better resolution checks.
635 if (parameters == null) { 660 if (parameters == null) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 int indexOfParameter(String name) { 704 int indexOfParameter(String name) {
680 for (int i = 0; i < parameters.length; i++) { 705 for (int i = 0; i < parameters.length; i++) {
681 final p = parameters[i]; 706 final p = parameters[i];
682 if (p.isOptional && p.name == name) { 707 if (p.isOptional && p.name == name) {
683 return i; 708 return i;
684 } 709 }
685 } 710 }
686 return -1; 711 return -1;
687 } 712 }
688 713
689 Type resolveType(TypeReference node, bool isRequired) {
690 var type = declaringType.resolveType(node, isRequired);
691 if (isStatic && type.hasTypeParams) {
692 // TODO(jimhug): Is this really so hard?
693 world.error('using type parameter in static context',
694 node.span);
695 }
696 return type;
697 }
698
699 bool get prefersPropertySyntax() => true; 714 bool get prefersPropertySyntax() => true;
700 bool get requiresFieldSyntax() => false; 715 bool get requiresFieldSyntax() => false;
701 716
702 void provideFieldSyntax() => _provideFieldSyntax = true; 717 void provideFieldSyntax() => _provideFieldSyntax = true;
703 void providePropertySyntax() => _providePropertySyntax = true; 718 void providePropertySyntax() => _providePropertySyntax = true;
704 719
705 Value set_(MethodGenerator context, Node, Value target, Value value, 720 Value set_(MethodGenerator context, Node, Value target, Value value,
706 [bool isDynamic=false]) { 721 [bool isDynamic=false]) {
707 world.error('can not set method', definition.span); 722 world.error('can not set method', definition.span);
708 } 723 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 return new Value(returnType, '$jsname($argsString)'); 918 return new Value(returnType, '$jsname($argsString)');
904 } 919 }
905 return new Value(returnType, 920 return new Value(returnType,
906 '${declaringType.jsname}.$jsname($argsString)'); 921 '${declaringType.jsname}.$jsname($argsString)');
907 } 922 }
908 923
909 var code = '${target.code}.$jsname($argsString)'; 924 var code = '${target.code}.$jsname($argsString)';
910 // optimize expressions which we know statically their value. 925 // optimize expressions which we know statically their value.
911 if (target.isConst) { 926 if (target.isConst) {
912 if (target is GlobalValue) { 927 if (target is GlobalValue) {
913 target = target.exp; 928 target = target.dynamic.exp; // TODO: an inline "cast" would be nice.
914 } 929 }
915 if (name == 'get\$length') { 930 if (name == 'get\$length') {
916 if (target is ConstListValue || target is ConstMapValue) { 931 if (target is ConstListValue || target is ConstMapValue) {
917 code = '${target.values.length}'; 932 code = '${target.dynamic.values.length}';
918 } 933 }
919 } else if (name == 'isEmpty') { 934 } else if (name == 'isEmpty') {
920 if (target is ConstListValue || target is ConstMapValue) { 935 if (target is ConstListValue || target is ConstMapValue) {
921 code = '${target.values.isEmpty()}'; 936 code = '${target.dynamic.values.isEmpty()}';
922 } 937 }
923 } 938 }
924 } 939 }
925 940
926 // TODO(jmesserly): factor this better 941 // TODO(jmesserly): factor this better
927 if (name == 'get\$typeName' && declaringType.library == world.dom) { 942 if (name == 'get\$typeName' && declaringType.library == world.dom) {
928 world.gen.corejs.useTypeNameOf = true; 943 world.gen.corejs.useTypeNameOf = true;
929 } 944 }
930 945
931 return new Value(returnType, code); 946 return new Value(returnType, code);
932 } 947 }
933 948
934 Value _invokeConstructor(MethodGenerator context, Node node, Value target, 949 Value _invokeConstructor(MethodGenerator context, Node node,
935 Arguments args, argsString) { 950 Value target, Arguments args, argsString) {
936 declaringType.markUsed(); 951 declaringType.markUsed();
937 952
938 if (target != null) { 953 if (target != null) {
939 // initializer call to another constructor 954 // initializer call to another constructor
940 var code = (constructorName != '') 955 var code = (constructorName != '')
941 ? '${declaringType.jsname}.${constructorName}\$ctor.call($argsString)' 956 ? '${declaringType.jsname}.${constructorName}\$ctor.call($argsString)'
942 : '${declaringType.jsname}.call($argsString)'; 957 : '${declaringType.jsname}.call($argsString)';
943 return new Value(declaringType, code); 958 return new Value(declaringType, code);
944 } else { 959 } else {
945 var code = (constructorName != '') 960 var code = (constructorName != '')
946 ? 'new ${declaringType.jsname}.${constructorName}\$ctor($argsString)' 961 ? 'new ${declaringType.jsname}.${constructorName}\$ctor($argsString)'
947 : 'new ${declaringType.jsname}($argsString)'; 962 : 'new ${declaringType.jsname}($argsString)';
948 if (isConst && node.isConst) { 963 // TODO(jmesserly): using the "node" here feels really hacky
964 if (isConst && node is NewExpression && node.dynamic.isConst) {
949 return _invokeConstConstructor(node, code, target, args); 965 return _invokeConstConstructor(node, code, target, args);
950 } else { 966 } else {
951 return new Value(declaringType, code); 967 return new Value(declaringType, code);
952 } 968 }
953 } 969 }
954 } 970 }
955 971
956 /** 972 /**
957 * Special handling for const constructors so that so that: 973 * Special handling for const constructors so that so that:
958 * [: const B() === const B.a(0, 1) === const B.b(0) :] 974 * [: const B() === const B.a(0, 1) === const B.b(0) :]
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 // Super-call: embed the value the super class fields. 1041 // Super-call: embed the value the super class fields.
1026 if (value is GlobalValue) { 1042 if (value is GlobalValue) {
1027 value = value.exp; 1043 value = value.exp;
1028 } 1044 }
1029 for (var fname in value.fields.getKeys()) { 1045 for (var fname in value.fields.getKeys()) {
1030 fields[fname] = value.fields[fname]; 1046 fields[fname] = value.fields[fname];
1031 } 1047 }
1032 } 1048 }
1033 } else { 1049 } else {
1034 // Normal field initializer assignment. 1050 // Normal field initializer assignment.
1035 var fname = init.x.name.name; 1051 BinaryExpression assign = init;
1036 var val = generator.visitValue(init.y); 1052 VarExpression x = assign.x;
1053 var fname = x.name.name;
1054 var val = generator.visitValue(assign.y);
1037 fields[fname] = val; 1055 fields[fname] = val;
1038 } 1056 }
1039 } 1057 }
1040 1058
1041 generator._popBlock(); 1059 generator._popBlock();
1042 } 1060 }
1043 1061
1044 // Add default values only if they weren't overriden in the constructor. 1062 // Add default values only if they weren't overriden in the constructor.
1045 for (var f in declaringType.members.getValues()) { 1063 for (var f in declaringType.members.getValues()) {
1046 if (f is FieldMember && !f.isStatic && f.value != null 1064 if (f is FieldMember && !f.isStatic && f.value != null
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 } 1561 }
1544 1562
1545 void forEach(void f(Member member)) { 1563 void forEach(void f(Member member)) {
1546 factories.forEach((_, Map constructors) { 1564 factories.forEach((_, Map constructors) {
1547 constructors.forEach((_, Member member) { 1565 constructors.forEach((_, Member member) {
1548 f(member); 1566 f(member);
1549 }); 1567 });
1550 }); 1568 });
1551 } 1569 }
1552 } 1570 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698