src/jdk/nashorn/internal/parser/Parser.java

Print this page
rev 739 : 8030809: Anonymous functions should not be shown with internal names in script stack trace
Reviewed-by: lagergren, hannesw, jlaskey
rev 743 : 8031317: SyntaxError when property setter has no parameter
Reviewed-by: lagergren, hannesw
rev 750 : 8032068: implement @sourceURL and #sourceURL directives
Reviewed-by: hannesw, lagergren
rev 758 : 8021350: Share script classes between threads/globals within context
Reviewed-by: lagergren, sundar

@@ -24,11 +24,11 @@
  */
 
 package jdk.nashorn.internal.parser;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
-import static jdk.nashorn.internal.codegen.CompilerConstants.FUNCTION_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
 import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
 import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
 import static jdk.nashorn.internal.parser.TokenType.CASE;
 import static jdk.nashorn.internal.parser.TokenType.CATCH;
 import static jdk.nashorn.internal.parser.TokenType.COLON;

@@ -387,11 +387,13 @@
         final FunctionNode parentFunction = lc.getCurrentFunction();
         if (parentFunction != null && !parentFunction.isProgram()) {
             sb.append(parentFunction.getName()).append('$');
         }
 
-        sb.append(ident != null ? ident.getName() : FUNCTION_PREFIX.symbolName());
+        assert ident.getName() != null;
+        sb.append(ident.getName());
+
         final String name = namespace.uniqueName(sb.toString());
         assert parentFunction != null || name.equals(RUN_SCRIPT.symbolName())  : "name = " + name;// must not rename runScript().
 
         int flags = 0;
         if (parentFunction == null) {

@@ -417,11 +419,12 @@
                 namespace,
                 ident,
                 name,
                 parameters,
                 kind,
-                flags);
+                flags,
+                sourceURL);
 
         lc.push(functionNode);
         // Create new block, and just put it on the context stack, restoreFunctionNode() will associate it with the
         // FunctionNode.
         newBlock();

@@ -636,10 +639,14 @@
 
         script.setFinish(source.getLength() - 1);
 
         script = restoreFunctionNode(script, token); //commit code
         script = script.setBody(lc, script.getBody().setNeedsScope(lc));
+        // user may have directive comment to set sourceURL
+        if (sourceURL != null) {
+            script = script.setSourceURL(lc, sourceURL);
+        }
 
         return script;
     }
 
     /**

@@ -1790,10 +1797,11 @@
 
         switch (type) {
         case THIS:
             final String name = type.getName();
             next();
+            lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_THIS);
             return new IdentNode(primaryToken, finish, name);
         case IDENT:
             final IdentNode ident = getIdent();
             if (ident == null) {
                 break;

@@ -2130,15 +2138,24 @@
                 case "set":
                     final PropertyKey setIdent = propertyName();
                     final String setterName = setIdent.getPropertyName();
                     final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName));
                     expect(LPAREN);
-                    final IdentNode argIdent = getIdent();
+                    // be sloppy and allow missing setter parameter even though
+                    // spec does not permit it!
+                    final IdentNode argIdent;
+                    if (type == IDENT || isNonStrictModeIdent()) {
+                        argIdent = getIdent();
                     verifyStrictIdent(argIdent, "setter argument");
+                    } else {
+                        argIdent = null;
+                    }
                     expect(RPAREN);
                     List<IdentNode> parameters = new ArrayList<>();
+                    if (argIdent != null) {
                     parameters.add(argIdent);
+                    }
                     functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER);
                     return new PropertyNode(propertyToken, finish, setIdent, null, null, functionNode);
 
                 default:
                     break;

@@ -2446,11 +2463,11 @@
         }
 
         // name is null, generate anonymous name
         boolean isAnonymous = false;
         if (name == null) {
-            final String tmpName = "_L" + functionLine;
+            final String tmpName = ANON_FUNCTION_PREFIX.symbolName() + functionLine;
             name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
             isAnonymous = true;
         }
 
         expect(LPAREN);