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:
@@ -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++];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user