From: <rb...@us...> - 2018-04-13 18:25:10
|
Revision: 15231 http://sourceforge.net/p/htmlunit/code/15231 Author: rbri Date: 2018-04-13 18:25:05 +0000 (Fri, 13 Apr 2018) Log Message: ----------- use the symbol implementation from rhino (and other es6 features) Modified Paths: -------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Map.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Set.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/ScriptableObjectTest.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/SymbolTest.java Removed Paths: ------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Symbol.java Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -267,6 +267,7 @@ @Override protected Context makeContext() { final TimeoutContext cx = new TimeoutContext(this); + cx.setLanguageVersion(Context.VERSION_ES6); // Use pure interpreter mode to get observeInstructionCount() callbacks. cx.setOptimizationLevel(-1); Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -69,7 +69,6 @@ import com.gargoylesoftware.htmlunit.javascript.host.SimpleArray; import com.gargoylesoftware.htmlunit.javascript.host.Storage; import com.gargoylesoftware.htmlunit.javascript.host.StorageManager; -import com.gargoylesoftware.htmlunit.javascript.host.Symbol; import com.gargoylesoftware.htmlunit.javascript.host.TextDecoder; import com.gargoylesoftware.htmlunit.javascript.host.TextEncoder; import com.gargoylesoftware.htmlunit.javascript.host.Touch; @@ -593,7 +592,7 @@ SVGSymbolElement.class, SVGTextContentElement.class, SVGTextElement.class, SVGTextPathElement.class, SVGTextPositioningElement.class, SVGTitleElement.class, SVGTransform.class, SVGTransformList.class, SVGTSpanElement.class, SVGUnitTypes.class, SVGUseElement.class, SVGViewElement.class, - SVGZoomEvent.class, Symbol.class, SyncManager.class, Text.class, TextDecoder.class, + SVGZoomEvent.class, SyncManager.class, Text.class, TextDecoder.class, TextEncoder.class, TextEvent.class, TextMetrics.class, TextRange.class, TextTrack.class, TextTrackCue.class, TextTrackCueList.class, TextTrackList.class, TimeEvent.class, TimeRanges.class, Touch.class, TouchEvent.class, TouchList.class, TrackEvent.class, TransitionEvent.class, TreeWalker.class, Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -26,6 +26,8 @@ import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime; import net.sourceforge.htmlunit.corejs.javascript.Scriptable; import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; +import net.sourceforge.htmlunit.corejs.javascript.SymbolKey; +import net.sourceforge.htmlunit.corejs.javascript.SymbolScriptable; import net.sourceforge.htmlunit.corejs.javascript.Undefined; /** @@ -113,7 +115,10 @@ final Scriptable thisObj, final Scriptable scriptable, final Consumer<Object> processor) { - final Object iterator = scriptable.get(Symbol.ITERATOR_STRING, scriptable); + if (!(scriptable instanceof SymbolScriptable)) { + return false; + } + final Object iterator = ((SymbolScriptable) scriptable).get(SymbolKey.ITERATOR, scriptable); if (iterator == Scriptable.NOT_FOUND) { return false; } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Map.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Map.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Map.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -36,6 +36,9 @@ import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime; import net.sourceforge.htmlunit.corejs.javascript.Scriptable; import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; +import net.sourceforge.htmlunit.corejs.javascript.Symbol; +import net.sourceforge.htmlunit.corejs.javascript.SymbolKey; +import net.sourceforge.htmlunit.corejs.javascript.SymbolScriptable; import net.sourceforge.htmlunit.corejs.javascript.Undefined; /** @@ -45,7 +48,7 @@ * @author Ronald Brill */ @JsxClass -public class Map extends SimpleScriptable { +public class Map extends SimpleScriptable implements SymbolScriptable { private static final String MAP_ITERATOR_NAME = "Map Iterator"; private static Iterator ITERATOR_PROTOTYPE_; @@ -214,18 +217,6 @@ } /** - * {@inheritDoc} - */ - @Override - public Object get(final String name, final Scriptable start) { - // A hack to handle Rhino not supporting "get(Object object, Scriptable start)" - if (name.equals(Symbol.ITERATOR_STRING)) { - return ScriptableObject.getProperty(start, "entries"); - } - return super.get(name, start); - } - - /** * Returns a new {@code Iterator} object that contains the {@code [key, value]} pairs for each element in the * Map object in insertion order. * @return a new {@code Iterator} object @@ -295,4 +286,26 @@ new Object[] {entry.getValue(), entry.getKey(), this}); } } + + /** + * {@inheritDoc} + */ + @Override + public Object get(final Symbol key, final Scriptable start) { + if (SymbolKey.ITERATOR.equals(key)) { + return ScriptableObject.getProperty(start, "entries"); + } + return super.get(key, start); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean has(final Symbol key, final Scriptable start) { + if (SymbolKey.ITERATOR.equals(key)) { + return true; + } + return super.has(key, start); + } } Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Set.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Set.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Set.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -35,6 +35,9 @@ import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime; import net.sourceforge.htmlunit.corejs.javascript.Scriptable; import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; +import net.sourceforge.htmlunit.corejs.javascript.Symbol; +import net.sourceforge.htmlunit.corejs.javascript.SymbolKey; +import net.sourceforge.htmlunit.corejs.javascript.SymbolScriptable; import net.sourceforge.htmlunit.corejs.javascript.Undefined; /** @@ -44,7 +47,7 @@ * @author Ronald Brill */ @JsxClass -public class Set extends SimpleScriptable { +public class Set extends SimpleScriptable implements SymbolScriptable { private static final String SET_ITERATOR_NAME = "Set Iterator"; private static Iterator ITERATOR_PROTOTYPE_; @@ -184,18 +187,6 @@ } /** - * {@inheritDoc} - */ - @Override - public Object get(final String name, final Scriptable start) { - // A hack to handle Rhino not supporting "get(Object object, Scriptable start)" - if (name.equals(Symbol.ITERATOR_STRING)) { - return ScriptableObject.getProperty(start, "values"); - } - return super.get(name, start); - } - - /** * Returns a new {@code Iterator} object that contains the values for each element in the Set object * in insertion order. * @return a new {@code Iterator} object @@ -238,4 +229,26 @@ new Object[] {object, object, this}); } } + + /** + * {@inheritDoc} + */ + @Override + public Object get(final Symbol key, final Scriptable start) { + if (SymbolKey.ITERATOR.equals(key)) { + return ScriptableObject.getProperty(start, "values"); + } + return super.get(key, start); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean has(final Symbol key, final Scriptable start) { + if (SymbolKey.ITERATOR.equals(key)) { + return true; + } + return super.has(key, start); + } } Deleted: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Symbol.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Symbol.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Symbol.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2002-2018 Gargoyle Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gargoylesoftware.htmlunit.javascript.host; - -import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME; -import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE; -import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF; -import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import com.gargoylesoftware.htmlunit.BrowserVersion; -import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable; -import com.gargoylesoftware.htmlunit.javascript.configuration.AbstractJavaScriptConfiguration; -import com.gargoylesoftware.htmlunit.javascript.configuration.ClassConfiguration; -import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; -import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor; -import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction; -import com.gargoylesoftware.htmlunit.javascript.configuration.JsxStaticFunction; -import com.gargoylesoftware.htmlunit.javascript.configuration.JsxStaticGetter; - -import net.sourceforge.htmlunit.corejs.javascript.Context; -import net.sourceforge.htmlunit.corejs.javascript.Function; -import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime; -import net.sourceforge.htmlunit.corejs.javascript.Scriptable; -import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; -import net.sourceforge.htmlunit.corejs.javascript.Undefined; - -/** - * A JavaScript object for {@code Symbol}. - * - * @author Ahmed Ashour - * @author Ronald Brill - */ -@JsxClass({CHROME, FF, EDGE}) -public class Symbol extends SimpleScriptable { - - static final String ITERATOR_STRING = "Symbol(Symbol.iterator)"; - private static Map<String, Map<String, Symbol>> SYMBOL_MAP_ = new HashMap<>(); - - private Object name_; - - /** - * Default constructor. - */ - public Symbol() { - } - - /** - * Creates an instance. - * @param name the name - */ - @JsxConstructor - public Symbol(final Object name) { - name_ = name; - for (final StackTraceElement stackElement : new Throwable().getStackTrace()) { - if (stackElement.getClassName().contains("BaseFunction") - && "construct".equals(stackElement.getMethodName())) { - throw ScriptRuntime.typeError("Symbol is not a constructor"); - } - } - } - - /** - * Returns the {@code iterator} static property. - * @param thisObj the scriptable - * @return the {@code iterator} static property - */ - @JsxStaticGetter - public static Symbol getIterator(final Scriptable thisObj) { - return getSymbol(thisObj, "iterator"); - } - - private static Symbol getSymbol(final Scriptable thisObj, final String name) { - final SimpleScriptable scope = (SimpleScriptable) thisObj.getParentScope(); - final BrowserVersion browserVersion = scope.getBrowserVersion(); - - Map<String, Symbol> map = SYMBOL_MAP_.get(browserVersion.getNickname()); - if (map == null) { - map = new HashMap<>(); - SYMBOL_MAP_.put(browserVersion.getNickname(), map); - } - - return map.computeIfAbsent(name, - k -> { - final Symbol sym = new Symbol(); - sym.name_ = k; - sym.setParentScope(scope); - sym.setPrototype(scope.getPrototype(sym.getClass())); - return sym; - }); - } - - /** - * Returns the {@code unscopables} static property. - * @param thisObj the scriptable - * @return the {@code unscopables} static property - */ - @JsxStaticGetter({CHROME, FF52}) - public static Symbol getUnscopables(final Scriptable thisObj) { - return getSymbol(thisObj, "unscopables"); - } - - /** - * Returns the {@code isConcatSpreadable} static property. - * @param thisObj the scriptable - * @return the {@code isConcatSpreadable} static property - */ - @JsxStaticGetter({CHROME, FF52}) - public static Symbol getIsConcatSpreadable(final Scriptable thisObj) { - return getSymbol(thisObj, "isConcatSpreadable"); - } - - /** - * Returns the {@code toPrimitive} static property. - * @param thisObj the scriptable - * @return the {@code toPrimitive} static property - */ - @JsxStaticGetter({CHROME, FF}) - public static Symbol getToPrimitive(final Scriptable thisObj) { - return getSymbol(thisObj, "toPrimitive"); - } - - /** - * Returns the {@code toStringTag} static property. - * @param thisObj the scriptable - * @return the {@code toStringTag} static property - */ - @JsxStaticGetter({CHROME, FF52}) - public static Symbol getToStringTag(final Scriptable thisObj) { - return getSymbol(thisObj, "toStringTag"); - } - - /** - * Returns the {@code match} static property. - * @param thisObj the scriptable - * @return the {@code match} static property - */ - @JsxStaticGetter({CHROME, FF}) - public static Symbol getMatch(final Scriptable thisObj) { - return getSymbol(thisObj, "match"); - } - - /** - * Returns the {@code hasInstance} static property. - * @param thisObj the scriptable - * @return the {@code hasInstance} static property - */ - @JsxStaticGetter({CHROME, FF52}) - public static Symbol getHasInstance(final Scriptable thisObj) { - return getSymbol(thisObj, "hasInstance"); - } - - /** - * Returns the {@code replace} static property. - * @param thisObj the scriptable - * @return the {@code replace} static property - */ - @JsxStaticGetter({CHROME, FF52}) - public static Symbol getReplace(final Scriptable thisObj) { - return getSymbol(thisObj, "replace"); - } - - /** - * Returns the {@code search} static property. - * @param thisObj the scriptable - * @return the {@code search} static property - */ - @JsxStaticGetter({CHROME, FF52}) - public static Symbol getSearch(final Scriptable thisObj) { - return getSymbol(thisObj, "search"); - } - - /** - * Returns the {@code split} static property. - * @param thisObj the scriptable - * @return the {@code split} static property - */ - @JsxStaticGetter({CHROME, FF52}) - public static Symbol getSplit(final Scriptable thisObj) { - return getSymbol(thisObj, "split"); - } - - /** - * Returns the {@code species} static property. - * @param thisObj the scriptable - * @return the {@code species} static property - */ - @JsxStaticGetter({CHROME, FF}) - public static Symbol getSpecies(final Scriptable thisObj) { - return getSymbol(thisObj, "species"); - } - - /** - * Searches for existing symbols in a runtime-wide symbol registry with the given key and returns it if found. - * Otherwise a new symbol gets created in the global symbol registry with this key. - * @param context the context - * @param thisObj this object - * @param args the arguments - * @param function the function - * @return the symbol - */ - @JsxStaticFunction(functionName = "for") - public static Symbol forFunction(final Context context, final Scriptable thisObj, final Object[] args, - final Function function) { - final String key = Context.toString(args.length != 0 ? args[0] : Undefined.instance); - - Symbol symbol = (Symbol) ((ScriptableObject) thisObj).get(key); - if (symbol == null) { - final SimpleScriptable parentScope = (SimpleScriptable) thisObj.getParentScope(); - - symbol = new Symbol(); - symbol.name_ = key; - symbol.setParentScope(parentScope); - symbol.setPrototype(parentScope.getPrototype(symbol.getClass())); - thisObj.put(key, thisObj, symbol); - } - return symbol; - } - - /** - * {@inheritDoc} - */ - @Override - public String getTypeOf() { - return "symbol"; - } - - /** - * {@inheritDoc} - */ - @Override - @JsxFunction - public String toString() { - if (name_ == Undefined.instance) { - return "Symbol()"; - } - - final ClassConfiguration config = AbstractJavaScriptConfiguration - .getClassConfiguration(getClass(), getBrowserVersion()); - - final String name = Context.toString(name_); - for (final Entry<String, ClassConfiguration.PropertyInfo> propertyEntry : config.getStaticPropertyEntries()) { - if (propertyEntry.getKey().equals(name)) { - return "Symbol(Symbol." + name + ')'; - } - } - return "Symbol(" + name + ')'; - } - - /** - * {@inheritDoc} - */ - @Override - public Object getDefaultValue(final Class<?> hint) { - if (String.class.equals(hint) || hint == null) { - return toString(); - } - return super.getDefaultValue(hint); - } - - /** - * Removes all cached symbols, which have the specified {@code window} as their parent scope. - * @param window the window - */ - public static void remove(final Window window) { - for (final Map<String, Symbol> symbols : SYMBOL_MAP_.values()) { - for (final java.util.Iterator<Symbol> it = symbols.values().iterator(); it.hasNext();) { - if (it.next().getParentScope() == window) { - it.remove(); - } - } - } - } -} Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -2347,7 +2347,6 @@ */ @Override public void close() { - Symbol.remove(this); } /** Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/ScriptableObjectTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/ScriptableObjectTest.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/ScriptableObjectTest.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -14,15 +14,11 @@ */ package com.gargoylesoftware.htmlunit.javascript; -import static com.gargoylesoftware.htmlunit.BrowserRunner.TestedBrowser.CHROME; -import static com.gargoylesoftware.htmlunit.BrowserRunner.TestedBrowser.FF; - import org.junit.Test; import org.junit.runner.RunWith; import com.gargoylesoftware.htmlunit.BrowserRunner; import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; -import com.gargoylesoftware.htmlunit.BrowserRunner.NotYetImplemented; import com.gargoylesoftware.htmlunit.WebDriverTestCase; /** @@ -70,7 +66,6 @@ @Test @Alerts(DEFAULT = {"2", "symbol", "symbol", "1", "c"}, IE = "not defined") - @NotYetImplemented({CHROME, FF}) public void getOwnPropertySymbols() throws Exception { final String html = "<html><body>\n" + "<script>\n" Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/SymbolTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/SymbolTest.java 2018-04-09 19:17:19 UTC (rev 15230) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/SymbolTest.java 2018-04-13 18:25:05 UTC (rev 15231) @@ -14,15 +14,11 @@ */ package com.gargoylesoftware.htmlunit.javascript.host; -import static com.gargoylesoftware.htmlunit.BrowserRunner.TestedBrowser.CHROME; -import static com.gargoylesoftware.htmlunit.BrowserRunner.TestedBrowser.FF52; - import org.junit.Test; import org.junit.runner.RunWith; import com.gargoylesoftware.htmlunit.BrowserRunner; import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts; -import com.gargoylesoftware.htmlunit.BrowserRunner.NotYetImplemented; import com.gargoylesoftware.htmlunit.WebDriverTestCase; import com.gargoylesoftware.htmlunit.html.HtmlPageTest; @@ -178,7 +174,6 @@ @Alerts(DEFAULT = {"Symbol()", "Symbol(foo)", "Symbol(Symbol.iterator)", "exception"}, FF45 = {"Symbol()", "Symbol(foo)", "Symbol(Symbol.iterator)", "undefined"}, IE = "not supported") - @NotYetImplemented({CHROME, FF52}) public void string() throws Exception { final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ |