Fix name function expressions
authorSimon Hausmann <simon.hausmann@digia.com>
Fri, 8 Feb 2013 12:25:23 +0000 (13:25 +0100)
committerLars Knoll <lars.knoll@digia.com>
Sat, 9 Feb 2013 09:53:50 +0000 (10:53 +0100)
We should also insert those into the environment members if they have
a name and are part of an expression statement. Simple testcase
example:

try {
    function foo() { ... }
} catch (e) {}

Then foo should be visible as if it was declared outside of the try.

Change-Id: I8d23a28e1c4537d4f57f9cb0d559e6163e0fdef0
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/v4/qv4codegen.cpp
src/v4/qv4codegen_p.h
tests/TestExpectations

index c44e54d..eda6b0c 100644 (file)
@@ -326,12 +326,29 @@ protected:
         return true;
     }
 
+    virtual bool visit(ExpressionStatement *ast)
+    {
+        if (FunctionExpression* expr = AST::cast<AST::FunctionExpression*>(ast->expression)) {
+            enterFunction(expr, /*enterName*/ true);
+            Node::accept(expr->formals, this);
+            Node::accept(expr->body, this);
+            leaveEnvironment();
+            return false;
+        }
+        return true;
+    }
+
     virtual bool visit(FunctionExpression *ast)
     {
+        enterFunction(ast, /*enterName*/ false);
+        return true;
+    }
+
+    void enterFunction(FunctionExpression *ast, bool enterName)
+    {
         if (_env->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
             _cg->throwSyntaxError(ast->identifierToken, QCoreApplication::translate("qv4codegen", "Function name may not be eval or arguments in strict mode"));
-        enterFunction(ast, ast->name.toString(), ast->formals, ast->body);
-        return true;
+        enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0);
     }
 
     virtual void endVisit(FunctionExpression *)
@@ -352,9 +369,7 @@ protected:
 
     virtual bool visit(FunctionDeclaration *ast)
     {
-        if (_env->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
-            _cg->throwSyntaxError(ast->identifierToken, QCoreApplication::translate("qv4codegen", "Function name may not be eval or arguments in strict mode"));
-        enterFunction(ast, ast->name.toString(), ast->formals, ast->body, ast);
+        enterFunction(ast, /*enterName*/ true);
         return true;
     }
 
@@ -374,12 +389,12 @@ protected:
     }
 
 private:
-    void enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionDeclaration *decl = 0)
+    void enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr = 0)
     {
         bool wasStrict = false;
         if (_env) {
             _env->hasNestedFunctions = true;
-            _env->enter(name, Environment::FunctionDefinition, decl);
+            _env->enter(name, Environment::FunctionDefinition, expr);
             if (name == QLatin1String("arguments"))
                 _env->usesArgumentsObject = Environment::ArgumentsObjectNotUsed;
             wasStrict = _env->isStrict;
index d83e129..239027a 100644 (file)
@@ -131,7 +131,7 @@ protected:
         struct Member {
             MemberType type;
             int index;
-            AST::FunctionDeclaration *function;
+            AST::FunctionExpression *function;
         };
         typedef QMap<QString, Member> MemberMap;
 
@@ -184,7 +184,7 @@ protected:
             return false;
         }
 
-        void enter(const QString &name, MemberType type, AST::FunctionDeclaration *function = 0)
+        void enter(const QString &name, MemberType type, AST::FunctionExpression *function = 0)
         {
             if (! name.isEmpty()) {
                 MemberMap::iterator it = members.find(name);
index 1338378..30aad20 100644 (file)
@@ -3,7 +3,6 @@
 15.2.3.6-2-17-1 failing
 
 
-10.4.2-1-2 failing
 10.4.3-1-104 failing
 10.4.3-1-106 failing
 10.4.3-1-63-s failing
@@ -12,7 +11,6 @@
 S11.5.3_A4_T2 failing
 S11.8.6_A3 failing
 S11.8.6_A5_T2 failing
-12.14-13 failing
 S13_A15_T4 failing
 S13_A3_T1 failing
 S13.2.3_A1 failing
@@ -20,13 +18,10 @@ S14_A2 failing
 14.1-5-s failing
 15.1.1.3-3 failing
 S15.12.2_A1 failing
-15.2.3.6-4-360-3 failing
-15.2.3.6-4-360-7 failing
 15.4.4.14-9-a-10 failing
 15.4.4.14-9-a-17 failing
 15.4.4.14-9-a-7 failing
 15.4.4.14-9-a-9 failing
-15.4.4.19-5-1 failing
 S15.4.4.3_A1_T1 failing
 S15.4.4.3_A3_T1 failing
 15.4.4.4-5-c-i-1 failing
@@ -37,8 +32,6 @@ S15.5.4.11_A5_T1 failing
 15.5.4.20-4-1 failing
 S15.5.4.8_A1_T4 failing
 S15.7.4.5_A1.4_T01 failing
-Sbp_12.5_A9_T3 failing
-Sbp_12.6.2_A13_T3 failing
 Sbp_7.8.4_A6.1_T4 failing
 Sbp_7.8.4_A6.2_T1 failing
 Sbp_7.8.4_A6.2_T2 failing
@@ -51,4 +44,8 @@ Sbp_A4_T2 failing
 S12.4_A1 failing
 S15.2.4.4_A14 failing
 # Try/catch scoping issue
-S12.14_A4 failing
\ No newline at end of file
+S12.14_A4 failing
+
+# Function declaration inside if / while
+Sbp_12.5_A9_T3 failing
+Sbp_12.6.2_A13_T3 failing
\ No newline at end of file