Bugfixes and improvements, trying to launch Knockout4Java

This commit is contained in:
konsoletyper 2014-02-24 13:07:06 +04:00
parent d34e26e970
commit 0004babe65
14 changed files with 296 additions and 19 deletions

View File

@ -38,8 +38,9 @@ public class EnumDependencySupport implements DependencyListener {
public void classAchieved(DependencyChecker dependencyChecker, String className) { public void classAchieved(DependencyChecker dependencyChecker, String className) {
ClassReader cls = dependencyChecker.getClassSource().get(className); ClassReader cls = dependencyChecker.getClassSource().get(className);
if (cls == null || cls.getParent() == null || !cls.getParent().equals("java.lang.Enum")) { if (cls == null || cls.getParent() == null || !cls.getParent().equals("java.lang.Enum")) {
allEnums.propagate(className); return;
} }
allEnums.propagate(className);
if (enumConstantsStack != null) { if (enumConstantsStack != null) {
MethodReader method = cls.getMethod(new MethodDescriptor("values", MethodReader method = cls.getMethod(new MethodDescriptor("values",
ValueType.arrayOf(ValueType.object(cls.getName())))); ValueType.arrayOf(ValueType.object(cls.getName()))));

View File

@ -34,6 +34,9 @@ public class NewInstanceDependencySupport implements DependencyListener {
@Override @Override
public void classAchieved(DependencyChecker dependencyChecker, String className) { public void classAchieved(DependencyChecker dependencyChecker, String className) {
ClassReader cls = dependencyChecker.getClassSource().get(className); ClassReader cls = dependencyChecker.getClassSource().get(className);
if (cls == null) {
return;
}
if (cls.hasModifier(ElementModifier.ABSTRACT) || cls.hasModifier(ElementModifier.INTERFACE)) { if (cls.hasModifier(ElementModifier.ABSTRACT) || cls.hasModifier(ElementModifier.INTERFACE)) {
return; return;
} }

View File

@ -65,13 +65,13 @@ public class ObjectNativeGenerator implements Generator, Injector, DependencyPlu
public void methodAchieved(DependencyChecker checker, MethodDependency method) { public void methodAchieved(DependencyChecker checker, MethodDependency method) {
switch (method.getReference().getName()) { switch (method.getReference().getName()) {
case "clone": case "clone":
achieveClone(method); method.getVariable(0).connect(method.getResult());
break; break;
case "getClass": case "getClass":
achieveGetClass(checker, method); achieveGetClass(checker, method);
break; break;
case "wrap": case "wrap":
achieveWrap(method); method.getVariable(1).connect(method.getResult());
break; break;
} }
} }
@ -109,15 +109,7 @@ public class ObjectNativeGenerator implements Generator, Injector, DependencyPlu
writer.append("return copy;").softNewLine(); writer.append("return copy;").softNewLine();
} }
private void achieveClone(MethodDependency method) {
method.getVariable(0).connect(method.getResult());
}
private void generateWrap(InjectorContext context) throws IOException { private void generateWrap(InjectorContext context) throws IOException {
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0));
} }
private void achieveWrap(MethodDependency graph) {
graph.getVariable(1).connect(graph.getResult());
}
} }

View File

@ -16,6 +16,9 @@
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import java.io.IOException; import java.io.IOException;
import org.teavm.dependency.DependencyChecker;
import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.ni.Injector; import org.teavm.javascript.ni.Injector;
import org.teavm.javascript.ni.InjectorContext; import org.teavm.javascript.ni.InjectorContext;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -24,17 +27,22 @@ import org.teavm.model.MethodReference;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class StringNativeGenerator implements Injector { public class StringNativeGenerator implements Injector, DependencyPlugin {
@Override @Override
public void generate(InjectorContext context, MethodReference methodRef) throws IOException { public void methodAchieved(DependencyChecker checker, MethodDependency method) {
switch (methodRef.getName()) { switch (method.getReference().getName()) {
case "wrap": case "wrap":
generateWrap(context); method.getVariable(0).connect(method.getResult());
break; break;
} }
} }
private void generateWrap(InjectorContext context) throws IOException { @Override
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
switch (methodRef.getName()) {
case "wrap":
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0));
break;
}
} }
} }

View File

@ -19,6 +19,7 @@ import org.teavm.classlib.impl.charset.*;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.io.TUnsupportedEncodingException; import org.teavm.classlib.java.io.TUnsupportedEncodingException;
import org.teavm.classlib.java.util.TArrays; import org.teavm.classlib.java.util.TArrays;
import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.javascript.ni.InjectedBy;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.ni.Rename;
@ -549,6 +550,7 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
} }
@InjectedBy(StringNativeGenerator.class) @InjectedBy(StringNativeGenerator.class)
@PluggableDependency(StringNativeGenerator.class)
public static native TString wrap(String str); public static native TString wrap(String str);
public TString toLowerCase() { public TString toLowerCase() {

View File

@ -0,0 +1,50 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.classlib.java.lang;
/**
*
* @author Alexey Andreev
*/
public class TThreadLocal<T> extends TObject {
private boolean initialized;
private T value;
public TThreadLocal() {
super();
}
protected T initialValue() {
return null;
}
public T get() {
if (!initialized) {
value = initialValue();
initialized = true;
}
return value;
}
public void set(T value) {
this.value = value;
}
public void remove() {
initialized = false;
value = null;
}
}

View File

@ -42,6 +42,7 @@ public class TArrayList<E> extends TAbstractList<E> implements TCloneable, TSeri
for (int i = 0; i < array.length; ++i) { for (int i = 0; i < array.length; ++i) {
array[i] = iter.next(); array[i] = iter.next();
} }
size = array.length;
} }
public void trimToSize() { public void trimToSize() {

View File

@ -0,0 +1,44 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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 org.teavm.classlib.java.lang.util;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
/**
*
* @author Alexey Andreev
*/
public class CollectionsTest {
private List<Integer> array;
@Test
public void arraySorted() {
array = new ArrayList<>();
array.addAll(Arrays.asList(2, 5, 7, 3, 5, 6));
Collections.sort(array);
assertEquals(Integer.valueOf(2), array.get(0));
assertEquals(Integer.valueOf(3), array.get(1));
assertEquals(Integer.valueOf(5), array.get(2));
assertEquals(Integer.valueOf(5), array.get(3));
assertEquals(Integer.valueOf(6), array.get(4));
assertEquals(Integer.valueOf(7), array.get(5));
}
}

View File

@ -20,5 +20,5 @@ package org.teavm.dependency;
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public interface DependencyPlugin { public interface DependencyPlugin {
void methodAchieved(DependencyChecker checker, MethodDependency graph); void methodAchieved(DependencyChecker checker, MethodDependency method);
} }

View File

@ -90,6 +90,9 @@ class BreakToContinueReplacer implements StatementVisitor {
@Override @Override
public void visit(ContinueStatement statement) { public void visit(ContinueStatement statement) {
if (statement.getTarget() == replacedBreak) {
statement.setTarget(replacement);
}
} }
@Override @Override

View File

@ -1225,7 +1225,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
if (expr.getType() instanceof ValueType.Object) { if (expr.getType() instanceof ValueType.Object) {
String clsName = ((ValueType.Object)expr.getType()).getClassName(); String clsName = ((ValueType.Object)expr.getType()).getClassName();
ClassHolder cls = classSource.get(clsName); ClassHolder cls = classSource.get(clsName);
if (!cls.getModifiers().contains(ElementModifier.INTERFACE)) { if (cls != null && !cls.getModifiers().contains(ElementModifier.INTERFACE)) {
writer.append("("); writer.append("(");
expr.getExpr().acceptVisitor(this); expr.getExpr().acceptVisitor(this);
writer.append(" instanceof ").appendClass(clsName).append(")"); writer.append(" instanceof ").appendClass(clsName).append(")");

View File

@ -45,6 +45,12 @@
<version>0.8-SNAPSHOT</version> <version>0.8-SNAPSHOT</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.netbeans.html</groupId>
<artifactId>ko4j</artifactId>
<version>0.8-SNAPSHOT</version>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@ -0,0 +1,166 @@
/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
*
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
* Other names may be trademarks of their respective owners.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
package org.teavm.html4j.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;
import net.java.html.BrwsrCtx;
import net.java.html.js.JavaScriptBody;
import org.apidesign.html.boot.spi.Fn;
import org.apidesign.html.context.spi.Contexts;
import org.apidesign.html.json.tck.KnockoutTCK;
import org.testng.Assert;
/**
*
* @author Jaroslav Tulach <jtulach@netbeans.org>
*/
public final class KnockoutFXTest extends KnockoutTCK {
private static Class<?> browserClass;
private static Fn.Presenter browserContext;
public KnockoutFXTest() {
}
static synchronized ClassLoader getClassLoader() throws InterruptedException {
while (browserClass == null) {
KnockoutFXTest.class.wait();
}
return browserClass.getClassLoader();
}
public static synchronized void initialized(Class<?> browserCls) throws Exception {
browserClass = browserCls;
browserContext = Fn.activePresenter();
KnockoutFXTest.class.notifyAll();
}
public static void initialized() throws Exception {
Assert.assertSame(
KnockoutFXTest.class.getClassLoader(),
ClassLoader.getSystemClassLoader(),
"No special classloaders"
);
KnockoutFXTest.initialized(KnockoutFXTest.class);
browserContext = Fn.activePresenter();
}
@Override
public BrwsrCtx createContext() {
Contexts.Builder cb = Contexts.newBuilder();
return cb.build();
}
@Override
public Object createJSON(Map<String, Object> values) {
Object json = createJSON();
for (Map.Entry<String, Object> entry : values.entrySet()) {
setProperty(json, entry.getKey(), entry.getValue());
}
return json;
}
@JavaScriptBody(args = {}, body = "return new Object();")
private static native Object createJSON();
@JavaScriptBody(args = { "json", "key", "value" }, body = "json[key] = value;")
private static native void setProperty(Object json, String key, Object value);
@Override
@JavaScriptBody(args = { "s", "args" }, body = ""
+ "var f = new Function(s); "
+ "return f.apply(null, args);"
)
public native Object executeScript(String script, Object[] arguments);
@JavaScriptBody(args = { }, body =
"var h;"
+ "if (!!window && !!window.location && !!window.location.href)\n"
+ " h = window.location.href;\n"
+ "else "
+ " h = null;"
+ "return h;\n"
)
private static native String findBaseURL();
@Override
public URI prepareURL(String content, String mimeType, String[] parameters) {
try {
final URL baseURL = new URL(findBaseURL());
StringBuilder sb = new StringBuilder();
sb.append("/dynamic?mimeType=").append(mimeType);
for (int i = 0; i < parameters.length; i++) {
sb.append("&param" + i).append("=").append(parameters[i]);
}
String mangle = content.replace("\n", "%0a")
.replace("\"", "\\\"").replace(" ", "%20");
sb.append("&content=").append(mangle);
URL query = new URL(baseURL, sb.toString());
URLConnection c = query.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
URI connectTo = new URI(br.readLine());
return connectTo;
} catch (IOException ex) {
throw new IllegalStateException(ex);
} catch (URISyntaxException ex) {
throw new IllegalStateException(ex);
}
}
@Override
public boolean canFailWebSocketTest() {
try {
Class.forName("java.util.function.Function");
return false;
} catch (ClassNotFoundException ex) {
// running on JDK7, FX WebView WebSocket impl does not work
return true;
}
}
}

View File

@ -0,0 +1 @@
org.teavm.html4j.test.KnockoutFXTest