--- a/nashorn/make/build.xml Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/make/build.xml Sat Mar 02 11:26:47 2013 -0400
@@ -21,7 +21,7 @@
or visit www.oracle.com if you need additional information or have any
questions.
-->
-<project name="nashorn" default="all" basedir="..">
+<project name="nashorn" default="test" basedir="..">
<import file="build-nasgen.xml"/>
<import file="build-benchmark.xml"/>
<import file="code_coverage.xml"/>
--- a/nashorn/make/project.properties Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/make/project.properties Sat Mar 02 11:26:47 2013 -0400
@@ -24,7 +24,7 @@
application.title=nashorn
# location of JDK embedded ASM sources
-jdk.asm.src.dir=../jdk/src/share/classes/jdk/internal
+jdk.asm.src.dir=../jdk/src/share/classes/jdk/internal/org/objectweb/asm
# source and target levels
build.compiler=modern
--- a/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java Sat Mar 02 11:26:47 2013 -0400
@@ -83,7 +83,6 @@
package jdk.internal.dynalink.beans;
-import java.beans.Introspector;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
@@ -136,16 +135,16 @@
// Add the method as a property getter and/or setter
if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) {
// Property getter
- setPropertyGetter(Introspector.decapitalize(name.substring(3)), introspector.unreflect(
+ setPropertyGetter(decapitalize(name.substring(3)), introspector.unreflect(
getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
} else if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0 &&
method.getReturnType() == boolean.class) {
// Boolean property getter
- setPropertyGetter(Introspector.decapitalize(name.substring(2)), introspector.unreflect(
+ setPropertyGetter(decapitalize(name.substring(2)), introspector.unreflect(
getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
} else if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) {
// Property setter
- addMember(Introspector.decapitalize(name.substring(3)), methodHandle, propertySetters);
+ addMember(decapitalize(name.substring(3)), methodHandle, propertySetters);
}
}
@@ -170,6 +169,27 @@
}
}
+ private static String decapitalize(String str) {
+ assert str != null;
+ if(str.isEmpty()) {
+ return str;
+ }
+
+ final char c0 = str.charAt(0);
+ if(Character.isLowerCase(c0)) {
+ return str;
+ }
+
+ // If it has two consecutive upper-case characters, i.e. "URL", don't decapitalize
+ if(str.length() > 1 && Character.isUpperCase(str.charAt(1))) {
+ return str;
+ }
+
+ final char c[] = str.toCharArray();
+ c[0] = Character.toLowerCase(c0);
+ return new String(c);
+ }
+
abstract FacetIntrospector createFacetIntrospector();
void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) {
--- a/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/internal/dynalink/beans/BeansLinker.java Sat Mar 02 11:26:47 2013 -0400
@@ -83,7 +83,6 @@
package jdk.internal.dynalink.beans;
-import java.beans.BeanInfo;
import java.lang.invoke.MethodHandles;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.DynamicLinkerFactory;
@@ -99,11 +98,9 @@
* <ul>
* <li>expose all public methods of form {@code setXxx()}, {@code getXxx()}, and {@code isXxx()} as property setters and
* getters for {@code dyn:setProp} and {@code dyn:getProp} operations;</li>
- * <li>expose all property getters and setters declared by the class' {@link BeanInfo};</li>
- * <li>expose all public methods and methods declared by the class' {@link BeanInfo} for invocation through
- * {@code dyn:callMethod} operation;</li>
- * <li>expose all public methods and methods declared by the class' {@link BeanInfo} for retrieval for
- * {@code dyn:getMethod} operation; the methods thus retrieved can then be invoked using {@code dyn:call};</li>
+ * <li>expose all public methods for invocation through {@code dyn:callMethod} operation;</li>
+ * <li>expose all public methods for retrieval for {@code dyn:getMethod} operation; the methods thus retrieved can then
+ * be invoked using {@code dyn:call};</li>
* <li>expose all public fields as properties, unless there are getters or setters for the properties of the same name;</li>
* <li>expose {@code dyn:getLength}, {@code dyn:getElem} and {@code dyn:setElem} on native Java arrays, as well as
* {@link java.util.List} and {@link java.util.Map} objects; ({@code dyn:getLength} works on any
--- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java Sat Mar 02 11:26:47 2013 -0400
@@ -95,7 +95,7 @@
* <p>
* There is also a very nice debug interface that can emit formatted
* bytecodes that have been written. This is enabled by setting the
- * environment "nashorn.codegen.debug" to true, or --log=codegen:<level>
+ * environment "nashorn.codegen.debug" to true, or --log=codegen:{@literal <level>}
* <p>
* A ClassEmitter implements an Emitter - i.e. it needs to have
* well defined start and end calls for whatever it is generating. Assertions
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Sat Mar 02 11:26:47 2013 -0400
@@ -46,7 +46,6 @@
import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE;
-import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FUNCTION_DECLARATION;
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_SCOPE;
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
@@ -2052,9 +2051,6 @@
if (needsScope) {
int flags = CALLSITE_SCOPE | getCallSiteFlags();
- if (varNode.isFunctionVarNode()) {
- flags |= CALLSITE_FUNCTION_DECLARATION;
- }
final IdentNode identNode = varNode.getName();
final Type type = identNode.getType();
if (varSymbol.isFastScope(getCurrentFunctionNode())) {
--- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Sat Mar 02 11:26:47 2013 -0400
@@ -112,7 +112,7 @@
private final Context context;
/**
- * The list of available accessor types in width order. This order is used for type guesses narrow->wide
+ * The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
* in the dual--fields world
*/
public static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
@@ -184,7 +184,7 @@
/**
* Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
- * Indexes are ordered narrower->wider / optimistic->pessimistic. Invalidations always
+ * Indexes are ordered narrower{@literal ->}wider / optimistic{@literal ->}pessimistic. Invalidations always
* go to a type of higher index
*
* @param index accessor type index
--- a/nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java Sat Mar 02 11:26:47 2013 -0400
@@ -459,120 +459,120 @@
}
/**
- * Specialized version of < operator for two int arguments. Do not call directly.
+ * Specialized version of {@literal <} operator for two int arguments. Do not call directly.
* @param a int
* @param b int
- * @return a < b
+ * @return a {@code <} b
*/
public static boolean LT(final int a, final int b) {
return a < b;
}
/**
- * Specialized version of < operator for two double arguments. Do not call directly.
+ * Specialized version of {@literal <} operator for two double arguments. Do not call directly.
* @param a double
* @param b double
- * @return a < b
+ * @return a {@literal <} b
*/
public static boolean LT(final double a, final double b) {
return a < b;
}
/**
- * Specialized version of < operator for two long arguments. Do not call directly.
+ * Specialized version of {@literal <} operator for two long arguments. Do not call directly.
* @param a long
* @param b long
- * @return a < b
+ * @return a {@literal <} b
*/
public static boolean LT(final long a, final long b) {
return a < b;
}
/**
- * Specialized version of <= operator for two int arguments. Do not call directly.
+ * Specialized version of {@literal <=} operator for two int arguments. Do not call directly.
* @param a int
* @param b int
- * @return a <= b
+ * @return a {@literal <=} b
*/
public static boolean LE(final int a, final int b) {
return a <= b;
}
/**
- * Specialized version of <= operator for two double arguments. Do not call directly.
+ * Specialized version of {@literal <=} operator for two double arguments. Do not call directly.
* @param a double
* @param b double
- * @return a <= b
+ * @return a {@literal <=} b
*/
public static boolean LE(final double a, final double b) {
return a <= b;
}
/**
- * Specialized version of <= operator for two long arguments. Do not call directly.
+ * Specialized version of {@literal <=} operator for two long arguments. Do not call directly.
* @param a long
* @param b long
- * @return a <= b
+ * @return a {@literal <=} b
*/
public static boolean LE(final long a, final long b) {
return a <= b;
}
/**
- * Specialized version of > operator for two int arguments. Do not call directly.
+ * Specialized version of {@literal >} operator for two int arguments. Do not call directly.
* @param a int
* @param b int
- * @return a > b
+ * @return a {@literal >} b
*/
public static boolean GT(final int a, final int b) {
return a > b;
}
/**
- * Specialized version of > operator for two double arguments. Do not call directly.
+ * Specialized version of {@literal >} operator for two double arguments. Do not call directly.
* @param a double
* @param b double
- * @return a > b
+ * @return a {@literal >} b
*/
public static boolean GT(final double a, final double b) {
return a > b;
}
/**
- * Specialized version of > operator for two long arguments. Do not call directly.
+ * Specialized version of {@literal >} operator for two long arguments. Do not call directly.
* @param a long
* @param b long
- * @return a > b
+ * @return a {@literal >} b
*/
public static boolean GT(final long a, final long b) {
return a > b;
}
/**
- * Specialized version of >= operator for two int arguments. Do not call directly.
+ * Specialized version of {@literal >=} operator for two int arguments. Do not call directly.
* @param a int
* @param b int
- * @return a >= b
+ * @return a {@literal >=} b
*/
public static boolean GE(final int a, final int b) {
return a >= b;
}
/**
- * Specialized version of >= operator for two double arguments. Do not call directly.
+ * Specialized version of {@literal >=} operator for two double arguments. Do not call directly.
* @param a double
* @param b double
- * @return a >= b
+ * @return a {@literal >=} b
*/
public static boolean GE(final double a, final double b) {
return a >= b;
}
/**
- * Specialized version of >= operator for two long arguments. Do not call directly.
+ * Specialized version of {@literal >=} operator for two long arguments. Do not call directly.
* @param a long
* @param b long
- * @return a >= b
+ * @return a {@code >=} b
*/
public static boolean GE(final long a, final long b) {
return a >= b;
--- a/nashorn/src/jdk/nashorn/internal/ir/Assignment.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/ir/Assignment.java Sat Mar 02 11:26:47 2013 -0400
@@ -46,18 +46,4 @@
* @return get the assignment source node
*/
public Node getAssignmentSource();
-
- /**
- * Reset the assignment source
- *
- * @param newSource new source node
- */
- public void setAssignmentSource(final Node newSource);
-
- /**
- * Reset the assignment destination
- *
- * @param newDest new destination node
- */
- public void setAssignmentDest(final D newDest);
}
--- a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java Sat Mar 02 11:26:47 2013 -0400
@@ -140,21 +140,11 @@
}
@Override
- public void setAssignmentDest(final Node node) {
- setLHS(node);
- }
-
- @Override
public Node getAssignmentSource() {
return rhs();
}
@Override
- public void setAssignmentSource(final Node source) {
- setRHS(source);
- }
-
- @Override
public boolean equals(final Object other) {
if (!super.equals(other)) {
return false;
--- a/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java Sat Mar 02 11:26:47 2013 -0400
@@ -64,17 +64,17 @@
EQ_STRICT(TokenType.EQ_STRICT, Type.BOOLEAN, 2, true),
/** == operator with at least one object */
EQ(TokenType.EQ, Type.BOOLEAN, 2, true),
- /** >= operator with at least one object */
+ /** {@literal >=} operator with at least one object */
GE(TokenType.GE, Type.BOOLEAN, 2, true),
- /** > operator with at least one object */
+ /** {@literal >} operator with at least one object */
GT(TokenType.GT, Type.BOOLEAN, 2, true),
/** in operator */
IN(TokenType.IN, Type.BOOLEAN, 2),
/** instanceof operator */
INSTANCEOF(TokenType.INSTANCEOF, Type.BOOLEAN, 2),
- /** <= operator with at least one object */
+ /** {@literal <=} operator with at least one object */
LE(TokenType.LE, Type.BOOLEAN, 2, true),
- /** < operator with at least one object */
+ /** {@literal <} operator with at least one object */
LT(TokenType.LT, Type.BOOLEAN, 2, true),
/** !== operator with at least one object */
NE_STRICT(TokenType.NE_STRICT, Type.BOOLEAN, 2, true),
@@ -184,7 +184,7 @@
/**
* If this request can be reversed, return the reverse request
- * Eq EQ -> NE.
+ * Eq EQ {@literal ->} NE.
*
* @param request request to reverse
*
--- a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java Sat Mar 02 11:26:47 2013 -0400
@@ -109,16 +109,6 @@
}
@Override
- public void setAssignmentSource(final Node source) {
- setAssignmentDest(source);
- }
-
- @Override
- public void setAssignmentDest(final Node source) {
- setRHS(source);
- }
-
- @Override
public boolean equals(final Object other) {
if (!super.equals(other)) {
return false;
--- a/nashorn/src/jdk/nashorn/internal/ir/VarNode.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java Sat Mar 02 11:26:47 2013 -0400
@@ -83,20 +83,10 @@
}
@Override
- public void setAssignmentDest(final IdentNode node) {
- setName(name);
- }
-
- @Override
public Node getAssignmentSource() {
return isAssignment() ? getInit() : null;
}
- @Override
- public void setAssignmentSource(final Node source) {
- setInit(source);
- }
-
/**
* Does this variable declaration have an init value
* @return true if an init exists, false otherwise
--- a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Sat Mar 02 11:26:47 2013 -0400
@@ -542,7 +542,7 @@
}
/**
- * Binary enter - callback for entering && operator
+ * Binary enter - callback for entering {@literal &&} operator
*
* @param binaryNode the node
* @return processed node
@@ -552,7 +552,7 @@
}
/**
- * Binary leave - callback for leaving a && operator
+ * Binary leave - callback for leaving a {@literal &&} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -602,7 +602,7 @@
}
/**
- * Binary enter - callback for entering &= operator
+ * Binary enter - callback for entering {@literal &=} operator
*
* @param binaryNode the node
* @return processed node
@@ -612,7 +612,7 @@
}
/**
- * Binary leave - callback for leaving a &= operator
+ * Binary leave - callback for leaving a {@literal &=} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -722,7 +722,7 @@
}
/**
- * Binary enter - callback for entering >>= operator
+ * Binary enter - callback for entering {@literal >>=} operator
*
* @param binaryNode the node
* @return processed node
@@ -732,7 +732,7 @@
}
/**
- * Binary leave - callback for leaving a >>= operator
+ * Binary leave - callback for leaving a {@literal >>=} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -742,7 +742,7 @@
}
/**
- * Binary enter - callback for entering a <<= operator
+ * Binary enter - callback for entering a {@literal <<=} operator
*
* @param binaryNode the node
* @return processed node
@@ -752,7 +752,7 @@
}
/**
- * Binary leave - callback for leaving a <<= operator
+ * Binary leave - callback for leaving a {@literal <<=} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -762,7 +762,7 @@
}
/**
- * Binary enter - callback for entering >>>= operator
+ * Binary enter - callback for entering {@literal >>>=} operator
*
* @param binaryNode the node
* @return processed node
@@ -772,7 +772,7 @@
}
/**
- * Binary leave - callback for leaving a >>>= operator
+ * Binary leave - callback for leaving a {@literal >>>=} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -822,7 +822,7 @@
}
/**
- * Binary enter - callback for entering & operator
+ * Binary enter - callback for entering {@literal &} operator
*
* @param binaryNode the node
* @return processed node
@@ -832,7 +832,7 @@
}
/**
- * Binary leave - callback for leaving a & operator
+ * Binary leave - callback for leaving a {@literal &} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -986,7 +986,7 @@
}
/**
- * Binary enter - callback for entering >= operator
+ * Binary enter - callback for entering {@literal >=} operator
*
* @param binaryNode the node
* @return processed node
@@ -996,7 +996,7 @@
}
/**
- * Binary leave - callback for leaving >= operator
+ * Binary leave - callback for leaving {@literal >=} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -1006,7 +1006,7 @@
}
/**
- * Binary enter - callback for entering > operator
+ * Binary enter - callback for entering {@literal >} operator
*
* @param binaryNode the node
* @return processed node
@@ -1016,7 +1016,7 @@
}
/**
- * Binary leave - callback for leaving > operator
+ * Binary leave - callback for leaving {@literal >} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -1066,7 +1066,7 @@
}
/**
- * Binary enter - callback for entering <= operator
+ * Binary enter - callback for entering {@literal <=} operator
*
* @param binaryNode the node
* @return processed node
@@ -1076,7 +1076,7 @@
}
/**
- * Binary leave - callback for leaving <= operator
+ * Binary leave - callback for leaving {@literal <=} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -1086,7 +1086,7 @@
}
/**
- * Binary enter - callback for entering < operator
+ * Binary enter - callback for entering {@literal <} operator
*
* @param binaryNode the node
* @return processed node
@@ -1096,7 +1096,7 @@
}
/**
- * Binary leave - callback for leaving < operator
+ * Binary leave - callback for leaving {@literal <} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -1205,7 +1205,7 @@
}
/**
- * Binary enter - callback for entering >> operator
+ * Binary enter - callback for entering {@literal >>} operator
*
* @param binaryNode the node
* @return processed node
@@ -1215,7 +1215,7 @@
}
/**
- * Binary leave - callback for leaving >> operator
+ * Binary leave - callback for leaving {@literal >>} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -1225,7 +1225,7 @@
}
/**
- * Binary enter - callback for entering << operator
+ * Binary enter - callback for entering {@literal <<} operator
*
* @param binaryNode the node
* @return processed node
@@ -1235,7 +1235,7 @@
}
/**
- * Binary leave - callback for leaving << operator
+ * Binary leave - callback for leaving {@literal <<} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
@@ -1244,7 +1244,7 @@
return leaveDefault(binaryNode);
}
/**
- * Binary enter - callback for entering >>> operator
+ * Binary enter - callback for entering {@literal >>>} operator
*
* @param binaryNode the node
* @return processed node
@@ -1254,7 +1254,7 @@
}
/**
- * Binary leave - callback for leaving >>> operator
+ * Binary leave - callback for leaving {@literal >>>} operator
*
* @param binaryNode the node
* @return processed node, which will replace the original one, or the original node
--- a/nashorn/src/jdk/nashorn/internal/objects/DateParser.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/objects/DateParser.java Sat Mar 02 11:26:47 2013 -0400
@@ -221,7 +221,7 @@
*
* <p>English month names and selected time zone names as well as AM/PM markers are recognized
* and handled properly. Additionally, numeric time zone offsets such as <tt>(+|-)hh:mm</tt> or
- * <tt></tt>(+|-)hhmm</tt> are recognized. If the string does not contain a time zone offset
+ * <tt>(+|-)hhmm</tt> are recognized. If the string does not contain a time zone offset
* the <tt>TIMEZONE</tt>field is left undefined, meaning the local time zone should be applied.</p>
*
* <p>English weekday names are recognized but ignored. All text in parentheses is ignored as well.
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Sat Mar 02 11:26:47 2013 -0400
@@ -74,13 +74,16 @@
* delete x.p; // calls y.__delete__
* for (i in x) { print(i); } // calls y.__getIds__
* </pre>
+ * <p>
* JavaScript caller of adapter object is isolated from the fact that the property access/mutation/deletion are really
* calls to JavaScript methods on adaptee.
- * </p><p>
+ * </p>
+ * <p>
* JSAdapter constructor can optionally receive an "overrides" object. Properties of overrides object is copied to
* JSAdapter instance. When user accessed property is one of these, then adaptee's methods like {@code __get__},
* {@code __put__} etc. are not called for those. This can be used to make certain "preferred" properties that can be
* accessed in the usual/faster way avoiding proxy mechanism. Example:
+ * </p>
* <pre>
* var x = new JSAdapter({ foo: 444, bar: 6546 }) {
* __get__: function(name) { return name; }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Sat Mar 02 11:26:47 2013 -0400
@@ -65,6 +65,7 @@
}
/**
+ * <p>
* Given a name of a Java type, returns an object representing that type in Nashorn. The Java class of the objects
* used to represent Java types in Nashorn is not {@link java.lang.Class} but rather {@link StaticClass}. They are
* the objects that you can use with the {@code new} operator to create new instances of the class as well as to
@@ -75,7 +76,8 @@
* different expression (e.g. {@code java.io.File}) as an argument in "new" and to address statics, and it is
* distinct from the {@code Class} object (e.g. {@code java.io.File.class}). Below we cover in details the
* properties of the type objects.
- * <h2>Constructing Java objects</h2>
+ * </p>
+ * <p><b>Constructing Java objects</b></p>
* Examples:
* <pre>
* var arrayListType = Java.type("java.util.ArrayList")
@@ -104,19 +106,24 @@
* var arctype = Java.type("java.awt.geom.Arc2D")
* var ftype = arctype.Float
* </pre>
+ * <p>
* You can access both static and non-static inner classes. If you want to create an instance of a non-static
* inner class, remember to pass an instance of its outer class as the first argument to the constructor.
- * </p><p>
+ * </p>
+ * <p>
* If the type is abstract, you can instantiate an anonymous subclass of it using an argument list that is
* applicable to any of its public or protected constructors, but inserting a JavaScript object with functions
* properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the
* JavaScript function will provide implementation for all overloads. E.g.:
+ * </p>
* <pre>
* var TimerTask = Java.type("java.util.TimerTask")
* var task = new TimerTask({ run: function() { print("Hello World!") } })
* </pre>
+ * <p>
* Nashorn supports a syntactic extension where a "new" expression followed by an argument is identical to
* invoking the constructor and passing the argument to it, so you can write the above example also as:
+ * </p>
* <pre>
* var task = new TimerTask {
* run: function() {
@@ -124,30 +131,38 @@
* }
* }
* </pre>
+ * <p>
* which is very similar to Java anonymous inner class definition. On the other hand, if the type is an abstract
* type with a single abstract method (commonly referred to as a "SAM type") or all abstract methods it has share
* the same overloaded name), then instead of an object, you can just pass a function, so the above example can
* become even more simplified to:
+ * </p>
* <pre>
* var task = new TimerTask(function() { print("Hello World!") })
* </pre>
+ * <p>
* Note that in every one of these cases if you are trying to instantiate an abstract class that has constructors
* that take some arguments, you can invoke those simply by specifying the arguments after the initial
* implementation object or function.
- * </p><p>The use of functions can be taken even further; if you are invoking a Java method that takes a SAM type,
+ * </p>
+ * <p>The use of functions can be taken even further; if you are invoking a Java method that takes a SAM type,
* you can just pass in a function object, and Nashorn will know what you meant:
+ * </p>
* <pre>
* var timer = new Java.type("java.util.Timer")
* timer.schedule(function() { print("Hello World!") })
* </pre>
+ * <p>
* Here, {@code Timer.schedule()} expects a {@code TimerTask} as its argument, so Nashorn creates an instance of a
* {@code TimerTask} subclass and uses the passed function to implement its only abstract method, {@code run()}. In
* this usage though, you can't use non-default constructors; the type must be either an interface, or must have a
* protected or public no-arg constructor.
- * </p><p>
+ * </p>
+ * <p>
* You can also subclass non-abstract classes; for that you will need to use the {@link #extend(Object, Object...)}
* method.
- * <h2>Accessing static members</h2>
+ * </p>
+ * <p><b>Accessing static members</b></p>
* Examples:
* <pre>
* var File = Java.type("java.io.File")
@@ -176,7 +191,7 @@
* var File = Java.type("java.io.File")
* print(File.class.static === File) // prints true
* </pre>
- * <h2>{@code instanceof} operator</h2>
+ * <p><b>{@code instanceof} operator</b></p>
* The standard ECMAScript {@code instanceof} operator is extended to recognize Java objects and their type objects:
* <pre>
* var File = Java.type("java.io.File")
@@ -368,6 +383,7 @@
* <li>If the Java method is overloaded (as in the above example {@code List.add()}), then your JavaScript adapter
* must be prepared to deal with all overloads.</li>
* <li>You can't invoke {@code super.*()} from adapters for now.</li>
+ * </ul>
* @param self not used
* @param types the original types. The caller must pass at least one Java type object of class {@link StaticClass}
* representing either a public interface or a non-final public class with at least one public or protected
--- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java Sat Mar 02 11:26:47 2013 -0400
@@ -30,7 +30,7 @@
* As only the code generating package (i.e. Context) knows about
* the ScriptLoader and it would be a security hazard otherwise
* the Compiler is given an installation interface for its code.
- * <p>>
+ * <p>
* The compiler still retains most of the state around code emission
* and management internally, so this is to avoid passing around any
* logic that isn't directly related to installing a class
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Sat Mar 02 11:26:47 2013 -0400
@@ -509,7 +509,7 @@
*
* @param fullName full name of class, e.g. jdk.nashorn.internal.objects.JO$2P1 contains 2 fields and 1 parameter.
*
- * @return the Class<?> for this structure
+ * @return the {@code Class<?>} for this structure
*
* @throws ClassNotFoundException if structure class cannot be resolved
*/
@@ -523,7 +523,7 @@
*
* @param fullName full name of class to load
*
- * @return the Class<?> for the name
+ * @return the {@code Class<?>} for the name
*
* @throws ClassNotFoundException if class cannot be resolved
*/
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Sat Mar 02 11:26:47 2013 -0400
@@ -1463,7 +1463,7 @@
}
/**
- * Returns the set of <property, value> entries that make up this
+ * Returns the set of {@literal <property, value>} entries that make up this
* ScriptObject's properties
* (java.util.Map-like method to help ScriptObjectMirror implementation)
*
@@ -1524,7 +1524,7 @@
* of their keys to their values
* (java.util.Map-like method to help ScriptObjectMirror implementation)
*
- * @param otherMap a <key,value> map of properties to add
+ * @param otherMap a {@literal <key,value>} map of properties to add
*/
public void putAll(final Map<?, ?> otherMap) {
final boolean strict = getContext()._strict;
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Sat Mar 02 11:26:47 2013 -0400
@@ -815,7 +815,7 @@
}
/**
- * ECMA 11.8.1 - The less than operator (<) - generic implementation
+ * ECMA 11.8.1 - The less than operator ({@literal <}) - generic implementation
*
* @param x first object to compare
* @param y second object to compare
@@ -828,7 +828,7 @@
}
/**
- * ECMA 11.8.2 - The greater than operator (>) - generic implementation
+ * ECMA 11.8.2 - The greater than operator ({@literal >}) - generic implementation
*
* @param x first object to compare
* @param y second object to compare
@@ -841,7 +841,7 @@
}
/**
- * ECMA 11.8.3 - The less than or equal operator (<=) - generic implementation
+ * ECMA 11.8.3 - The less than or equal operator ({@literal <=}) - generic implementation
*
* @param x first object to compare
* @param y second object to compare
@@ -854,7 +854,7 @@
}
/**
- * ECMA 11.8.4 - The greater than or equal operator (>=) - generic implementation
+ * ECMA 11.8.4 - The greater than or equal operator ({@literal >=}) - generic implementation
*
* @param x first object to compare
* @param y second object to compare
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Sat Mar 02 11:26:47 2013 -0400
@@ -87,7 +87,7 @@
import jdk.nashorn.internal.runtime.Undefined;
/**
- * A factory class that generates adapter classes. Adapter classes allow implementation of Java interfaces and
+ * <p>A factory class that generates adapter classes. Adapter classes allow implementation of Java interfaces and
* extending of Java classes from JavaScript. For every combination of a superclass to extend and interfaces to
* implement (collectively: "original types"), exactly one adapter class is generated that extends the specified
* superclass and implements the specified interfaces.
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Sat Mar 02 11:26:47 2013 -0400
@@ -43,8 +43,6 @@
public static final int CALLSITE_SCOPE = 0x01;
/** Flags that the call site is in code that uses ECMAScript strict mode. */
public static final int CALLSITE_STRICT = 0x02;
- /** Flags that a property setter call site is part of a function declaration that assigns the function object to a name. */
- public static final int CALLSITE_FUNCTION_DECLARATION = 0x04;
/** Flags that a property getter or setter call site references a scope variable that is not in the global scope
* (it is in a function lexical scope), and the function's scope object class is fixed and known in advance. Such
* getters and setters can often be linked more optimally using these assumptions. */
@@ -182,7 +180,7 @@
/**
* Returns the named operand in this descriptor's name. Equivalent to
* {@code getNameToken(CallSiteDescriptor.NAME_OPERAND)}. E.g. for operation {@code "dyn:getProp:color"}, returns
- * {@code "color"}. For call sites without named operands (e.g. {@link "dyn:new"}) returns null.
+ * {@code "color"}. For call sites without named operands (e.g. {@code "dyn:new"}) returns null.
* @return the named operand in this descriptor's name.
*/
public String getOperand() {
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Sat Mar 02 11:26:47 2013 -0400
@@ -200,7 +200,7 @@
/**
* Return an option given its resource key. If the key doesn't begin with
- * <resource>.option it will be completed using the resource from this
+ * {@literal <resource>}.option it will be completed using the resource from this
* instance
*
* @param key key for option
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java Sat Mar 02 11:26:47 2013 -0400
@@ -117,10 +117,6 @@
return new JoniRegExp(pattern, flags);
}
- @Override
- protected String replaceToken(final String str) {
- return str.equals("[^]") ? "[\\s\\S]" : str;
- }
}
class JoniMatcher implements RegExpMatcher {
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java Sat Mar 02 11:26:47 2013 -0400
@@ -68,25 +68,6 @@
}
/**
- * Replace a regexp token as suitable for regexp instances created by this factory.
- *
- * @param str a regular expression token
- * @return the replacement token
- */
- protected String replaceToken(final String str) {
- switch (str) {
- case "\\s":
- return "[" + Lexer.getWhitespaceRegExp() + "]";
- case "\\S":
- return "[^" + Lexer.getWhitespaceRegExp() + "]";
- case "[^]":
- return "[\\s\\S]";
- default:
- return str;
- }
- }
-
- /**
* Compile a regexp with the given {@code source} and {@code flags}.
*
* @param pattern RegExp pattern string
@@ -99,16 +80,6 @@
}
/**
- * Replace a regexp token as needed by the currently installed factory instance.
- *
- * @param token a regexp token
- * @return the replacement token
- */
- public static String replace(final String token) {
- return instance.replaceToken(token);
- }
-
- /**
* Validate a regexp with the given {@code source} and {@code flags}.
*
* @param pattern RegExp pattern string
@@ -120,4 +91,13 @@
public static void validate(final String pattern, final String flags) throws ParserException {
instance.compile(pattern, flags);
}
+
+ /**
+ * Returns true if the instance uses the JDK's {@code java.util.regex} package.
+ *
+ * @return true if instance uses JDK regex package
+ */
+ public static boolean usesJavaUtilRegex() {
+ return instance != null && instance.getClass() == RegExpFactory.class;
+ }
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java Sat Mar 02 11:26:47 2013 -0400
@@ -25,15 +25,15 @@
package jdk.nashorn.internal.runtime.regexp;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.regex.PatternSyntaxException;
+import jdk.nashorn.internal.parser.Lexer;
import jdk.nashorn.internal.parser.Scanner;
import jdk.nashorn.internal.runtime.BitVector;
@@ -44,17 +44,13 @@
final class RegExpScanner extends Scanner {
/**
- * String builder to accumulate the result - this contains verbatim parsed JavaScript.
- * to get the java equivalent we need to create a Pattern token and return its toString()
+ * String builder used to rewrite the pattern for the currently used regexp factory.
*/
private final StringBuilder sb;
/** Is this the special case of a regexp that never matches anything */
private boolean neverMatches;
- /** The resulting java.util.regex pattern string. */
- private String javaPattern;
-
/** Expected token table */
private final Map<Character, Integer> expected = new HashMap<>();
@@ -62,11 +58,14 @@
private final List<Capture> caps = new LinkedList<>();
/** Forward references to capturing parenthesis to be resolved later.*/
- private final Map<Integer, Token> forwardReferences = new LinkedHashMap<>();
+ private final Set<Integer> forwardReferences = new LinkedHashSet<>();
/** Current level of zero-width negative lookahead assertions. */
private int negativeLookaheadLevel;
+ /** Are we currently inside a character class? */
+ private boolean inCharClass = false;
+
private static final String NON_IDENT_ESCAPES = "$^*+(){}[]|\\.?";
private static class Capture {
@@ -74,11 +73,6 @@
* Zero-width negative lookaheads enclosing the capture.
*/
private final int negativeLookaheadLevel;
- /**
- * Captures that live inside a negative lookahead are dead after the
- * lookahead and will be undefined if referenced from outside.
- */
- private boolean isDead;
Capture(final int negativeLookaheadLevel) {
this.negativeLookaheadLevel = negativeLookaheadLevel;
@@ -88,336 +82,6 @@
return negativeLookaheadLevel;
}
- public boolean isDead() {
- return isDead;
- }
-
- public void setDead() {
- this.isDead = true;
- }
- }
-
- /**
- * This is a token - the JavaScript regexp is scanned into a token tree
- * A token has other tokens as children as well as "atoms", i.e. Strings.
- */
- private static class Token {
-
- private enum Type {
- PATTERN,
- DISJUNCTION,
- ALTERNATIVE,
- TERM,
- ASSERTION,
- QUANTIFIER,
- QUANTIFIER_PREFIX,
- ATOM,
- PATTERN_CHARACTER,
- ATOM_ESCAPE,
- CHARACTER_ESCAPE,
- CONTROL_ESCAPE,
- CONTROL_LETTER,
- IDENTITY_ESCAPE,
- DECIMAL_ESCAPE,
- CHARACTERCLASS_ESCAPE,
- CHARACTERCLASS,
- CLASSRANGES,
- NON_EMPTY_CLASSRANGES,
- NON_EMPTY_CLASSRANGES_NODASH,
- CLASSATOM,
- CLASSATOM_NODASH,
- CLASS_ESCAPE,
- DECIMALDIGITS,
- HEX_ESCAPESEQUENCE,
- UNICODE_ESCAPESEQUENCE,
- }
-
- /**
- * Token tyoe
- */
- private final Token.Type type;
-
- /**
- * Child nodes
- */
- private final List<Object> children;
-
- /**
- * Parent node
- */
- private Token parent;
-
- /**
- * Dead code flag
- */
- private boolean isDead;
-
- private static final Map<Type, ToString> toStringMap = new HashMap<>();
- private static final ToString DEFAULT_TOSTRING = new ToString();
-
- private static String unicode(final int value) {
- final StringBuilder sb = new StringBuilder();
- final String hex = Integer.toHexString(value);
- sb.append('u');
- for (int i = 0; i < 4 - hex.length(); i++) {
- sb.append('0');
- }
- sb.append(hex);
-
- return sb.toString();
- }
-
- static {
- toStringMap.put(Type.CHARACTERCLASS, new ToString() {
- @Override
- public String toString(final Token token) {
- return super.toString(token).replace("\\b", "\b");
- }
- });
-
- // for some reason java regexps don't like control characters on the
- // form "\\ca".match([string with ascii 1 at char0]). Translating
- // them to unicode does it though.
- toStringMap.put(Type.CHARACTER_ESCAPE, new ToString() {
- @Override
- public String toString(final Token token) {
- final String str = super.toString(token);
- if (str.length() == 2) {
- return Token.unicode(Character.toLowerCase(str.charAt(1)) - 'a' + 1);
- }
- return str;
- }
- });
-
- toStringMap.put(Type.DECIMAL_ESCAPE, new ToString() {
- @Override
- public String toString(final Token token) {
- final String str = super.toString(token);
-
- if ("\0".equals(str)) {
- return str;
- }
-
- int value;
-
- if (!token.hasParentOfType(Type.CLASSRANGES)) {
- return str;
- }
-
- value = Integer.parseInt(str, 8); //throws exception that leads to SyntaxError if not octal
- if (value > 0xff) {
- throw new NumberFormatException(str);
- }
-
- return Token.unicode(value);
- }
- });
-
- }
-
- /**
- * JavaScript Token to Java regex substring framework.
- */
- private static class ToString {
- String toString(final Token token) {
- final Object[] children = token.getChildren();
-
- // Allow the installed regexp factory to perform global substitutions.
- switch (children.length) {
- case 0:
- return "";
- case 1:
- return RegExpFactory.replace(children[0].toString());
- default:
- final StringBuilder sb = new StringBuilder();
- for (final Object child : children) {
- sb.append(child);
- }
- return RegExpFactory.replace(sb.toString());
- }
- }
- }
-
- /**
- * Token iterator. Doesn't return "atom" children. i.e. string representations,
- * just tokens
- *
- */
- private static class TokenIterator implements Iterator<Token> {
- private final List<Token> preorder;
-
- private void init(final Token root) {
- preorder.add(root);
- for (final Object child : root.getChildren()) {
- if (child instanceof Token) {
- init((Token)child);
- }
- }
- }
-
- TokenIterator(final Token root) {
- preorder = new ArrayList<>();
- init(root);
- }
-
- @Override
- public boolean hasNext() {
- return !preorder.isEmpty();
- }
-
- @Override
- public Token next() {
- return preorder.remove(0);
- }
-
- @Override
- public void remove() {
- next();
- }
- }
-
- /**
- * Constructor
- * @param type the token type
- */
- Token(final Token.Type type) {
- this.type = type;
- children = new ArrayList<>();
- }
-
- /**
- * Add a an "atom" child to a token
- * @param child the child to add
- * @return the token (for chaining)
- */
- public Token add(final String child) {
- children.add(child);
- return this;
- }
-
- /**
- * Add a child to a token
- * @param child the child
- * @return the token (for chaining)
- */
- public Token add(final Token child) {
- if (child != null) {
- children.add(child);
- child.setParent(this);
- }
- return this;
- }
-
- /**
- * Remove a child from a token
- * @param child the child to remove
- * @return true if successful
- */
- public boolean remove(final Token child) {
- return children.remove(child);
- }
-
- /**
- * Remove the last child from a token
- * @return the removed child
- */
- public Object removeLast() {
- return children.remove(children.size() - 1);
- }
-
- /**
- * Flag this token as dead code
- * @param isDead is it dead or not
- */
- private void setIsDead(final boolean isDead) {
- this.isDead = isDead;
- }
-
- /**
- * Is this token dead code
- * @return boolean
- */
- private boolean getIsDead() {
- return isDead;
- }
-
- /**
- * Get the parent of this token
- * @return parent token
- */
- public Token getParent() {
- return parent;
- }
-
- public boolean hasParentOfType(final Token.Type parentType) {
- for (Token p = getParent(); p != null; p = p.getParent()) {
- if (p.getType() == parentType) {
- return true;
- }
- }
- return false;
- }
-
- public boolean hasChildOfType(final Token.Type childType) {
- for (final Iterator<Token> iter = iterator() ; iter.hasNext() ; ) {
- if (iter.next().getType() == childType) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Set the parent of this token
- * @param parent
- */
- private void setParent(final Token parent) {
- this.parent = parent;
- }
-
- /**
- * Get the children of this token
- * @return an array of children, never null
- */
- public Object[] getChildren() {
- return children.toArray();
- }
-
- /**
- * Reset this token, remove all children
- */
- public void reset() {
- children.clear();
- }
-
- /**
- * Get a preorder token iterator with this token as root
- * @return an iterator
- */
- public Iterator<Token> iterator() {
- return new TokenIterator(this);
- }
-
- /**
- * Get the type of this token
- * @return type
- */
- public Type getType() {
- return type;
- }
-
- /**
- * Turn this token into Java regexp compatible text
- * @return part of a java regexp
- */
- @Override
- public String toString() {
- ToString t = toStringMap.get(getType());
- if (t == null) {
- t = DEFAULT_TOSTRING;
- }
- return t.toString(this);
- }
}
/**
@@ -437,13 +101,11 @@
return;
}
- for (final Map.Entry<Integer, Token> fwdRef : forwardReferences.entrySet()) {
- if (fwdRef.getKey().intValue() > caps.size()) {
+ for (final Integer ref : forwardReferences) {
+ if (ref.intValue() > caps.size()) {
neverMatches = true;
break;
}
-
- fwdRef.getValue().setIsDead(true);
}
forwardReferences.clear();
@@ -459,12 +121,10 @@
public static RegExpScanner scan(final String string) {
final RegExpScanner scanner = new RegExpScanner(string);
- Token pattern;
-
try {
- pattern = scanner.pattern();
+ scanner.disjunction();
} catch (final Exception e) {
- throw new PatternSyntaxException(e.getMessage(), string, scanner.sb.length());
+ throw new PatternSyntaxException(e.getMessage(), string, scanner.position);
}
scanner.processForwardReferences();
@@ -472,24 +132,12 @@
return null; // never matches
}
- // go over the code and remove dead code
- final Iterator<Token> iter = pattern.iterator();
- while (iter.hasNext()) {
- final Token next = iter.next();
- if (next.getIsDead()) {
- next.getParent().remove(next);
- }
- }
-
- // turn the pattern into a string, p, the java equivalent string for our js regexp
- final String p = pattern.toString();
- // if builder contains all tokens that were sent in, we know
- // we correctly parsed the entire JavaScript regexp without syntax errors
- if (!string.equals(scanner.getStringBuilder().toString())) {
+ // Throw syntax error unless we parsed the entire JavaScript regexp without syntax errors
+ if (scanner.position != string.length()) {
+ final String p = scanner.getStringBuilder().toString();
throw new PatternSyntaxException(string, p, p.length() + 1);
}
- scanner.javaPattern = p;
return scanner;
}
@@ -508,7 +156,7 @@
}
String getJavaPattern() {
- return javaPattern;
+ return sb.toString();
}
BitVector getGroupsInNegativeLookahead() {
@@ -527,11 +175,10 @@
/**
* Commit n characters to the builder and to a given token
- * @param token Uncommitted token.
* @param n Number of characters.
* @return Committed token
*/
- private Token commit(final Token token, final int n) {
+ private boolean commit(final int n) {
final int startIn = position;
switch (n) {
@@ -554,11 +201,7 @@
assert false : "Should not reach here";
}
- if (token == null) {
- return null;
- }
-
- return token.add(sb.substring(startIn, sb.length()));
+ return true;
}
/**
@@ -587,35 +230,20 @@
*/
/*
- * Pattern ::
- * Disjunction
- */
- private Token pattern() {
- final Token token = new Token(Token.Type.PATTERN);
-
- final Token child = disjunction();
- return token.add(child);
- }
-
- /*
* Disjunction ::
* Alternative
* Alternative | Disjunction
*/
- private Token disjunction() {
- final Token token = new Token(Token.Type.DISJUNCTION);
-
+ private void disjunction() {
while (true) {
- token.add(alternative());
+ alternative();
if (ch0 == '|') {
- commit(token, 1);
+ commit(1);
} else {
break;
}
}
-
- return token;
}
/*
@@ -623,15 +251,10 @@
* [empty]
* Alternative Term
*/
- private Token alternative() {
- final Token token = new Token(Token.Type.ALTERNATIVE);
-
- Token child;
- while ((child = term()) != null) {
- token.add(child);
+ private void alternative() {
+ while (term()) {
+ // do nothing
}
-
- return token;
}
/*
@@ -640,48 +263,37 @@
* Atom
* Atom Quantifier
*/
- private Token term() {
+ private boolean term() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.TERM);
- Token child;
- child = assertion();
- if (child != null) {
- return token.add(child);
+ if (assertion()) {
+ return true;
}
- child = atom();
- if (child != null) {
+ if (atom()) {
boolean emptyCharacterClass = false;
- if ("[]".equals(child.toString())) {
+ if (sb.toString().endsWith("[]")) {
emptyCharacterClass = true;
+ } else if (sb.toString().endsWith("[^]")) {
+ sb.setLength(sb.length() - 2);
+ sb.append("\\s\\S]");
}
- token.add(child);
-
- final Token quantifier = quantifier();
- if (quantifier != null) {
- token.add(quantifier);
- }
+ boolean quantifier = quantifier();
if (emptyCharacterClass) {
- if (quantifier == null) {
+ if (!quantifier) {
neverMatches = true; //never matches ever.
- } else {
- //if we can get away with max zero, remove this entire token
- final String qs = quantifier.toString();
- if ("+".equals(qs) || "*".equals(qs) || qs.startsWith("{0,")) {
- token.setIsDead(true);
- }
}
+ // Note: we could check if quantifier has min zero to mark empty character class as dead.
}
- return token;
+ return true;
}
restart(startIn, startOut);
- return null;
+ return false;
}
/*
@@ -693,19 +305,18 @@
* ( ? = Disjunction )
* ( ? ! Disjunction )
*/
- private Token assertion() {
+ private boolean assertion() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.ASSERTION);
switch (ch0) {
case '^':
case '$':
- return commit(token, 1);
+ return commit(1);
case '\\':
if (ch1 == 'b' || ch1 == 'B') {
- return commit(token, 2);
+ return commit(2);
}
break;
@@ -717,24 +328,18 @@
break;
}
final boolean isNegativeLookahead = (ch2 == '!');
- commit(token, 3);
+ commit(3);
if (isNegativeLookahead) {
negativeLookaheadLevel++;
}
- final Token disjunction = disjunction();
+ disjunction();
if (isNegativeLookahead) {
- for (final Capture cap : caps) {
- if (cap.getNegativeLookaheadLevel() >= negativeLookaheadLevel) {
- cap.setDead();
- }
- }
negativeLookaheadLevel--;
}
- if (disjunction != null && ch0 == ')') {
- token.add(disjunction);
- return commit(token, 1);
+ if (ch0 == ')') {
+ return commit(1);
}
break;
@@ -743,8 +348,7 @@
}
restart(startIn, startOut);
-
- return null;
+ return false;
}
/*
@@ -752,17 +356,14 @@
* QuantifierPrefix
* QuantifierPrefix ?
*/
- private Token quantifier() {
- final Token token = new Token(Token.Type.QUANTIFIER);
- final Token child = quantifierPrefix();
- if (child != null) {
- token.add(child);
+ private boolean quantifier() {
+ if (quantifierPrefix()) {
if (ch0 == '?') {
- commit(token, 1);
+ commit(1);
}
- return token;
+ return true;
}
- return null;
+ return false;
}
/*
@@ -774,45 +375,42 @@
* { DecimalDigits , }
* { DecimalDigits , DecimalDigits }
*/
- private Token quantifierPrefix() {
+ private boolean quantifierPrefix() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.QUANTIFIER_PREFIX);
switch (ch0) {
case '*':
case '+':
case '?':
- return commit(token, 1);
+ return commit(1);
case '{':
- commit(token, 1);
+ commit(1);
- final Token child = decimalDigits();
- if (child == null) {
+ if (!decimalDigits()) {
break; // not a quantifier - back out
}
push('}');
- token.add(child);
if (ch0 == ',') {
- commit(token, 1);
- token.add(decimalDigits());
+ commit(1);
+ decimalDigits();
}
if (ch0 == '}') {
pop('}');
- commit(token, 1);
+ commit(1);
}
- return token;
+ return true;
default:
break;
}
restart(startIn, startOut);
- return null;
+ return false;
}
/*
@@ -825,81 +423,51 @@
* ( ? : Disjunction )
*
*/
- private Token atom() {
+ private boolean atom() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.ATOM);
- Token child;
- child = patternCharacter();
- if (child != null) {
- return token.add(child);
+ if (patternCharacter()) {
+ return true;
}
if (ch0 == '.') {
- return commit(token, 1);
+ return commit(1);
}
if (ch0 == '\\') {
- commit(token, 1);
- child = atomEscape();
-
- if (child != null) {
- if (child.hasChildOfType(Token.Type.IDENTITY_ESCAPE)) {
- final char idEscape = child.toString().charAt(0);
- if (NON_IDENT_ESCAPES.indexOf(idEscape) == -1) {
- token.reset();
- }
- }
-
- token.add(child);
+ commit(1);
- // forward backreferences always match empty. JavaScript != Java
- if (child.hasChildOfType(Token.Type.DECIMAL_ESCAPE) && !"\u0000".equals(child.toString())) {
- final int refNum = Integer.parseInt(child.toString());
-
- if (refNum - 1 < caps.size() && caps.get(refNum - 1).isDead()) {
- // reference to dead in-negative-lookahead capture
- token.setIsDead(true);
- } else if (caps.size() < refNum) {
- // forward reference: always matches against empty string (dead token).
- // invalid reference (non-existant capture): pattern never matches.
- forwardReferences.put(refNum, token);
- }
- }
-
- return token;
+ if (atomEscape()) {
+ return true;
}
}
- child = characterClass();
- if (child != null) {
- return token.add(child);
+ if (characterClass()) {
+ return true;
}
if (ch0 == '(') {
boolean capturingParens = true;
- commit(token, 1);
+ commit(1);
if (ch0 == '?' && ch1 == ':') {
capturingParens = false;
- commit(token, 2);
+ commit(2);
}
- child = disjunction();
- if (child != null) {
- token.add(child);
- if (ch0 == ')') {
- final Token atom = commit(token, 1);
- if (capturingParens) {
- caps.add(new Capture(negativeLookaheadLevel));
- }
- return atom;
+ disjunction();
+
+ if (ch0 == ')') {
+ commit(1);
+ if (capturingParens) {
+ caps.add(new Capture(negativeLookaheadLevel));
}
+ return true;
}
}
restart(startIn, startOut);
- return null;
+ return false;
}
/*
@@ -907,9 +475,9 @@
* SourceCharacter but not any of: ^$\.*+?()[]{}|
*/
@SuppressWarnings("fallthrough")
- private Token patternCharacter() {
+ private boolean patternCharacter() {
if (atEOF()) {
- return null;
+ return false;
}
switch (ch0) {
@@ -924,23 +492,26 @@
case ')':
case '[':
case '|':
- return null;
+ return false;
case '}':
case ']':
final int n = expected.get(ch0);
if (n != 0) {
- return null;
+ return false;
}
case '{':
// if not a valid quantifier escape curly brace to match itself
// this ensures compatibility with other JS implementations
- final Token quant = quantifierPrefix();
- return (quant == null) ? commit(new Token(Token.Type.PATTERN_CHARACTER).add("\\"), 1) : null;
+ if (!quantifierPrefix()) {
+ sb.append('\\');
+ return commit(1);
+ }
+ return false;
default:
- return commit(new Token(Token.Type.PATTERN_CHARACTER), 1); // SOURCECHARACTER
+ return commit(1); // SOURCECHARACTER
}
}
@@ -950,27 +521,9 @@
* CharacterEscape
* CharacterClassEscape
*/
- private Token atomEscape() {
- final Token token = new Token(Token.Type.ATOM_ESCAPE);
- Token child;
-
- child = decimalEscape();
- if (child != null) {
- return token.add(child);
- }
-
- child = characterClassEscape();
- if (child != null) {
- return token.add(child);
- }
-
- child = characterEscape();
- if (child != null) {
- return token.add(child);
- }
-
-
- return null;
+ private boolean atomEscape() {
+ // Note that contrary to ES 5.1 spec we put identityEscape() last because it acts as a catch-all
+ return decimalEscape() || characterClassEscape() || characterEscape() || identityEscape();
}
/*
@@ -981,48 +534,31 @@
* UnicodeEscapeSequence
* IdentityEscape
*/
- private Token characterEscape() {
+ private boolean characterEscape() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.CHARACTER_ESCAPE);
- Token child;
-
- child = controlEscape();
- if (child != null) {
- return token.add(child);
+ if (controlEscape()) {
+ return true;
}
if (ch0 == 'c') {
- commit(token, 1);
- child = controlLetter();
- if (child != null) {
- return token.add(child);
+ commit(1);
+ if (controlLetter()) {
+ return true;
}
restart(startIn, startOut);
}
- child = hexEscapeSequence();
- if (child != null) {
- return token.add(child);
- }
-
- child = unicodeEscapeSequence();
- if (child != null) {
- return token.add(child);
- }
-
- child = identityEscape();
- if (child != null) {
- return token.add(child);
+ if (hexEscapeSequence() || unicodeEscapeSequence()) {
+ return true;
}
restart(startIn, startOut);
-
- return null;
+ return false;
}
- private boolean scanEscapeSequence(final char leader, final int length, final Token token) {
+ private boolean scanEscapeSequence(final char leader, final int length) {
final int startIn = position;
final int startOut = sb.length();
@@ -1030,11 +566,11 @@
return false;
}
- commit(token, 1);
+ commit(1);
for (int i = 0; i < length; i++) {
final char ch0l = Character.toLowerCase(ch0);
if ((ch0l >= 'a' && ch0l <= 'f') || isDecimalDigit(ch0)) {
- commit(token, 1);
+ commit(1);
} else {
restart(startIn, startOut);
return false;
@@ -1044,37 +580,29 @@
return true;
}
- private Token hexEscapeSequence() {
- final Token token = new Token(Token.Type.HEX_ESCAPESEQUENCE);
- if (scanEscapeSequence('x', 2, token)) {
- return token;
- }
- return null;
+ private boolean hexEscapeSequence() {
+ return scanEscapeSequence('x', 2);
}
- private Token unicodeEscapeSequence() {
- final Token token = new Token(Token.Type.UNICODE_ESCAPESEQUENCE);
- if (scanEscapeSequence('u', 4, token)) {
- return token;
- }
- return null;
+ private boolean unicodeEscapeSequence() {
+ return scanEscapeSequence('u', 4);
}
/*
* ControlEscape ::
* one of fnrtv
*/
- private Token controlEscape() {
+ private boolean controlEscape() {
switch (ch0) {
case 'f':
case 'n':
case 'r':
case 't':
case 'v':
- return commit(new Token(Token.Type.CONTROL_ESCAPE), 1);
+ return commit(1);
default:
- return null;
+ return false;
}
}
@@ -1083,19 +611,18 @@
* one of abcdefghijklmnopqrstuvwxyz
* ABCDEFGHIJKLMNOPQRSTUVWXYZ
*/
- private Token controlLetter() {
+ private boolean controlLetter() {
final char c = Character.toUpperCase(ch0);
if (c >= 'A' && c <= 'Z') {
- final Token token = new Token(Token.Type.CONTROL_LETTER);
- commit(token, 1);
- return token;
+ // for some reason java regexps don't like control characters on the
+ // form "\\ca".match([string with ascii 1 at char0]). Translating
+ // them to unicode does it though.
+ sb.setLength(sb.length() - 1);
+ unicode(c - 'A' + 1);
+ skip(1);
+ return true;
}
- return null;
- /*
- Token token = new Token(Token.Type.CONTROL_LETTER);
- commit(null, 1);//add original char to builder not to token
- this.neverMatches = c < 'A' || c > 'Z';
- return token.add(""+c);*/
+ return false;
}
/*
@@ -1104,56 +631,115 @@
* <ZWJ> (200c)
* <ZWNJ> (200d)
*/
- private Token identityEscape() {
- final Token token = new Token(Token.Type.IDENTITY_ESCAPE);
- commit(token, 1);
- return token;
+ private boolean identityEscape() {
+ if (atEOF()) {
+ throw new RuntimeException("\\ at end of pattern"); // will be converted to PatternSyntaxException
+ }
+ // ES 5.1 A.7 requires "not IdentifierPart" here but all major engines accept any character here.
+ if (NON_IDENT_ESCAPES.indexOf(ch0) == -1) {
+ sb.setLength(sb.length() - 1);
+ }
+ return commit(1);
}
/*
* DecimalEscape ::
* DecimalIntegerLiteral [lookahead DecimalDigit]
*/
- private Token decimalEscape() {
- final Token token = new Token(Token.Type.DECIMAL_ESCAPE);
+ private boolean decimalEscape() {
final int startIn = position;
final int startOut = sb.length();
if (ch0 == '0' && !isDecimalDigit(ch1)) {
- commit(token, 1);
- token.removeLast();
+ skip(1);
// DecimalEscape :: 0. If i is zero, return the EscapeValue consisting of a <NUL> character (Unicodevalue0000);
- return token.add("\u0000");
+ sb.append("\u0000");
+ return true;
}
if (isDecimalDigit(ch0)) {
- while (isDecimalDigit(ch0)) {
- commit(token, 1);
+ final int num = ch0 - '0';
+
+ // Single digit escape, treat as backreference.
+ if (!isDecimalDigit(ch1)) {
+ if (num <= caps.size() && caps.get(num - 1).getNegativeLookaheadLevel() > 0) {
+ // Captures that live inside a negative lookahead are dead after the
+ // lookahead and will be undefined if referenced from outside.
+ if (caps.get(num - 1).getNegativeLookaheadLevel() > negativeLookaheadLevel) {
+ sb.setLength(sb.length() - 1);
+ } else {
+ sb.append(ch0);
+ }
+ skip(1);
+ return true;
+ } else if (num > caps.size()) {
+ // Forward reference to a capture group. Forward references are always undefined so we
+ // can omit it from the output buffer. Additionally, if the capture group does not exist
+ // the whole regexp becomes invalid, so register the reference for later processing.
+ forwardReferences.add(num);
+ sb.setLength(sb.length() - 1);
+ skip(1);
+ return true;
+ }
}
- return token;
+
+ if (inCharClass) {
+ // Convert octal escape to unicode escape if inside character class.
+ StringBuilder digit = new StringBuilder(4);
+ while (isDecimalDigit(ch0)) {
+ digit.append(ch0);
+ skip(1);
+ }
+
+ int value = Integer.parseInt(digit.toString(), 8); //throws exception that leads to SyntaxError if not octal
+ if (value > 0xff) {
+ throw new NumberFormatException(digit.toString());
+ }
+
+ unicode(value);
+
+ } else {
+ // Copy decimal escape as-is
+ decimalDigits();
+ }
+ return true;
}
restart(startIn, startOut);
-
- return null;
+ return false;
}
/*
* CharacterClassEscape ::
* one of dDsSwW
*/
- private Token characterClassEscape() {
+ private boolean characterClassEscape() {
switch (ch0) {
+ // java.util.regex requires translation of \s and \S to explicit character list
case 's':
+ if (RegExpFactory.usesJavaUtilRegex()) {
+ sb.setLength(sb.length() - 1);
+ sb.append('[').append(Lexer.getWhitespaceRegExp()).append(']');
+ skip(1);
+ return true;
+ }
+ return commit(1);
case 'S':
+ if (RegExpFactory.usesJavaUtilRegex()) {
+ sb.setLength(sb.length() - 1);
+ sb.append("[^").append(Lexer.getWhitespaceRegExp()).append(']');
+ skip(1);
+ return true;
+ }
+ return commit(1);
case 'd':
case 'D':
case 'w':
case 'W':
- return commit(new Token(Token.Type.CHARACTERCLASS_ESCAPE), 1);
+ return commit(1);
default:
- return null;
+ return false;
}
}
@@ -1162,29 +748,31 @@
* [ [lookahead {^}] ClassRanges ]
* [ ^ ClassRanges ]
*/
- private Token characterClass() {
+ private boolean characterClass() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.CHARACTERCLASS);
if (ch0 == '[') {
- push(']');
- commit(token, 1);
+ try {
+ inCharClass = true;
+ push(']');
+ commit(1);
- if (ch0 == '^') {
- commit(token, 1);
- }
+ if (ch0 == '^') {
+ commit(1);
+ }
- final Token child = classRanges();
- if (child != null && ch0 == ']') {
- pop(']');
- token.add(child);
- return commit(token, 1);
+ if (classRanges() && ch0 == ']') {
+ pop(']');
+ return commit(1);
+ }
+ } finally {
+ inCharClass = false; // no nested character classes in JavaScript
}
}
restart(startIn, startOut);
- return null;
+ return false;
}
/*
@@ -1192,8 +780,9 @@
* [empty]
* NonemptyClassRanges
*/
- private Token classRanges() {
- return new Token(Token.Type.CLASSRANGES).add(nonemptyClassRanges());
+ private boolean classRanges() {
+ nonemptyClassRanges();
+ return true;
}
/*
@@ -1202,40 +791,27 @@
* ClassAtom NonemptyClassRangesNoDash
* ClassAtom - ClassAtom ClassRanges
*/
- private Token nonemptyClassRanges() {
+ private boolean nonemptyClassRanges() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.NON_EMPTY_CLASSRANGES);
- Token child;
- child = classAtom();
- if (child != null) {
- token.add(child);
+ if (classAtom()) {
if (ch0 == '-') {
- commit(token, 1);
+ commit(1);
- final Token child1 = classAtom();
- final Token child2 = classRanges();
- if (child1 != null && child2 != null) {
- token.add(child1);
- token.add(child2);
-
- return token;
+ if (classAtom() && classRanges()) {
+ return true;
}
}
- child = nonemptyClassRangesNoDash();
- if (child != null) {
- token.add(child);
- return token;
- }
+ nonemptyClassRangesNoDash();
- return token;
+ return true;
}
restart(startIn, startOut);
- return null;
+ return false;
}
/*
@@ -1244,61 +820,44 @@
* ClassAtomNoDash NonemptyClassRangesNoDash
* ClassAtomNoDash - ClassAtom ClassRanges
*/
- private Token nonemptyClassRangesNoDash() {
+ private boolean nonemptyClassRangesNoDash() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.NON_EMPTY_CLASSRANGES_NODASH);
- Token child;
- child = classAtomNoDash();
- if (child != null) {
- token.add(child);
+ if (classAtomNoDash()) {
// need to check dash first, as for e.g. [a-b|c-d] will otherwise parse - as an atom
if (ch0 == '-') {
- commit(token, 1);
+ commit(1);
- final Token child1 = classAtom();
- final Token child2 = classRanges();
- if (child1 != null && child2 != null) {
- token.add(child1);
- return token.add(child2);
+ if (classAtom() && classRanges()) {
+ return true;
}
//fallthru
}
- child = nonemptyClassRangesNoDash();
- if (child != null) {
- token.add(child);
- }
- return token; // still a class atom
+ nonemptyClassRangesNoDash();
+ return true; // still a class atom
}
- child = classAtom();
- if (child != null) {
- return token.add(child);
+ if (classAtom()) {
+ return true;
}
restart(startIn, startOut);
- return null;
+ return false;
}
/*
* ClassAtom : - ClassAtomNoDash
*/
- private Token classAtom() {
- final Token token = new Token(Token.Type.CLASSATOM);
+ private boolean classAtom() {
if (ch0 == '-') {
- return commit(token, 1);
+ return commit(1);
}
- final Token child = classAtomNoDash();
- if (child != null) {
- return token.add(child);
- }
-
- return null;
+ return classAtomNoDash();
}
/*
@@ -1306,33 +865,32 @@
* SourceCharacter but not one of \ or ] or -
* \ ClassEscape
*/
- private Token classAtomNoDash() {
+ private boolean classAtomNoDash() {
final int startIn = position;
final int startOut = sb.length();
- final Token token = new Token(Token.Type.CLASSATOM_NODASH);
switch (ch0) {
case ']':
case '-':
case '\0':
- return null;
+ return false;
case '[':
// unescaped left square bracket - add escape
- return commit(token.add("\\"), 1);
+ sb.append('\\');
+ return commit(1);
case '\\':
- commit(token, 1);
- final Token child = classEscape();
- if (child != null) {
- return token.add(child);
+ commit(1);
+ if (classEscape()) {
+ return true;
}
restart(startIn, startOut);
- return null;
+ return false;
default:
- return commit(token, 1);
+ return commit(1);
}
}
@@ -1343,46 +901,45 @@
* CharacterEscape
* CharacterClassEscape
*/
- private Token classEscape() {
- final Token token = new Token(Token.Type.CLASS_ESCAPE);
- Token child;
+ private boolean classEscape() {
- child = decimalEscape();
- if (child != null) {
- return token.add(child);
+ if (decimalEscape()) {
+ return true;
}
if (ch0 == 'b') {
- return commit(token, 1);
+ sb.setLength(sb.length() - 1);
+ sb.append('\b');
+ skip(1);
+ return true;
}
- child = characterEscape();
- if (child != null) {
- return token.add(child);
- }
-
- child = characterClassEscape();
- if (child != null) {
- return token.add(child);
- }
-
- return null;
+ // Note that contrary to ES 5.1 spec we put identityEscape() last because it acts as a catch-all
+ return characterEscape() || characterClassEscape() || identityEscape();
}
/*
* DecimalDigits
*/
- private Token decimalDigits() {
+ private boolean decimalDigits() {
if (!isDecimalDigit(ch0)) {
- return null;
+ return false;
+ }
+
+ while (isDecimalDigit(ch0)) {
+ commit(1);
}
- final Token token = new Token(Token.Type.DECIMALDIGITS);
- while (isDecimalDigit(ch0)) {
- commit(token, 1);
+ return true;
+ }
+
+ private void unicode(final int value) {
+ final String hex = Integer.toHexString(value);
+ sb.append('u');
+ for (int i = 0; i < 4 - hex.length(); i++) {
+ sb.append('0');
}
-
- return token;
+ sb.append(hex);
}
private static boolean isDecimalDigit(final char ch) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java Wed Feb 27 14:12:45 2013 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java Sat Mar 02 11:26:47 2013 -0400
@@ -219,7 +219,7 @@
}
/**
- * @see [http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt]
+ * @see <a href="http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt">http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt</a>
*/
public static boolean isCodeCType(int code, int ctype) {
int type;