Igor's dejsni files and tests. Modified to compile. ide
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 13 Feb 2013 12:08:00 +0100
branchide
changeset 71758ce0cd13d26
parent 716 8d7f8719d29c
child 718 b93760cedf02
Igor's dejsni files and tests. Modified to compile.
ide/editor/pom.xml
ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JNIHelper.java
ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizer.java
ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/ManglingSink.java
ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/DejsniReaderTest.java
ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JSNI2JavaScriptBodyTest.java
ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizerTest.java
ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/ManglingSinkTest.java
     1.1 --- a/ide/editor/pom.xml	Wed Feb 13 11:12:55 2013 +0100
     1.2 +++ b/ide/editor/pom.xml	Wed Feb 13 12:08:00 2013 +0100
     1.3 @@ -102,6 +102,11 @@
     1.4              <version>${netbeans.version}</version>
     1.5              <scope>test</scope>
     1.6          </dependency>
     1.7 +        <dependency>
     1.8 +            <groupId>org.testng</groupId>
     1.9 +            <artifactId>testng</artifactId>
    1.10 +            <scope>test</scope>
    1.11 +        </dependency>
    1.12      </dependencies>
    1.13  
    1.14      <build>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JNIHelper.java	Wed Feb 13 12:08:00 2013 +0100
     2.3 @@ -0,0 +1,80 @@
     2.4 +/**
     2.5 + * Back 2 Browser Bytecode Translator
     2.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     2.7 + *
     2.8 + * This program is free software: you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License as published by
    2.10 + * the Free Software Foundation, version 2 of the License.
    2.11 + *
    2.12 + * This program is distributed in the hope that it will be useful,
    2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.15 + * GNU General Public License for more details.
    2.16 + *
    2.17 + * You should have received a copy of the GNU General Public License
    2.18 + * along with this program. Look for COPYING file in the top folder.
    2.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    2.20 + */
    2.21 +package org.apidesign.bck2brwsr.ide.editor;
    2.22 +
    2.23 +import java.lang.reflect.Method;
    2.24 +import java.util.HashMap;
    2.25 +import java.util.Map;
    2.26 +
    2.27 +/**
    2.28 + * JNI Helper.
    2.29 + * To facilitate lookup of methods by name and signature, instead of manually parsing signatures,
    2.30 + * constructs the map of all methods and uses Class.getName() to generate almost-correct signatures.
    2.31 + */
    2.32 +public class JNIHelper {
    2.33 +
    2.34 +    static Method method(String clazz, String method, String signature) {
    2.35 +        final Map<String, Method> methods = methodMap(JNIHelper.clazz(clazz));
    2.36 +        return methods.get(methodKey(method, signature));
    2.37 +    }
    2.38 +
    2.39 +    static Class<?> clazz(String clazz) {
    2.40 +        try {
    2.41 +            return Class.forName(clazz);
    2.42 +        } catch (ClassNotFoundException e) {
    2.43 +            throw new IllegalArgumentException(e);
    2.44 +        }
    2.45 +    }
    2.46 +
    2.47 +    static Map<String, Method> methodMap(final Class<?> clazz) {
    2.48 +        final Map<String, Method> map = new HashMap<String, Method>();
    2.49 +        final Method[] methods = clazz.getDeclaredMethods();
    2.50 +        for (int i = 0; i < methods.length; i++) {
    2.51 +            final Method method = methods[i];
    2.52 +            map.put(methodKey(method.getName(), signature(method)), method);
    2.53 +        }
    2.54 +        return map;
    2.55 +    }
    2.56 +
    2.57 +    static String methodKey(String method, String signature) {
    2.58 +        return method + '@' + signature;
    2.59 +    }
    2.60 +
    2.61 +    static String signature(final Method method) {
    2.62 +        final Class<?>[] parameterTypes = method.getParameterTypes();
    2.63 +        final StringBuilder b = new StringBuilder();
    2.64 +        for (int j = 0; j < parameterTypes.length; j++) {
    2.65 +            b.append(signature(parameterTypes[j]));
    2.66 +        }
    2.67 +        return b.toString();
    2.68 +    }
    2.69 +
    2.70 +    static String signature(final Class<?> clazz) {
    2.71 +        if (clazz == boolean.class) return "Z";
    2.72 +        else if (clazz == byte.class) return "B";
    2.73 +        else if (clazz == char.class) return "C";
    2.74 +        else if (clazz == double.class) return "D";
    2.75 +        else if (clazz == float.class) return "F";
    2.76 +        else if (clazz == int.class) return "I";
    2.77 +        else if (clazz == long.class) return "J";
    2.78 +        else if (clazz == short.class) return "S";
    2.79 +        else if (clazz == void.class) return "V";
    2.80 +        else if (clazz.isArray()) return clazz.getName().replace('.','/');
    2.81 +        else return "L" + clazz.getName().replace('.','/') + ";";
    2.82 +    }
    2.83 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizer.java	Wed Feb 13 12:08:00 2013 +0100
     3.3 @@ -0,0 +1,70 @@
     3.4 +/**
     3.5 + * Back 2 Browser Bytecode Translator
     3.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     3.7 + *
     3.8 + * This program is free software: you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU General Public License as published by
    3.10 + * the Free Software Foundation, version 2 of the License.
    3.11 + *
    3.12 + * This program is distributed in the hope that it will be useful,
    3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.15 + * GNU General Public License for more details.
    3.16 + *
    3.17 + * You should have received a copy of the GNU General Public License
    3.18 + * along with this program. Look for COPYING file in the top folder.
    3.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    3.20 + */
    3.21 +package org.apidesign.bck2brwsr.ide.editor;
    3.22 +
    3.23 +import java.util.regex.Matcher;
    3.24 +import java.util.regex.Pattern;
    3.25 +
    3.26 +public class JsniCommentTokenizer {
    3.27 +
    3.28 +    /**
    3.29 +     * Tokenize the contents of JSNI comment into the provided {@linkplain Sink}.
    3.30 +     * @param in the contents of JSNI comment
    3.31 +     * @param out the sink that consumes parsed tokens
    3.32 +     */
    3.33 +    public void process(final String in, final Sink out) {
    3.34 +        final Matcher member = Pattern.compile("@([^:]+)::([a-zA-Z_$][a-zA-Z\\d_$]*)").matcher(in);
    3.35 +        final Matcher signature = Pattern.compile("\\(([^\\)]*)\\)").matcher(in);
    3.36 +
    3.37 +        int i = 0;
    3.38 +        while (true) {
    3.39 +            if (member.find(i)) {
    3.40 +                final int memberStart = member.start();
    3.41 +                final int memberEnd = member.end();
    3.42 +                if (memberStart > i) out.javascript(in.substring(i, memberStart));
    3.43 +
    3.44 +                final String clazz = member.group(1);
    3.45 +                final String name = member.group(2);
    3.46 +
    3.47 +                if (in.charAt(memberEnd) == '(') {
    3.48 +                    if (!signature.find(memberEnd)) {
    3.49 +                        throw new IllegalStateException("Expected method signature");
    3.50 +                    }
    3.51 +                    assert signature.start() == memberEnd;
    3.52 +                    out.method(clazz, name, signature.group(1));
    3.53 +                    i = signature.end();
    3.54 +                } else {
    3.55 +                    out.field(clazz, name);
    3.56 +                    i = memberEnd;
    3.57 +                }
    3.58 +            } else {
    3.59 +                out.javascript(in.substring(i, in.length()));
    3.60 +                break;
    3.61 +            }
    3.62 +        }
    3.63 +    }
    3.64 +
    3.65 +
    3.66 +    public static interface Sink {
    3.67 +        void javascript(String s);
    3.68 +
    3.69 +        void method(String clazz, String method, String signature);
    3.70 +
    3.71 +        void field(String clazz, String field);
    3.72 +    }
    3.73 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/ide/editor/src/main/java/org/apidesign/bck2brwsr/ide/editor/ManglingSink.java	Wed Feb 13 12:08:00 2013 +0100
     4.3 @@ -0,0 +1,71 @@
     4.4 +/**
     4.5 + * Back 2 Browser Bytecode Translator
     4.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4.7 + *
     4.8 + * This program is free software: you can redistribute it and/or modify
     4.9 + * it under the terms of the GNU General Public License as published by
    4.10 + * the Free Software Foundation, version 2 of the License.
    4.11 + *
    4.12 + * This program is distributed in the hope that it will be useful,
    4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.15 + * GNU General Public License for more details.
    4.16 + *
    4.17 + * You should have received a copy of the GNU General Public License
    4.18 + * along with this program. Look for COPYING file in the top folder.
    4.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    4.20 + */
    4.21 +package org.apidesign.bck2brwsr.ide.editor;
    4.22 +
    4.23 +/**
    4.24 + * An implementation of {@linkplain JsniCommentTokenizer.Sink} that generates B2B
    4.25 + */
    4.26 +class ManglingSink implements JsniCommentTokenizer.Sink {
    4.27 +
    4.28 +    final StringBuilder out = new StringBuilder();
    4.29 +
    4.30 +    public void javascript(String s) {
    4.31 +        out.append(s);
    4.32 +    }
    4.33 +
    4.34 +    public void method(String clazz, String method, String signature) {
    4.35 +        out.append(mangle(clazz, method, signature));
    4.36 +    }
    4.37 +
    4.38 +    public void field(String clazz, String field) {
    4.39 +//        out.append(field);
    4.40 +        out.append('_').append(field).append('(').append(')');
    4.41 +    }
    4.42 +
    4.43 +
    4.44 +    @Override
    4.45 +    public String toString() {
    4.46 +        return out.toString();
    4.47 +    }
    4.48 +
    4.49 +
    4.50 +    static String mangle(String clazz, String method, String signature) {
    4.51 +        final StringBuilder builder = new StringBuilder();
    4.52 +        builder.append(method);
    4.53 +        builder.append("__");
    4.54 +        builder.append(mangle(JNIHelper.signature(JNIHelper.method(clazz, method, signature).getReturnType())));
    4.55 +        builder.append(mangle(signature));
    4.56 +        return builder.toString();
    4.57 +    }
    4.58 +
    4.59 +
    4.60 +    static String mangle(String txt) {
    4.61 +        final StringBuilder sb = new StringBuilder();
    4.62 +        for (int i = 0; i < txt.length(); i++) {
    4.63 +            final char ch = txt.charAt(i);
    4.64 +            switch (ch) {
    4.65 +                case '/': sb.append('_'); break;
    4.66 +                case '_': sb.append("_1"); break;
    4.67 +                case ';': sb.append("_2"); break;
    4.68 +                case '[': sb.append("_3"); break;
    4.69 +                default: sb.append(ch); break;
    4.70 +            }
    4.71 +        }
    4.72 +        return sb.toString();
    4.73 +    }
    4.74 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/DejsniReaderTest.java	Wed Feb 13 12:08:00 2013 +0100
     5.3 @@ -0,0 +1,81 @@
     5.4 +/**
     5.5 + * Back 2 Browser Bytecode Translator
     5.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     5.7 + *
     5.8 + * This program is free software: you can redistribute it and/or modify
     5.9 + * it under the terms of the GNU General Public License as published by
    5.10 + * the Free Software Foundation, version 2 of the License.
    5.11 + *
    5.12 + * This program is distributed in the hope that it will be useful,
    5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.15 + * GNU General Public License for more details.
    5.16 + *
    5.17 + * You should have received a copy of the GNU General Public License
    5.18 + * along with this program. Look for COPYING file in the top folder.
    5.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    5.20 + */
    5.21 +package org.apidesign.bck2brwsr.ide.editor;
    5.22 +
    5.23 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    5.24 +import org.netbeans.modules.java.hints.test.api.HintTest;
    5.25 +import org.openide.filesystems.FileUtil;
    5.26 +import org.testng.annotations.Test;
    5.27 +
    5.28 +public class DejsniReaderTest {
    5.29 +
    5.30 +    @Test
    5.31 +    public void test1() throws Exception {
    5.32 +        String s = "class Test {\n" +
    5.33 +                "    /** javadoc */\n" +
    5.34 +                "    public native void test() /*-{\n" +
    5.35 +                "        // body\n" +
    5.36 +                "    }-*/;\n" +
    5.37 +                "}\n";
    5.38 +
    5.39 +        String expected = "class Test {\n" +
    5.40 +                "\n" +
    5.41 +                "    /** javadoc */\n" +
    5.42 +                "    @org.apidesign.bck2brwsr.core.JavaScriptBody(args = {  }, body = \"\\n        // body\\n  \")\n" +
    5.43 +                "    public native void test();\n" +
    5.44 +                "}\n";
    5.45 +        
    5.46 +          HintTest.create()
    5.47 +                .input(s)
    5.48 +                .classpath(FileUtil.getArchiveRoot(JavaScriptBody.class.getProtectionDomain().getCodeSource().getLocation()))
    5.49 +                .run(JSNI2JavaScriptBody.class)
    5.50 +                .findWarning("2:23-2:26:verifier:" + Bundle.ERR_JSNI2JavaScriptBody())
    5.51 +                .applyFix()
    5.52 +                .assertCompilable()
    5.53 +                .assertOutput(expected);
    5.54 +    }
    5.55 +
    5.56 +
    5.57 +    @Test
    5.58 +    public void test2() throws Exception {
    5.59 +        String s = "class Test {\n" +
    5.60 +                "    /** javadoc */\n" +
    5.61 +                "    @SuppressWarnings(\"unused\")\n" +
    5.62 +                "    // comment\n" +
    5.63 +                "    public native void test() /*-{\n" +
    5.64 +                "        // body\n" +
    5.65 +                "    }-*/;\n" +
    5.66 +                "}\n";
    5.67 +
    5.68 +        String expected = "class Test {\n" +
    5.69 +                "\n" +
    5.70 +                "    /** javadoc */\n" +
    5.71 +                "    @SuppressWarnings(\"unused\")\n" +
    5.72 +                "    @org.apidesign.bck2brwsr.core.JavaScriptBody(args = {  }, body = \"\\n        // body\\n  \")\n" +
    5.73 +                "    public native void test();\n" +
    5.74 +                "}\n";
    5.75 +          HintTest.create()
    5.76 +                .input(s)
    5.77 +                .classpath(FileUtil.getArchiveRoot(JavaScriptBody.class.getProtectionDomain().getCodeSource().getLocation()))
    5.78 +                .run(JSNI2JavaScriptBody.class)
    5.79 +                .findWarning("2:23-2:26:verifier:" + Bundle.ERR_JSNI2JavaScriptBody())
    5.80 +                .applyFix()
    5.81 +                .assertCompilable()
    5.82 +                .assertOutput(expected);
    5.83 +    }
    5.84 +}
    5.85 \ No newline at end of file
     6.1 --- a/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JSNI2JavaScriptBodyTest.java	Wed Feb 13 11:12:55 2013 +0100
     6.2 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JSNI2JavaScriptBodyTest.java	Wed Feb 13 12:08:00 2013 +0100
     6.3 @@ -18,9 +18,9 @@
     6.4  package org.apidesign.bck2brwsr.ide.editor;
     6.5  
     6.6  import org.apidesign.bck2brwsr.core.JavaScriptBody;
     6.7 -import org.junit.Test;
     6.8  import org.netbeans.modules.java.hints.test.api.HintTest;
     6.9  import org.openide.filesystems.FileUtil;
    6.10 +import org.testng.annotations.Test;
    6.11  
    6.12  public class JSNI2JavaScriptBodyTest {
    6.13  
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/JsniCommentTokenizerTest.java	Wed Feb 13 12:08:00 2013 +0100
     7.3 @@ -0,0 +1,154 @@
     7.4 +/**
     7.5 + * Back 2 Browser Bytecode Translator
     7.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     7.7 + *
     7.8 + * This program is free software: you can redistribute it and/or modify
     7.9 + * it under the terms of the GNU General Public License as published by
    7.10 + * the Free Software Foundation, version 2 of the License.
    7.11 + *
    7.12 + * This program is distributed in the hope that it will be useful,
    7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.15 + * GNU General Public License for more details.
    7.16 + *
    7.17 + * You should have received a copy of the GNU General Public License
    7.18 + * along with this program. Look for COPYING file in the top folder.
    7.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    7.20 + */
    7.21 +package org.apidesign.bck2brwsr.ide.editor;
    7.22 +
    7.23 +import java.io.IOException;
    7.24 +import java.util.ArrayList;
    7.25 +import java.util.List;
    7.26 +import org.testng.Assert;
    7.27 +import org.testng.annotations.Test;
    7.28 +
    7.29 +public class JsniCommentTokenizerTest {
    7.30 +
    7.31 +    private static class MockSink implements JsniCommentTokenizer.Sink {
    7.32 +        final List<String> out = new ArrayList<String>();
    7.33 +
    7.34 +        public void javascript(String s) {
    7.35 +            out.add("J " + s);
    7.36 +        }
    7.37 +
    7.38 +        public void method(String clazz, String method, String signature) {
    7.39 +            out.add("M " + clazz + "|" + method + "|" + signature);
    7.40 +        }
    7.41 +
    7.42 +        public void field(String clazz, String field) {
    7.43 +            out.add("F " + clazz + "|" + field);
    7.44 +        }
    7.45 +    }
    7.46 +
    7.47 +
    7.48 +    @Test
    7.49 +    public void testProcess_nop() throws IOException {
    7.50 +        final String in = "foo bar";
    7.51 +        final List<String> expected = new ArrayList<String>();
    7.52 +        expected.add("J foo bar");
    7.53 +
    7.54 +        final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer();
    7.55 +        final MockSink out = new MockSink();
    7.56 +        jsniCommentTokenizer.process(in, out);
    7.57 +
    7.58 +        Assert.assertEquals(expected, out.out);
    7.59 +    }
    7.60 +
    7.61 +    @Test
    7.62 +    public void testProcess_read_static_field() throws IOException {
    7.63 +        final String in = " @com.google.gwt.examples.JSNIExample::myStaticField = val + \" and stuff\";";
    7.64 +        final List<String> expected = new ArrayList<String>();
    7.65 +        expected.add("J  ");
    7.66 +        expected.add("F com.google.gwt.examples.JSNIExample|myStaticField");
    7.67 +        expected.add("J  = val + \" and stuff\";");
    7.68 +
    7.69 +        final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer();
    7.70 +        final MockSink out = new MockSink();
    7.71 +        jsniCommentTokenizer.process(in, out);
    7.72 +
    7.73 +        Assert.assertEquals(expected, out.out);
    7.74 +    }
    7.75 +
    7.76 +    @Test
    7.77 +    public void testProcess_write_instance_field() throws IOException {
    7.78 +        final String in = " x.@com.google.gwt.examples.JSNIExample::myInstanceField = val + \" and stuff\";";
    7.79 +        final List<String> expected = new ArrayList<String>();
    7.80 +        expected.add("J  x.");
    7.81 +        expected.add("F com.google.gwt.examples.JSNIExample|myInstanceField");
    7.82 +        expected.add("J  = val + \" and stuff\";");
    7.83 +
    7.84 +        final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer();
    7.85 +        final MockSink out = new MockSink();
    7.86 +        jsniCommentTokenizer.process(in, out);
    7.87 +
    7.88 +        Assert.assertEquals(expected, out.out);
    7.89 +    }
    7.90 +
    7.91 +    @Test
    7.92 +    public void testProcess_read_instance_field() throws IOException {
    7.93 +        final String in = " var val = this.@com.google.gwt.examples.JSNIExample::myInstanceField;";
    7.94 +        final List<String> expected = new ArrayList<String>();
    7.95 +        expected.add("J  var val = this.");
    7.96 +        expected.add("F com.google.gwt.examples.JSNIExample|myInstanceField");
    7.97 +        expected.add("J ;");
    7.98 +
    7.99 +        final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer();
   7.100 +        final MockSink out = new MockSink();
   7.101 +        jsniCommentTokenizer.process(in, out);
   7.102 +
   7.103 +        Assert.assertEquals(expected, out.out);
   7.104 +    }
   7.105 +
   7.106 +
   7.107 +    @Test
   7.108 +    public void testProcess_static_method() throws IOException {
   7.109 +        final String in = " @com.google.gwt.examples.JSNIExample::staticFoo(Ljava/lang/String;)(s);";
   7.110 +        final List<String> expected = new ArrayList<String>();
   7.111 +        expected.add("J  ");
   7.112 +        expected.add("M com.google.gwt.examples.JSNIExample|staticFoo|Ljava/lang/String;");
   7.113 +        expected.add("J (s);");
   7.114 +
   7.115 +        final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer();
   7.116 +        final MockSink out = new MockSink();
   7.117 +        jsniCommentTokenizer.process(in, out);
   7.118 +
   7.119 +        Assert.assertEquals(expected, out.out);
   7.120 +    }
   7.121 +
   7.122 +
   7.123 +    @Test
   7.124 +    public void testProcess_instance_method() throws IOException {
   7.125 +        final String in = " x.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s);";
   7.126 +        final List<String> expected = new ArrayList<String>();
   7.127 +        expected.add("J  x.");
   7.128 +        expected.add("M com.google.gwt.examples.JSNIExample|instanceFoo|Ljava/lang/String;");
   7.129 +        expected.add("J (s);");
   7.130 +
   7.131 +        final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer();
   7.132 +        final MockSink out = new MockSink();
   7.133 +        jsniCommentTokenizer.process(in, out);
   7.134 +
   7.135 +        Assert.assertEquals(expected, out.out);
   7.136 +    }
   7.137 +
   7.138 +
   7.139 +    @Test
   7.140 +    public void testProcess_multiline() throws IOException {
   7.141 +        final String in =
   7.142 +            " x.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s);" +
   7.143 +            " @com.google.gwt.examples.JSNIExample::myStaticField = val + \" and stuff\";";
   7.144 +        final List<String> expected = new ArrayList<String>();
   7.145 +        expected.add("J  x.");
   7.146 +        expected.add("M com.google.gwt.examples.JSNIExample|instanceFoo|Ljava/lang/String;");
   7.147 +        expected.add("J (s); ");
   7.148 +        expected.add("F com.google.gwt.examples.JSNIExample|myStaticField");
   7.149 +        expected.add("J  = val + \" and stuff\";");
   7.150 +
   7.151 +        final JsniCommentTokenizer jsniCommentTokenizer = new JsniCommentTokenizer();
   7.152 +        final MockSink out = new MockSink();
   7.153 +        jsniCommentTokenizer.process(in, out);
   7.154 +
   7.155 +        Assert.assertEquals(expected, out.out);
   7.156 +    }
   7.157 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/ide/editor/src/test/java/org/apidesign/bck2brwsr/ide/editor/ManglingSinkTest.java	Wed Feb 13 12:08:00 2013 +0100
     8.3 @@ -0,0 +1,58 @@
     8.4 +/**
     8.5 + * Back 2 Browser Bytecode Translator
     8.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     8.7 + *
     8.8 + * This program is free software: you can redistribute it and/or modify
     8.9 + * it under the terms of the GNU General Public License as published by
    8.10 + * the Free Software Foundation, version 2 of the License.
    8.11 + *
    8.12 + * This program is distributed in the hope that it will be useful,
    8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.15 + * GNU General Public License for more details.
    8.16 + *
    8.17 + * You should have received a copy of the GNU General Public License
    8.18 + * along with this program. Look for COPYING file in the top folder.
    8.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    8.20 + */
    8.21 +package org.apidesign.bck2brwsr.ide.editor;
    8.22 +
    8.23 +import org.testng.Assert;
    8.24 +import org.testng.annotations.Test;
    8.25 +
    8.26 +
    8.27 +public class ManglingSinkTest {
    8.28 +
    8.29 +    @Test
    8.30 +    public void testMangle_1() {
    8.31 +        Assert.assertEquals(
    8.32 +                "binarySearch__I_3BIIB",
    8.33 +                ManglingSink.mangle("java.util.Arrays", "binarySearch", "[BIIB")
    8.34 +        );
    8.35 +    }
    8.36 +
    8.37 +    @Test
    8.38 +    public void testMangle_2() {
    8.39 +        Assert.assertEquals(
    8.40 +                "sort__V_3I",
    8.41 +                ManglingSink.mangle("java.util.Arrays", "sort", "[I")
    8.42 +        );
    8.43 +    }
    8.44 +
    8.45 +    @Test
    8.46 +    public void testMangle_3() {
    8.47 +        Assert.assertEquals(
    8.48 +                "binarySearch__I_3Ljava_lang_Object_2IILjava_lang_Object_2",
    8.49 +                ManglingSink.mangle("java.util.Arrays", "binarySearch", "[Ljava/lang/Object;IILjava/lang/Object;")
    8.50 +        );
    8.51 +    }
    8.52 +
    8.53 +
    8.54 +    @Test
    8.55 +    public void testField() {
    8.56 +        final ManglingSink manglingSink = new ManglingSink();
    8.57 +        manglingSink.field(null, "value");
    8.58 +
    8.59 +        Assert.assertEquals("_value()", manglingSink.toString());
    8.60 +    }
    8.61 +}