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

Unified Diff: lib/compiler/implementation/typechecker.dart

Issue 9835007: Typecheck constructor calls. I'm pretty sure about the call to (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add tests to TypeCheckerTest Created 8 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: lib/compiler/implementation/typechecker.dart
diff --git a/lib/compiler/implementation/typechecker.dart b/lib/compiler/implementation/typechecker.dart
index ef555b2a420e88e1cba9224a75c35fbeffce3301..9256e07b3953c8fa8964da9a481b3f2b9f496150 100644
--- a/lib/compiler/implementation/typechecker.dart
+++ b/lib/compiler/implementation/typechecker.dart
@@ -343,11 +343,10 @@ class TypeCheckerVisitor implements Visitor<Type> {
if (member === null) {
classElement.ensureResolved(compiler);
for (Link<Type> supertypes = classElement.allSupertypes;
- !supertypes.isEmpty();
+ !supertypes.isEmpty() && member === null;
supertypes = supertypes.tail) {
ClassElement lookupTarget = supertypes.head.element;
member = lookupTarget.lookupLocalMember(name);
- if (member !== null) return computeType(member);
}
}
if (member !== null && member.kind == ElementKind.FUNCTION) {
@@ -358,13 +357,28 @@ class TypeCheckerVisitor implements Visitor<Type> {
return types.dynamicType;
}
- Link<Type> analyzeArguments(Link<Node> arguments) {
- LinkBuilder<Type> builder = new LinkBuilder<Type>();
- while(!arguments.isEmpty()) {
- builder.addLast(analyze(arguments.head));
- arguments = arguments.tail;
+ void analyzeArguments(Send send, FunctionType funType) {
+ Link<Node> arguments = send.arguments;
+ if (funType === null) {
+ while(!arguments.isEmpty()) {
+ analyze(arguments.head);
+ arguments = arguments.tail;
+ }
+ } else {
+ Link<Type> parameterTypes = funType.parameterTypes;
+ while (!arguments.isEmpty() && !parameterTypes.isEmpty()) {
+ checkAssignable(arguments.head, parameterTypes.head,
+ analyze(arguments.head));
+ arguments = arguments.tail;
+ parameterTypes = parameterTypes.tail;
+ }
+ if (!arguments.isEmpty()) {
+ reportTypeWarning(arguments.head, MessageKind.ADDITIONAL_ARGUMENT);
+ } else if (!parameterTypes.isEmpty()) {
+ reportTypeWarning(send, MessageKind.MISSING_ARGUMENT,
+ [parameterTypes.head]);
+ }
}
- return builder.toLink();
}
Type visitSend(Send node) {
@@ -416,54 +430,38 @@ class TypeCheckerVisitor implements Visitor<Type> {
fail(node.receiver, 'function object invocation unimplemented');
} else {
- Link<Type> argumentTypes = analyzeArguments(node.arguments);
- FunctionType funType;
- if (node.receiver !== null) {
- Type receiverType = analyze(node.receiver);
- if (receiverType === types.dynamicType) return types.dynamicType;
- if (receiverType === null) {
- fail(node.receiver, 'receivertype is null');
- }
- if (receiverType.element.kind !== ElementKind.CLASS) {
- fail(node.receiver, 'receivertype is not a class');
- }
- ClassElement classElement = receiverType.element;
- // TODO(karlklose): substitute type arguments.
- Type memberType =
- lookupMethodType(selector, classElement, selector.source);
- if (memberType === types.dynamicType) return types.dynamicType;
- if (memberType is !FunctionType) {
- fail(node, 'can only handle function types');
- }
- funType = memberType;
- } else {
- Element element = elements[node];
- if (element === null) {
- fail(node, 'unresolved ${node.selector}');
- } else if (element.kind === ElementKind.FUNCTION) {
- funType = computeType(element);
- } else if (element.kind === ElementKind.FOREIGN) {
- return types.dynamicType;
+ FunctionType computeFunType() {
+ if (node.receiver !== null) {
+ Type receiverType = analyze(node.receiver);
+ if (receiverType === types.dynamicType) return null;
+ if (receiverType === null) {
+ fail(node.receiver, 'receivertype is null');
+ }
+ if (receiverType.element.kind !== ElementKind.CLASS) {
+ fail(node.receiver, 'receivertype is not a class');
+ }
+ ClassElement classElement = receiverType.element;
+ // TODO(karlklose): substitute type arguments.
+ Type memberType =
+ lookupMethodType(selector, classElement, selector.source);
+ if (memberType === types.dynamicType) return null;
+ return memberType;
} else {
- fail(node, 'unexpected element kind ${element.kind}');
+ Element element = elements[node];
+ if (element === null) {
+ fail(node, 'unresolved ${node.selector}');
+ } else if (element.kind === ElementKind.FUNCTION) {
+ return computeType(element);
+ } else if (element.kind === ElementKind.FOREIGN) {
+ return null;
+ } else {
+ fail(node, 'unexpected element kind ${element.kind}');
+ }
}
}
- Link<Type> parameterTypes = funType.parameterTypes;
- Link<Node> argumentNodes = node.arguments;
- while (!argumentTypes.isEmpty() && !parameterTypes.isEmpty()) {
- checkAssignable(argumentNodes.head, parameterTypes.head,
- argumentTypes.head);
- argumentTypes = argumentTypes.tail;
- parameterTypes = parameterTypes.tail;
- argumentNodes = argumentNodes.tail;
- }
- if (!argumentTypes.isEmpty()) {
- reportTypeWarning(argumentNodes.head, MessageKind.ADDITIONAL_ARGUMENT);
- } else if (!parameterTypes.isEmpty()) {
- reportTypeWarning(node, MessageKind.MISSING_ARGUMENT,
- [parameterTypes.head]);
- }
- return funType.returnType;
+ FunctionType funType = computeFunType();
+ analyzeArguments(node, funType);
+ return (funType !== null) ? funType.returnType : types.dynamicType;
}
}
@@ -510,6 +508,8 @@ class TypeCheckerVisitor implements Visitor<Type> {
}
Type visitNewExpression(NewExpression node) {
+ Element element = elements[node.send];
+ analyzeArguments(node.send, computeType(element));
return analyze(node.send.selector);
}

Powered by Google App Engine
This is Rietveld 408576698