Compute function types together with the parameters.

This avoids resolving the types of arguments twice.

Review URL: https://chromiumcodereview.appspot.com//10363003

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@7374 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
karlklose@google.com
2012-05-07 12:33:09 +00:00
parent 61f38fde3b
commit e205b4fdb0
11 changed files with 63 additions and 65 deletions
@@ -1043,7 +1043,7 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
*/
void assignArgumentsToParameters(List<Constant> arguments) {
// Assign arguments to parameters.
FunctionParameters parameters = constructor.computeParameters(compiler);
FunctionSignature parameters = constructor.computeSignature(compiler);
int index = 0;
parameters.forEachParameter((Element parameter) {
Constant argument = arguments[index++];
+2 -2
View File
@@ -292,7 +292,7 @@ class Compiler implements DiagnosticListener {
cancel('main is not a function', element: main);
}
FunctionElement mainMethod = main;
FunctionParameters parameters = mainMethod.computeParameters(this);
FunctionSignature parameters = mainMethod.computeSignature(this);
if (parameters.parameterCount > 0) {
cancel('main cannot have parameters', element: mainMethod);
}
@@ -420,7 +420,7 @@ class Compiler implements DiagnosticListener {
return resolver.resolveTypeAnnotation(element, annotation);
}
FunctionParameters resolveSignature(FunctionElement element) {
FunctionSignature resolveSignature(FunctionElement element) {
return withCurrentElement(element,
() => resolver.resolveSignature(element));
}
@@ -507,15 +507,17 @@ class AbstractFieldElement extends Element {
}
}
class FunctionParameters {
class FunctionSignature {
Link<Element> requiredParameters;
Link<Element> optionalParameters;
Type returnType;
int requiredParameterCount;
int optionalParameterCount;
FunctionParameters(this.requiredParameters,
this.optionalParameters,
this.requiredParameterCount,
this.optionalParameterCount);
FunctionSignature(this.requiredParameters,
this.optionalParameters,
this.requiredParameterCount,
this.optionalParameterCount,
this.returnType);
void forEachParameter(void function(Element parameter)) {
for (Link<Element> link = requiredParameters;
@@ -538,7 +540,7 @@ class FunctionElement extends Element {
Type type;
final Modifiers modifiers;
FunctionParameters functionParameters;
FunctionSignature functionSignature;
/**
* If this is an interface constructor, [defaultImplementation] will
@@ -565,14 +567,14 @@ class FunctionElement extends Element {
Element enclosing)
: this.tooMuchOverloading(name, other.cachedNode, other.kind,
other.modifiers, enclosing,
other.functionParameters);
other.functionSignature);
FunctionElement.tooMuchOverloading(SourceString name,
FunctionExpression this.cachedNode,
ElementKind kind,
Modifiers this.modifiers,
Element enclosing,
FunctionParameters this.functionParameters)
FunctionSignature this.functionSignature)
: super(name, kind, enclosing)
{
defaultImplementation = this;
@@ -585,42 +587,42 @@ class FunctionElement extends Element {
&& !modifiers.isStatic();
}
FunctionParameters computeParameters(Compiler compiler) {
if (functionParameters !== null) return functionParameters;
functionParameters = compiler.resolveSignature(this);
return functionParameters;
FunctionSignature computeSignature(Compiler compiler) {
if (functionSignature !== null) return functionSignature;
compiler.withCurrentElement(this, () {
functionSignature = compiler.resolveSignature(this);
});
return functionSignature;
}
int requiredParameterCount(Compiler compiler) {
return computeParameters(compiler).requiredParameterCount;
return computeSignature(compiler).requiredParameterCount;
}
int optionalParameterCount(Compiler compiler) {
return computeParameters(compiler).optionalParameterCount;
return computeSignature(compiler).optionalParameterCount;
}
int parameterCount(Compiler compiler) {
return computeParameters(compiler).parameterCount;
return computeSignature(compiler).parameterCount;
}
FunctionType computeType(Compiler compiler) {
if (type != null) return type;
return compiler.withCurrentElement(this, () {
FunctionParameters parameters = computeParameters(compiler);
Types types = compiler.types;
FunctionExpression node =
compiler.parser.measure(() => parseNode(compiler));
Type returnType = compiler.resolveTypeAnnotation(this, node.returnType);
compiler.withCurrentElement(this, () {
FunctionSignature signature = computeSignature(compiler);
LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>();
for (Link<Element> link = parameters.requiredParameters;
for (Link<Element> link = signature.requiredParameters;
!link.isEmpty();
link = link.tail) {
parameterTypes.addLast(link.head.computeType(compiler));
parameterTypes.addLast(link.head.computeType(compiler));
// TODO(karlklose): optional parameters.
}
type = new FunctionType(returnType, parameterTypes.toLink(), this);
return type;
type = new FunctionType(signature.returnType,
parameterTypes.toLink(),
this);
});
return type;
}
Node parseNode(DiagnosticListener listener) => cachedNode;
@@ -637,7 +639,7 @@ class ConstructorBodyElement extends FunctionElement {
ElementKind.GENERATIVE_CONSTRUCTOR_BODY,
null,
constructor.enclosingElement) {
functionParameters = constructor.functionParameters;
functionSignature = constructor.functionSignature;
}
bool isInstanceMember() => true;
+2 -2
View File
@@ -198,7 +198,7 @@ function() {
Selector selector,
void defineInstanceMember(String invocationName,
String definition)) {
FunctionParameters parameters = member.computeParameters(compiler);
FunctionSignature parameters = member.computeSignature(compiler);
int positionalArgumentCount = selector.positionalArgumentCount;
if (positionalArgumentCount == parameters.parameterCount) {
assert(selector.namedArgumentCount == 0);
@@ -330,7 +330,7 @@ function() {
defineInstanceMember(compiler.namer.getBailoutName(member), codeBlock);
}
FunctionElement function = member;
FunctionParameters parameters = function.computeParameters(compiler);
FunctionSignature parameters = function.computeSignature(compiler);
if (!parameters.optionalParameters.isEmpty()) {
addParameterStubs(member, defineInstanceMember);
}
@@ -149,7 +149,7 @@ class NativeEmitter {
void potentiallyConvertDartClosuresToJs(StringBuffer code,
FunctionElement member) {
FunctionParameters parameters = member.computeParameters(compiler);
FunctionSignature parameters = member.computeSignature(compiler);
Element converter =
compiler.findHelper(const SourceString('convertDartClosureToJS'));
String closureConverter = compiler.namer.isolateAccess(converter);
@@ -250,7 +250,7 @@ void handleSsaNative(SsaBuilder builder, Send node) {
compiler.emitter.nativeEmitter.nativeMethods.add(element);
}
FunctionParameters parameters = element.computeParameters(builder.compiler);
FunctionSignature parameters = element.computeSignature(builder.compiler);
if (!hasBody) {
List<String> arguments = <String>[];
List<HInstruction> inputs = <HInstruction>[];
@@ -317,10 +317,9 @@ void generateMethodWithPrototypeCheckForElement(Compiler compiler,
String methodName;
Namer namer = compiler.namer;
if (element.kind == ElementKind.FUNCTION) {
FunctionParameters computedParameters =
element.computeParameters(compiler);
FunctionSignature signature = element.computeSignature(compiler);
methodName = namer.instanceMethodName(
element.getLibrary(), element.name, computedParameters.parameterCount);
element.getLibrary(), element.name, signature.parameterCount);
} else if (element.kind == ElementKind.GETTER) {
methodName = namer.getterName(element.getLibrary(), element.name);
} else if (element.kind == ElementKind.SETTER) {
+16 -19
View File
@@ -233,7 +233,7 @@ class ResolverTask extends CompilerTask {
});
}
FunctionParameters resolveSignature(FunctionElement element) {
FunctionSignature resolveSignature(FunctionElement element) {
return measure(() => SignatureResolver.analyze(compiler, element));
}
@@ -682,8 +682,8 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
void setupFunction(FunctionExpression node, FunctionElement function) {
context = new MethodScope(context, function);
// Put the parameters in scope.
FunctionParameters functionParameters =
function.computeParameters(compiler);
FunctionSignature functionParameters =
function.computeSignature(compiler);
Link<Node> parameterNodes = node.parameters.nodes;
functionParameters.forEachParameter((Element element) {
if (element == functionParameters.optionalParameters.head) {
@@ -1645,8 +1645,6 @@ class SignatureResolver extends CommonResolverVisitor<Element> {
}
Element visitVariableDefinitions(VariableDefinitions node) {
resolveType(node.type);
Link<Node> definitions = node.definitions.nodes;
if (definitions.isEmpty()) {
cancel(node, 'internal error: no parameter definition');
@@ -1746,16 +1744,21 @@ class SignatureResolver extends CommonResolverVisitor<Element> {
return elements;
}
static FunctionParameters analyze(Compiler compiler,
FunctionElement element) {
FunctionExpression node = element.parseNode(compiler);
static FunctionSignature analyze(Compiler compiler,
FunctionElement element) {
FunctionExpression node =
compiler.parser.measure(() => element.parseNode(compiler));
SignatureResolver visitor = new SignatureResolver(compiler, element);
Link<Node> nodes = node.parameters.nodes;
LinkBuilder<Element> parameters = visitor.analyzeNodes(nodes);
return new FunctionParameters(parameters.toLink(),
visitor.optionalParameters,
parameters.length,
visitor.optionalParameterCount);
LinkBuilder<Element> parametersBuilder = visitor.analyzeNodes(nodes);
Link<Element> parameters = parametersBuilder.toLink();
Type returnType =
compiler.resolveTypeAnnotation(element, node.returnType);
return new FunctionSignature(parameters,
visitor.optionalParameters,
parametersBuilder.length,
visitor.optionalParameterCount,
returnType);
}
// TODO(ahe): This is temporary.
@@ -1764,12 +1767,6 @@ class SignatureResolver extends CommonResolverVisitor<Element> {
node.accept(new ResolverVisitor(compiler, enclosingElement));
}
// TODO(ahe): This is temporary.
void resolveType(Node node) {
if (node == null) return;
node.accept(new ResolverVisitor(compiler, enclosingElement));
}
// TODO(ahe): This is temporary.
ClassElement get currentClass() {
return enclosingElement.isMember()
+5 -5
View File
@@ -303,7 +303,7 @@ class LocalsHandler {
new ClosureTranslator(builder.compiler, builder.elements);
closureData = translator.translate(node);
FunctionParameters params = function.computeParameters(builder.compiler);
FunctionSignature params = function.computeSignature(builder.compiler);
params.forEachParameter((Element element) {
HParameterValue parameter = new HParameterValue(element);
builder.add(parameter);
@@ -864,7 +864,7 @@ class SsaBuilder implements Visitor {
}
int index = 0;
FunctionParameters parameters = constructor.computeParameters(compiler);
FunctionSignature parameters = constructor.computeSignature(compiler);
parameters.forEachParameter((Element parameter) {
HInstruction argument = compiledArguments[index++];
localsHandler.updateLocal(parameter, argument);
@@ -963,7 +963,7 @@ class SsaBuilder implements Visitor {
openFunction(functionElement, function);
Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>();
FunctionParameters parameters = functionElement.computeParameters(compiler);
FunctionSignature parameters = functionElement.computeSignature(compiler);
parameters.forEachParameter((Element element) {
if (element.kind == ElementKind.FIELD_PARAMETER) {
// If the [element] is a field-parameter (such as [:this.x:] then
@@ -1007,7 +1007,7 @@ class SsaBuilder implements Visitor {
if (body === null) continue;
List bodyCallInputs = <HInstruction>[];
bodyCallInputs.add(newObject);
body.functionParameters.forEachParameter((parameter) {
body.functionSignature.forEachParameter((parameter) {
bodyCallInputs.add(localsHandler.readLocal(parameter));
});
// TODO(ahe): The constructor name is statically resolved. See
@@ -2132,7 +2132,7 @@ class SsaBuilder implements Visitor {
node: closure);
}
FunctionElement function = element;
FunctionParameters parameters = function.computeParameters(compiler);
FunctionSignature parameters = function.computeSignature(compiler);
if (parameters.optionalParameterCount !== 0) {
compiler.cancel(
'JS_TO_CLOSURE does not handle closure with optional parameters',
+1 -1
View File
@@ -95,7 +95,7 @@ class SsaCodeGeneratorTask extends CompilerTask {
// The dom/html libraries have inline JS code that reference
// parameter names directly. Long-term such code will be rejected.
// Now, just don't mangle the parameter name.
function.computeParameters(compiler).forEachParameter((Element element) {
function.computeSignature(compiler).forEachParameter((Element element) {
parameterNames[element] = function.isNative()
? element.name.slowToString()
: JsNames.getValid('${element.name.slowToString()}');
@@ -200,7 +200,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase {
if (element != null && element.isFunction()) {
if (node.selector.applies(element, compiler)) {
FunctionElement method = element;
FunctionParameters parameters = method.computeParameters(compiler);
FunctionSignature parameters = method.computeSignature(compiler);
if (parameters.optionalParameterCount == 0) {
node.element = element;
}
+2 -2
View File
@@ -139,7 +139,7 @@ class Selector implements Hashable {
if (kind === SelectorKind.GETTER) return true;
FunctionElement function = element;
FunctionParameters parameters = function.computeParameters(compiler);
FunctionSignature parameters = function.computeSignature(compiler);
if (argumentCount > parameters.parameterCount) return false;
int requiredParameterCount = parameters.requiredParameterCount;
int optionalParameterCount = parameters.optionalParameterCount;
@@ -190,7 +190,7 @@ class Selector implements Hashable {
void addMatchingArgumentsToList(Link<Node> link) {}
FunctionParameters parameters = element.computeParameters(compiler);
FunctionSignature parameters = element.computeSignature(compiler);
if (this.positionalArgumentCount == parameters.parameterCount) {
for (Link<Node> link = arguments; !link.isEmpty(); link = link.tail) {
list.add(compileArgument(link.head));