# HG changeset patch # User Lubomir Nerad # Date 1360923315 -3600 # Node ID 80833f6829e68ec9cd65b45570d324ebe6609de5 # Parent b9bf26ea01182e2b1608c3ef894e4b4d80eb46ce# Parent 25eba32a96cdc503fab7f222f79833bfc27993b4 Merge with trunk diff -r b9bf26ea0118 -r 80833f6829e6 benchmarks/matrix-multiplication/pom.xml --- a/benchmarks/matrix-multiplication/pom.xml Thu Feb 07 17:41:41 2013 +0100 +++ b/benchmarks/matrix-multiplication/pom.xml Fri Feb 15 11:15:15 2013 +0100 @@ -7,6 +7,11 @@ matrix.multiplication 0.3-SNAPSHOT jar + + benchmarks + org.apidesign.bck2brwsr + 0.3-SNAPSHOT + Matrix multiplication @@ -25,6 +30,14 @@ 1.7 + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + diff -r b9bf26ea0118 -r 80833f6829e6 emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/JFXIssuesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/JFXIssuesTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,46 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.compact.tck; + +import org.apidesign.bck2brwsr.vmtest.Compare; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + + +public class JFXIssuesTest { + private abstract class Application { + public abstract int getID(); + } + + private class MyApplication extends Application { + + @Override + public int getID() { + return 1; + } + + } + + @Compare public boolean isClassAssignable() { + return Application.class.isAssignableFrom(MyApplication.class); + } + + @Factory public static Object[] create() { + return VMTest.create(JFXIssuesTest.class); + } +} diff -r b9bf26ea0118 -r 80833f6829e6 emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ReaderTest.java --- a/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ReaderTest.java Thu Feb 07 17:41:41 2013 +0100 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ReaderTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.util.Arrays; import org.apidesign.bck2brwsr.vmtest.Compare; import org.apidesign.bck2brwsr.vmtest.VMTest; @@ -50,8 +51,8 @@ } return sb.toString().toString(); } - @Compare public String stringToBytes() { - return Arrays.toString("Žluťoučký kůň".getBytes()); + @Compare public String stringToBytes() throws UnsupportedEncodingException { + return Arrays.toString("\u017dlu\u0165ou\u010dk\u00fd k\u016f\u0148".getBytes("UTF-8")); } @Factory public static Object[] create() { diff -r b9bf26ea0118 -r 80833f6829e6 emul/mini/src/main/java/java/lang/Class.java --- a/emul/mini/src/main/java/java/lang/Class.java Thu Feb 07 17:41:41 2013 +0100 +++ b/emul/mini/src/main/java/java/lang/Class.java Fri Feb 15 11:15:15 2013 +0100 @@ -401,10 +401,15 @@ return cmpType != null && getComponentType().isAssignableFrom(cmpType); } String prop = "$instOf_" + getName().replace('.', '_'); - return hasProperty(cls, prop); + return hasCnstrProperty(cls, prop); } - + @JavaScriptBody(args = { "who", "prop" }, body = + "if (who.cnstr.prototype[prop]) return true; else return false;" + ) + private static native boolean hasCnstrProperty(Object who, String prop); + + /** * Determines if the specified {@code Class} object represents an * interface type. diff -r b9bf26ea0118 -r 80833f6829e6 emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Thu Feb 07 17:41:41 2013 +0100 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Fri Feb 15 11:15:15 2013 +0100 @@ -45,7 +45,7 @@ ) public static native byte[] expandArray(byte[] arr, int expectedSize); - @JavaScriptBody(args = {}, body = "return new Date().getMilliseconds();") + @JavaScriptBody(args = {}, body = "return new Date().getTime();") public static native long currentTimeMillis(); public static long nanoTime() { diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/pom.xml Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,198 @@ + + + 4.0.0 + + ide + org.apidesign.bck2brwsr + 0.3-SNAPSHOT + + + org.apidesign.bck2brwsr.ide.editor + editor + 0.3-SNAPSHOT + nbm + + Editor Support for Bck2Brwsr + + + UTF-8 + RELEASE72 + ${project.build.directory}/endorsed + + + + + + netbeans + NetBeans + http://bits.netbeans.org/maven2/ + + false + + + + + + + org.netbeans.api + org-netbeans-api-annotations-common + ${netbeans.version} + + + org.netbeans.api + org-netbeans-modules-java-source + ${netbeans.version} + + + org.netbeans.api + org-netbeans-libs-javacapi + ${netbeans.version} + + + org.netbeans.api + org-netbeans-spi-java-hints + ${netbeans.version} + + + org.netbeans.api + org-netbeans-modules-parsing-api + ${netbeans.version} + + + org.netbeans.api + org-netbeans-spi-editor-hints + ${netbeans.version} + + + org.netbeans.api + org-openide-util + ${netbeans.version} + + + org.netbeans.api + org-netbeans-modules-java-lexer + ${netbeans.version} + + + org.netbeans.api + org-netbeans-modules-lexer + ${netbeans.version} + + + org.apidesign.bck2brwsr + core + 0.3-SNAPSHOT + jar + test + + + org.netbeans.api + org-netbeans-modules-java-hints-test + ${netbeans.version} + test + + + org.netbeans.api + org-netbeans-libs-junit4 + ${netbeans.version} + test + + + org.netbeans.modules + org-netbeans-lib-nbjavac + ${netbeans.version} + test + + + org.testng + testng + test + + + + + + + org.codehaus.mojo + nbm-maven-plugin + 3.8 + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.6 + 1.6 + + ${endorsed.dir} + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + true + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + endorsed + validate + + copy + + + + + ${endorsed.dir} + true + + + org.netbeans.api + org-netbeans-libs-javacapi + ${netbeans.version} + + + org.netbeans.external + nb-javac-api + ${netbeans.version} + + + org.netbeans.modules + org-netbeans-libs-javacimpl + ${netbeans.version} + + + org.netbeans.external + nb-javac-impl + ${netbeans.version} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + -Djava.endorsed.dirs=${endorsed.dir} + + + + + diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JNIHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JNIHelper.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,80 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * JNI Helper. + * To facilitate lookup of methods by name and signature, instead of manually parsing signatures, + * constructs the map of all methods and uses Class.getName() to generate almost-correct signatures. + */ +class JNIHelper { + + static Method method(String clazz, String method, String signature) { + final Map methods = methodMap(JNIHelper.clazz(clazz)); + return methods.get(methodKey(method, signature)); + } + + static Class clazz(String clazz) { + try { + return Class.forName(clazz); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + + static Map methodMap(final Class clazz) { + final Map map = new HashMap(); + final Method[] methods = clazz.getDeclaredMethods(); + for (int i = 0; i < methods.length; i++) { + final Method method = methods[i]; + map.put(methodKey(method.getName(), signature(method)), method); + } + return map; + } + + static String methodKey(String method, String signature) { + return method + '@' + signature; + } + + static String signature(final Method method) { + final Class[] parameterTypes = method.getParameterTypes(); + final StringBuilder b = new StringBuilder(); + for (int j = 0; j < parameterTypes.length; j++) { + b.append(signature(parameterTypes[j])); + } + return b.toString(); + } + + static String signature(final Class clazz) { + if (clazz == boolean.class) return "Z"; + else if (clazz == byte.class) return "B"; + else if (clazz == char.class) return "C"; + else if (clazz == double.class) return "D"; + else if (clazz == float.class) return "F"; + else if (clazz == int.class) return "I"; + else if (clazz == long.class) return "J"; + else if (clazz == short.class) return "S"; + else if (clazz == void.class) return "V"; + else if (clazz.isArray()) return clazz.getName().replace('.','/'); + else return "L" + clazz.getName().replace('.','/') + ";"; + } +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JSEmbeddingProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JSEmbeddingProvider.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,188 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import com.sun.source.tree.AnnotationTree; +import com.sun.source.tree.AssignmentTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.LiteralTree; +import com.sun.source.tree.MethodTree; +import com.sun.source.util.SourcePositions; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.lang.model.element.TypeElement; +import javax.swing.text.Document; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.api.java.source.CompilationInfo; +import org.netbeans.api.java.source.JavaParserResultTask; +import org.netbeans.api.java.source.JavaSource; +import org.netbeans.api.lexer.Language; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.modules.parsing.api.Snapshot; +import org.netbeans.modules.parsing.spi.Parser; +import org.netbeans.modules.parsing.spi.Scheduler; +import org.netbeans.modules.parsing.spi.SchedulerEvent; +import org.netbeans.modules.parsing.spi.SchedulerTask; +import org.netbeans.modules.parsing.spi.TaskFactory; +import org.openide.util.Exceptions; + +/** + * + * @author Tomas Zezula + */ +public final class JSEmbeddingProvider extends JavaParserResultTask { + + private static final int PRIORITY = 1000; + private static final String JS_ANNOTATION = "org.apidesign.bck2brwsr.core.JavaScriptBody"; //NOI18N + private static final String BODY = "body"; //NOI18N + private static final String JAVA_MIME_TYPE = "text/x-java"; //NOI18N + private static final String JAVASCRIPT_MIME_TYPE = "text/javascript"; //NOI18N + private final AtomicBoolean canceled = new AtomicBoolean(); + + private JSEmbeddingProvider() { + super(JavaSource.Phase.ELEMENTS_RESOLVED); + } + + @Override + public int getPriority() { + return PRIORITY; + } + + @Override + public void cancel() { + canceled.set(true); + } + + @Override + public Class getSchedulerClass() { + return Scheduler.EDITOR_SENSITIVE_TASK_SCHEDULER; + } + + @Override + public void run(Parser.Result t, SchedulerEvent se) { + canceled.set(false); + final CompilationInfo ci = CompilationInfo.get(t); + final CompilationUnitTree cu = ci.getCompilationUnit(); + final Trees trees = ci.getTrees(); + final SourcePositions sp = trees.getSourcePositions(); + final Finder f = new Finder(trees); + final List result = new ArrayList(); + f.scan(cu, result); + if (!result.isEmpty()) { + try { + final TokenHierarchy tk = TokenHierarchy.get(ci.getDocument()); + final Language java = Language.find(JAVA_MIME_TYPE); + final Language javaScript = Language.find(JAVASCRIPT_MIME_TYPE); + if (java != null && javaScript != null) { + final TokenSequence seq = tk.tokenSequence(java); + if (seq != null) { + for (LiteralTree lt : result) { + final int start = (int) sp.getStartPosition(cu, lt); + final int end = (int) sp.getEndPosition(cu, lt); + seq.move(start); + while (seq.moveNext() && seq.offset() < end) { + seq.createEmbedding(javaScript, 1, 1, true); + } + } + } + } + } catch (IOException ioe) { + Exceptions.printStackTrace(ioe); + } + } + } + + + + + private static final class Finder extends TreePathScanner> { + + private final Trees trees; + private CompilationUnitTree cu; + private boolean inEmbedding; + + Finder(final Trees trees) { + this.trees = trees; + } + + @Override + public Void visitCompilationUnit( + final CompilationUnitTree unit, + final List p) { + this.cu = unit; + return super.visitCompilationUnit(unit, p); + } + + + + @Override + public Void visitMethod( + final MethodTree m, + final List p) { + for (AnnotationTree a : m.getModifiers().getAnnotations()) { + final TypeElement ae = (TypeElement) trees.getElement(TreePath.getPath(cu, a.getAnnotationType())); + if (ae != null && JS_ANNOTATION.contentEquals(ae.getQualifiedName())) { + final List args = a.getArguments(); + for (ExpressionTree kvp : args) { + if (kvp instanceof AssignmentTree) { + final AssignmentTree assignemt = (AssignmentTree) kvp; + if (BODY.equals(assignemt.getVariable().toString())) { + inEmbedding = true; + try { + scan(assignemt.getExpression(), p); + } finally { + inEmbedding = false; + } + } + } + } + } + } + return null; + } + + @Override + public Void visitLiteral(LiteralTree node, List p) { + if (inEmbedding) { + p.add(node); + } + return super.visitLiteral(node, p); + } + + } + + @MimeRegistration( + service = TaskFactory.class, + mimeType = JAVA_MIME_TYPE) + public static final class Factory extends TaskFactory { + @Override + public Collection create(Snapshot snpsht) { + return Collections.singleton(new JSEmbeddingProvider()); + } + } + +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JSNI2JavaScriptBody.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JSNI2JavaScriptBody.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,149 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import com.sun.source.tree.AnnotationTree; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.LiteralTree; +import com.sun.source.tree.MethodTree; +import com.sun.source.tree.Tree.Kind; +import com.sun.source.tree.VariableTree; +import com.sun.source.util.TreePath; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.netbeans.api.java.lexer.JavaTokenId; +import static org.netbeans.api.java.lexer.JavaTokenId.BLOCK_COMMENT; +import static org.netbeans.api.java.lexer.JavaTokenId.JAVADOC_COMMENT; +import static org.netbeans.api.java.lexer.JavaTokenId.LINE_COMMENT; +import static org.netbeans.api.java.lexer.JavaTokenId.WHITESPACE; +import org.netbeans.api.java.source.CompilationInfo; +import org.netbeans.api.java.source.TreeMaker; +import org.netbeans.api.lexer.Token; +import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.spi.editor.hints.ErrorDescription; +import org.netbeans.spi.editor.hints.Fix; +import org.netbeans.spi.java.hints.ErrorDescriptionFactory; +import org.netbeans.spi.java.hints.Hint; +import org.netbeans.spi.java.hints.HintContext; +import org.netbeans.spi.java.hints.JavaFix; +import org.netbeans.spi.java.hints.TriggerTreeKind; +import org.openide.util.NbBundle.Messages; + +@Hint(displayName = "#DN_JSNI2JavaScriptBody", description = "#DESC_JSNI2JavaScriptBody", category = "general") +@Messages({ + "DN_JSNI2JavaScriptBody=JSNI to @JavaScriptBody", + "DESC_JSNI2JavaScriptBody=JSNI to @JavaScriptBody" +}) +public class JSNI2JavaScriptBody { + + @TriggerTreeKind(Kind.METHOD) + @Messages("ERR_JSNI2JavaScriptBody=Can convert JSNI to @JavaScriptBody") + public static ErrorDescription computeWarning(final HintContext ctx) { + Token token = findBlockToken(ctx.getInfo(), ctx.getPath(), ctx); + + if (token == null) { + return null; + } + + Fix fix = new FixImpl(ctx.getInfo(), ctx.getPath()).toEditorFix(); + return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_JSNI2JavaScriptBody(), fix); + } + + private static Token findBlockToken(CompilationInfo info, TreePath path, HintContext ctx) { + int end = (int) info.getTrees().getSourcePositions().getEndPosition(path.getCompilationUnit(), path.getLeaf()); + TokenSequence ts = info.getTokenHierarchy().tokenSequence(JavaTokenId.language()); + + if (ts == null) return null; + + ts.move(end); + + if ((ctx != null && ctx.isCanceled()) || !ts.movePrevious() || ts.token().id() != JavaTokenId.SEMICOLON) return null; + + OUTER: while (ts.movePrevious()) { + if (ctx != null && ctx.isCanceled()) return null; + + switch (ts.token().id()) { + case WHITESPACE: break; + case LINE_COMMENT: break; + case JAVADOC_COMMENT: break; + case BLOCK_COMMENT: + final CharSequence tok = ts.token().text(); + final int l = tok.length(); + if (l > 4 + && tok.subSequence(0, 4).toString().equals("/*-{") // NOI18N + && tok.subSequence(l - 4, l).toString().equals("}-*/") // NOI18N + ) { + return ts.offsetToken(); + } + break; + default: + break OUTER; + } + } + + return null; + } + + private static final class FixImpl extends JavaFix { + + public FixImpl(CompilationInfo info, TreePath tp) { + super(info, tp); + } + + @Override + @Messages("FIX_JSNI2JavaScriptBody=Convert JSNI to @JavaScriptBody") + protected String getText() { + return Bundle.FIX_JSNI2JavaScriptBody(); + } + + @Override + protected void performRewrite(TransformationContext ctx) { + Token jsniComment = findBlockToken(ctx.getWorkingCopy(), ctx.getPath(), null); + + if (jsniComment == null) { + //XXX: warn? + return ; + } + + JsniCommentTokenizer tok = new JsniCommentTokenizer(); + ManglingSink ms = new ManglingSink(); + final CharSequence cmnt = jsniComment.text(); + tok.process(cmnt.subSequence(4, cmnt.length() - 4), ms); + + TreeMaker make = ctx.getWorkingCopy().getTreeMaker(); + MethodTree mt = (MethodTree) ctx.getPath().getLeaf(); + List params = new ArrayList(); + + for (VariableTree p : mt.getParameters()) { + params.add(make.Literal(p.getName().toString())); + } + + AnnotationTree jsBody = make.Annotation(make.QualIdent("org.apidesign.bck2brwsr.core.JavaScriptBody"), + Arrays.asList( + make.Assignment(make.Identifier("args"), make.NewArray(null, Collections.emptyList(), params)), + make.Assignment(make.Identifier("body"), make.Literal(ms.out.toString())) + ) + ); + + + ctx.getWorkingCopy().rewrite(mt.getModifiers(), make.addModifiersAnnotation(mt.getModifiers(), jsBody)); + } + } +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizer.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,70 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +final class JsniCommentTokenizer { + + /** + * Tokenize the contents of JSNI comment into the provided {@linkplain Sink}. + * @param in the contents of JSNI comment + * @param out the sink that consumes parsed tokens + */ + public void process(final CharSequence in, final Sink out) { + final Matcher member = Pattern.compile("@([^:]+)::([a-zA-Z_$][a-zA-Z\\d_$]*)").matcher(in); + final Matcher signature = Pattern.compile("\\(([^\\)]*)\\)").matcher(in); + + int i = 0; + while (true) { + if (member.find(i)) { + final int memberStart = member.start(); + final int memberEnd = member.end(); + if (memberStart > i) out.javascript(in.subSequence(i, memberStart).toString()); + + final String clazz = member.group(1); + final String name = member.group(2); + + if (in.charAt(memberEnd) == '(') { + if (!signature.find(memberEnd)) { + throw new IllegalStateException("Expected method signature"); + } + assert signature.start() == memberEnd; + out.method(clazz, name, signature.group(1)); + i = signature.end(); + } else { + out.field(clazz, name); + i = memberEnd; + } + } else { + out.javascript(in.subSequence(i, in.length()).toString()); + break; + } + } + } + + + static interface Sink { + void javascript(String s); + + void method(String clazz, String method, String signature); + + void field(String clazz, String field); + } +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/ManglingSink.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/ManglingSink.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,71 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +/** + * An implementation of {@linkplain JsniCommentTokenizer.Sink} that generates B2B + */ +class ManglingSink implements JsniCommentTokenizer.Sink { + + final StringBuilder out = new StringBuilder(); + + public void javascript(String s) { + out.append(s); + } + + public void method(String clazz, String method, String signature) { + out.append(mangle(clazz, method, signature)); + } + + public void field(String clazz, String field) { +// out.append(field); + out.append('_').append(field).append('(').append(')'); + } + + + @Override + public String toString() { + return out.toString(); + } + + + static String mangle(String clazz, String method, String signature) { + final StringBuilder builder = new StringBuilder(); + builder.append(method); + builder.append("__"); + builder.append(mangle(JNIHelper.signature(JNIHelper.method(clazz, method, signature).getReturnType()))); + builder.append(mangle(signature)); + return builder.toString(); + } + + + static String mangle(String txt) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < txt.length(); i++) { + final char ch = txt.charAt(i); + switch (ch) { + case '/': sb.append('_'); break; + case '_': sb.append("_1"); break; + case ';': sb.append("_2"); break; + case '[': sb.append("_3"); break; + default: sb.append(ch); break; + } + } + return sb.toString(); + } +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/main/nbm/manifest.mf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/main/nbm/manifest.mf Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jackpot30/test/hints/Bundle.properties diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/main/resources/org/netbeans/modules/jackpot30/test/hints/Bundle.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/main/resources/org/netbeans/modules/jackpot30/test/hints/Bundle.properties Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,21 @@ +# +# Back 2 Browser Bytecode Translator +# Copyright (C) 2012 Jaroslav Tulach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. Look for COPYING file in the top folder. +# If not, see http://opensource.org/licenses/GPL-2.0. +# + +OpenIDE-Module-Name=Bck2Brwsr Editor Support +OpenIDE-Module-Short-Description=Provides hints, coloring, etc. for the bck2brwsr.apidesign.org project +OpenIDE-Module-Display-Category=Java diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/DejsniReaderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/DejsniReaderTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,84 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import org.apidesign.bck2brwsr.core.JavaScriptBody; +import org.netbeans.modules.java.hints.test.api.HintTest; +import org.openide.filesystems.FileUtil; +import org.testng.annotations.Test; + +public class DejsniReaderTest { + + @Test + public void test1() throws Exception { + String s = "class Test {\n" + + " /** javadoc */\n" + + " public native void test() /*-{\n" + + " // body\n" + + " }-*/;\n" + + "}\n"; + + String expected = " import org.apidesign.bck2brwsr.core.JavaScriptBody;\n" + + "class Test {\n" + + "\n" + + " /** javadoc */\n" + + " @JavaScriptBody(args = {}, body = \"\\n // body\\n \")\n" + + " public native void test();\n" + + "}\n"; + + HintTest.create() + .input(s) + .classpath(FileUtil.getArchiveRoot(JavaScriptBody.class.getProtectionDomain().getCodeSource().getLocation())) + .run(JSNI2JavaScriptBody.class) + .findWarning("2:23-2:27:verifier:" + Bundle.ERR_JSNI2JavaScriptBody()) + .applyFix() + .assertCompilable() + .assertOutput(expected); + } + + + @Test + public void test2() throws Exception { + String s = "class Test {\n" + + " /** javadoc */\n" + + " @SuppressWarnings(\"unused\")\n" + + " // comment\n" + + " public native void test() /*-{\n" + + " // body\n" + + " }-*/;\n" + + "}\n"; + + String expected = " import org.apidesign.bck2brwsr.core.JavaScriptBody;\n" + + "class Test {\n" + + "\n" + + " /** javadoc */\n" + + " @SuppressWarnings(\"unused\")\n" + + " // comment\n" + + " @JavaScriptBody(args = {}, body = \"\\n // body\\n \")\n" + + " public native void test();\n" + + "}\n"; + HintTest.create() + .input(s) + .classpath(FileUtil.getArchiveRoot(JavaScriptBody.class.getProtectionDomain().getCodeSource().getLocation())) + .run(JSNI2JavaScriptBody.class) + .findWarning("4:23-4:27:verifier:" + Bundle.ERR_JSNI2JavaScriptBody()) + .applyFix() + .assertCompilable() + .assertOutput(expected); + } +} \ No newline at end of file diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JSNI2JavaScriptBodyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JSNI2JavaScriptBodyTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,46 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import org.apidesign.bck2brwsr.core.JavaScriptBody; +import org.netbeans.modules.java.hints.test.api.HintTest; +import org.openide.filesystems.FileUtil; +import org.testng.annotations.Test; + +public class JSNI2JavaScriptBodyTest { + + @Test + public void testFixWorking() throws Exception { + HintTest.create() + .input("package test;\n" + + "public class Test {\n" + + " public native void run(int a) /*-{ this.a = a; }-*/;\n" + + "}\n") + .classpath(FileUtil.getArchiveRoot(JavaScriptBody.class.getProtectionDomain().getCodeSource().getLocation())) + .run(JSNI2JavaScriptBody.class) + .findWarning("2:23-2:26:verifier:" + Bundle.ERR_JSNI2JavaScriptBody()) + .applyFix() + .assertCompilable() + .assertOutput("package test;\n" + + "import org.apidesign.bck2brwsr.core.JavaScriptBody;\n" + + "public class Test {\n" + + " @JavaScriptBody(args = {\"a\"}, body = \" this.a = a; \")\n" + + " public native void run(int a);\n" + + "}\n"); + } +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizerTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,154 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class JsniCommentTokenizerTest { + + private static class MockSink implements JsniCommentTokenizer.Sink { + final List out = new ArrayList(); + + public void javascript(String s) { + out.add("J " + s); + } + + public void method(String clazz, String method, String signature) { + out.add("M " + clazz + "|" + method + "|" + signature); + } + + public void field(String clazz, String field) { + out.add("F " + clazz + "|" + field); + } + } + + + @Test + public void testProcess_nop() throws IOException { + final String in = "foo bar"; + final List expected = new ArrayList(); + expected.add("J foo bar"); + + final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer(); + final MockSink out = new MockSink(); + jsniCommentTokenizer.process(in, out); + + Assert.assertEquals(expected, out.out); + } + + @Test + public void testProcess_read_static_field() throws IOException { + final String in = " @com.google.gwt.examples.JSNIExample::myStaticField = val + \" and stuff\";"; + final List expected = new ArrayList(); + expected.add("J "); + expected.add("F com.google.gwt.examples.JSNIExample|myStaticField"); + expected.add("J = val + \" and stuff\";"); + + final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer(); + final MockSink out = new MockSink(); + jsniCommentTokenizer.process(in, out); + + Assert.assertEquals(expected, out.out); + } + + @Test + public void testProcess_write_instance_field() throws IOException { + final String in = " x.@com.google.gwt.examples.JSNIExample::myInstanceField = val + \" and stuff\";"; + final List expected = new ArrayList(); + expected.add("J x."); + expected.add("F com.google.gwt.examples.JSNIExample|myInstanceField"); + expected.add("J = val + \" and stuff\";"); + + final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer(); + final MockSink out = new MockSink(); + jsniCommentTokenizer.process(in, out); + + Assert.assertEquals(expected, out.out); + } + + @Test + public void testProcess_read_instance_field() throws IOException { + final String in = " var val = this.@com.google.gwt.examples.JSNIExample::myInstanceField;"; + final List expected = new ArrayList(); + expected.add("J var val = this."); + expected.add("F com.google.gwt.examples.JSNIExample|myInstanceField"); + expected.add("J ;"); + + final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer(); + final MockSink out = new MockSink(); + jsniCommentTokenizer.process(in, out); + + Assert.assertEquals(expected, out.out); + } + + + @Test + public void testProcess_static_method() throws IOException { + final String in = " @com.google.gwt.examples.JSNIExample::staticFoo(Ljava/lang/String;)(s);"; + final List expected = new ArrayList(); + expected.add("J "); + expected.add("M com.google.gwt.examples.JSNIExample|staticFoo|Ljava/lang/String;"); + expected.add("J (s);"); + + final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer(); + final MockSink out = new MockSink(); + jsniCommentTokenizer.process(in, out); + + Assert.assertEquals(expected, out.out); + } + + + @Test + public void testProcess_instance_method() throws IOException { + final String in = " x.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s);"; + final List expected = new ArrayList(); + expected.add("J x."); + expected.add("M com.google.gwt.examples.JSNIExample|instanceFoo|Ljava/lang/String;"); + expected.add("J (s);"); + + final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer(); + final MockSink out = new MockSink(); + jsniCommentTokenizer.process(in, out); + + Assert.assertEquals(expected, out.out); + } + + + @Test + public void testProcess_multiline() throws IOException { + final String in = + " x.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s);" + + " @com.google.gwt.examples.JSNIExample::myStaticField = val + \" and stuff\";"; + final List expected = new ArrayList(); + expected.add("J x."); + expected.add("M com.google.gwt.examples.JSNIExample|instanceFoo|Ljava/lang/String;"); + expected.add("J (s); "); + expected.add("F com.google.gwt.examples.JSNIExample|myStaticField"); + expected.add("J = val + \" and stuff\";"); + + final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer(); + final MockSink out = new MockSink(); + jsniCommentTokenizer.process(in, out); + + Assert.assertEquals(expected, out.out); + } +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/ManglingSinkTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/ManglingSinkTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,58 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.ide.editor; + +import org.testng.Assert; +import org.testng.annotations.Test; + + +public class ManglingSinkTest { + + @Test + public void testMangle_1() { + Assert.assertEquals( + "binarySearch__I_3BIIB", + ManglingSink.mangle("java.util.Arrays", "binarySearch", "[BIIB") + ); + } + + @Test + public void testMangle_2() { + Assert.assertEquals( + "sort__V_3I", + ManglingSink.mangle("java.util.Arrays", "sort", "[I") + ); + } + + @Test + public void testMangle_3() { + Assert.assertEquals( + "binarySearch__I_3Ljava_lang_Object_2IILjava_lang_Object_2", + ManglingSink.mangle("java.util.Arrays", "binarySearch", "[Ljava/lang/Object;IILjava/lang/Object;") + ); + } + + + @Test + public void testField() { + final ManglingSink manglingSink = new ManglingSink(); + manglingSink.field(null, "value"); + + Assert.assertEquals("_value()", manglingSink.toString()); + } +} diff -r b9bf26ea0118 -r 80833f6829e6 ide/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ide/pom.xml Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,17 @@ + + + 4.0.0 + + bck2brwsr + org.apidesign + 0.3-SNAPSHOT + + org.apidesign.bck2brwsr + ide + 0.3-SNAPSHOT + pom + IDE Support + + editor + + diff -r b9bf26ea0118 -r 80833f6829e6 javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/GraphicsContext.java --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/GraphicsContext.java Thu Feb 07 17:41:41 2013 +0100 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/GraphicsContext.java Fri Feb 15 11:15:15 2013 +0100 @@ -307,10 +307,10 @@ public native double getGlobalAlpha(); @JavaScriptBody(args = {"operation"}, body = "this._context().globalCompositeOperation=operation;") - public native void setGlobalCompositeOperation(double alpha); + public native void setGlobalCompositeOperation(String operation); @JavaScriptBody(args = {}, body = "return this._context().globalCompositeOperation;") - public native double getGlobalCompositeOperation(); + public native String getGlobalCompositeOperation(); public LinearGradient createLinearGradient(double x0, double y0, double x1, double y1) { return new LinearGradient(createLinearGradientImpl(context, x0, y0, x1, y1)); diff -r b9bf26ea0118 -r 80833f6829e6 javaquery/demo-calculator-dynamic/pom.xml --- a/javaquery/demo-calculator-dynamic/pom.xml Thu Feb 07 17:41:41 2013 +0100 +++ b/javaquery/demo-calculator-dynamic/pom.xml Fri Feb 15 11:15:15 2013 +0100 @@ -40,6 +40,14 @@ 1.7 + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + diff -r b9bf26ea0118 -r 80833f6829e6 javaquery/demo-calculator/pom.xml --- a/javaquery/demo-calculator/pom.xml Thu Feb 07 17:41:41 2013 +0100 +++ b/javaquery/demo-calculator/pom.xml Fri Feb 15 11:15:15 2013 +0100 @@ -60,6 +60,14 @@ + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + diff -r b9bf26ea0118 -r 80833f6829e6 launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Thu Feb 07 17:41:41 2013 +0100 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Fri Feb 15 11:15:15 2013 +0100 @@ -285,10 +285,10 @@ if (ch == '$' && params.length > 0) { int cnt = is.read() - '0'; if (cnt == 'U' - '0') { - os.write(baseURL.getBytes()); + os.write(baseURL.getBytes("UTF-8")); } if (cnt >= 0 && cnt < params.length) { - os.write(params[cnt].getBytes()); + os.write(params[cnt].getBytes("UTF-8")); } } else { os.write(ch); diff -r b9bf26ea0118 -r 80833f6829e6 mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java --- a/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java Thu Feb 07 17:41:41 2013 +0100 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java Fri Feb 15 11:15:15 2013 +0100 @@ -37,7 +37,7 @@ import org.apidesign.bck2brwsr.launcher.Launcher; /** Executes given HTML page in a browser. */ -@Mojo(name="brwsr", defaultPhase=LifecyclePhase.DEPLOY) +@Mojo(name="brwsr", defaultPhase=LifecyclePhase.NONE) public class BrswrMojo extends AbstractMojo { public BrswrMojo() { } diff -r b9bf26ea0118 -r 80833f6829e6 mojo/src/main/resources/archetype-resources/pom.xml --- a/mojo/src/main/resources/archetype-resources/pom.xml Thu Feb 07 17:41:41 2013 +0100 +++ b/mojo/src/main/resources/archetype-resources/pom.xml Fri Feb 15 11:15:15 2013 +0100 @@ -10,6 +10,32 @@ ${artifactId} + + + java.net + Java.net + https://maven.java.net/content/repositories/snapshots/ + + true + + + + netbeans + NetBeans + http://bits.netbeans.org/maven2/ + + + + + java.net + Local Maven repository of releases + https://maven.java.net/content/repositories/snapshots/ + + true + + + + UTF-8 diff -r b9bf26ea0118 -r 80833f6829e6 pom.xml --- a/pom.xml Thu Feb 07 17:41:41 2013 +0100 +++ b/pom.xml Fri Feb 15 11:15:15 2013 +0100 @@ -6,6 +6,11 @@ 0.3-SNAPSHOT pom Back 2 Browser + + net.java + jvnet-parent + 3 + vm emul @@ -17,6 +22,7 @@ benchmarks launcher vmtest + ide @@ -29,6 +35,11 @@ API Design http://apidesign.org + + scm:hg:http://source.apidesign.org/hg/bck2brwsr + scm:hg:https://source.apidesign.org/hg/bck2brwsr + http://source.apidesign.org/hg/bck2brwsr + netbeans diff -r b9bf26ea0118 -r 80833f6829e6 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Feb 07 17:41:41 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Feb 15 11:15:15 2013 +0100 @@ -632,7 +632,7 @@ final int varIndx = wide ? readUShort(byteCodes, i++) : readUByte(byteCodes, i); ++i; - final int incrBy = wide ? readIntArg(byteCodes, i++) + final int incrBy = wide ? readShort(byteCodes, i++) : byteCodes[i]; wide = false; if (incrBy == 1) { @@ -1353,20 +1353,25 @@ final int indxLo = byteCodes[offsetInstruction + 2]; return (indxHi & 0xffffff00) | (indxLo & 0xff); } - private int readInt4(byte[] byteCodes, int offsetInstruction) { - final int d = byteCodes[offsetInstruction + 0] << 24; - final int c = byteCodes[offsetInstruction + 1] << 16; - final int b = byteCodes[offsetInstruction + 2] << 8; - final int a = byteCodes[offsetInstruction + 3]; + private int readInt4(byte[] byteCodes, int offset) { + final int d = byteCodes[offset + 0] << 24; + final int c = byteCodes[offset + 1] << 16; + final int b = byteCodes[offset + 2] << 8; + final int a = byteCodes[offset + 3]; return (d & 0xff000000) | (c & 0xff0000) | (b & 0xff00) | (a & 0xff); } - private int readUByte(byte[] byteCodes, int offsetInstruction) { - return byteCodes[offsetInstruction] & 0xff; + private int readUByte(byte[] byteCodes, int offset) { + return byteCodes[offset] & 0xff; } - private int readUShort(byte[] byteCodes, int offsetInstruction) { - return ((byteCodes[offsetInstruction] & 0xff) << 8) - | (byteCodes[offsetInstruction + 1] & 0xff); + private int readUShort(byte[] byteCodes, int offset) { + return ((byteCodes[offset] & 0xff) << 8) + | (byteCodes[offset + 1] & 0xff); + } + + private int readShort(byte[] byteCodes, int offset) { + return (byteCodes[offset] << 8) + | (byteCodes[offset + 1] & 0xff); } private static void countArgs(String descriptor, char[] returnType, StringBuilder sig, StringBuilder cnt) { diff -r b9bf26ea0118 -r 80833f6829e6 vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Thu Feb 07 17:41:41 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -181,5 +181,11 @@ ) throws Exception { StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args); } + @Test public void isClassAssignable() throws Exception { + assertExec("isAssignable works on subclasses", Classes.class, + "isClassAssignable__Z", + true + ); + } } diff -r b9bf26ea0118 -r 80833f6829e6 vm/src/test/java/org/apidesign/vm4brwsr/Classes.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Thu Feb 07 17:41:41 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Fri Feb 15 11:15:15 2013 +0100 @@ -151,4 +151,20 @@ Method m = StaticMethod.class.getMethod("sum", int.class, int.class); return (int) m.invoke(null, a, b); } + + private abstract class Application { + public abstract int getID(); + } + + private class MyApplication extends Application { + @Override + public int getID() { + return 1; + } + } + + public static boolean isClassAssignable() { + return Application.class.isAssignableFrom(MyApplication.class); + } + } diff -r b9bf26ea0118 -r 80833f6829e6 vm/src/test/java/org/apidesign/vm4brwsr/StringSample.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/StringSample.java Thu Feb 07 17:41:41 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StringSample.java Fri Feb 15 11:15:15 2013 +0100 @@ -17,6 +17,8 @@ */ package org.apidesign.vm4brwsr; +import java.io.UnsupportedEncodingException; + /** * * @author Jaroslav Tulach @@ -68,8 +70,8 @@ return chars('a', (char)30, 'b') instanceof String; } - public static String getBytes(String s) { - byte[] arr = s.getBytes(); + public static String getBytes(String s) throws UnsupportedEncodingException { + byte[] arr = s.getBytes("UTF-8"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < arr.length; i++) { sb.append(arr[i]).append(" "); diff -r b9bf26ea0118 -r 80833f6829e6 vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java Thu Feb 07 17:41:41 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -76,7 +76,7 @@ } @Test public void getBytes() throws Exception { - final String horse = "Žluťoučký kůň"; + final String horse = "\u017dlu\u0165ou\u010dk\u00fd k\u016f\u0148"; final String expected = StringSample.getBytes(horse); assertExec( "Bytes look simplar", diff -r b9bf26ea0118 -r 80833f6829e6 vm/src/test/java/org/apidesign/vm4brwsr/SystemTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/SystemTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -0,0 +1,59 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.vm4brwsr; + +import javax.script.Invocable; +import org.testng.annotations.BeforeClass; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class SystemTest { + @Test public void verifyJSTime() throws Exception { + long now = System.currentTimeMillis(); + + Object js = TestUtils.execCode(code, codeSeq, "Get js time", + org.apidesign.bck2brwsr.emul.lang.System.class, "currentTimeMillis__J", + null + ); + + assertTrue(js instanceof Double, "Double " + js); + long time = ((Double)js).longValue(); + + long later = System.currentTimeMillis(); + + assertTrue(now <= time, "Lower bound is OK: " + now + " <= " + time); + assertTrue(time <= later, "Upper bound is OK: " + time + " <= " + later); + } + + private static CharSequence codeSeq; + private static Invocable code; + + @BeforeClass + public void compileTheCode() throws Exception { + StringBuilder sb = new StringBuilder(); + code = StaticMethodTest.compileClass(sb, "org/apidesign/bck2brwsr/emul/lang/System"); + codeSeq = sb; + } + +} + diff -r b9bf26ea0118 -r 80833f6829e6 vm/src/test/java/org/apidesign/vm4brwsr/TestUtils.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/TestUtils.java Thu Feb 07 17:41:41 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/TestUtils.java Fri Feb 15 11:15:15 2013 +0100 @@ -40,7 +40,7 @@ if (ret == null && expRes == null) { return null; } - if (expRes.equals(ret)) { + if (expRes != null && expRes.equals(ret)) { return null; } if (expRes instanceof Number) { diff -r b9bf26ea0118 -r 80833f6829e6 vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Thu Feb 07 17:41:41 2013 +0100 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Fri Feb 15 11:15:15 2013 +0100 @@ -134,7 +134,7 @@ @Compare public int stringToBytesLenght() throws UnsupportedEncodingException { - return "Žluťoučký kůň".getBytes("utf8").length; + return "\u017dlu\u0165ou\u010dk\u00fd k\u016f\u0148".getBytes("utf8").length; } @Factory