1.1 --- a/benchmarks/matrix-multiplication/jsTestDriver.conf Fri Jan 18 14:23:18 2013 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,5 +0,0 @@
1.4 -server: http://localhost:9876
1.5 -
1.6 -load:
1.7 - - target/classes/org/apidesign/benchmark/matrixmul/*.js
1.8 -
2.1 --- a/benchmarks/matrix-multiplication/nbactions.xml Fri Jan 18 14:23:18 2013 +0100
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,29 +0,0 @@
2.4 -<?xml version="1.0" encoding="UTF-8"?>
2.5 -<!--
2.6 -
2.7 - Back 2 Browser Bytecode Translator
2.8 - Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.9 -
2.10 - This program is free software: you can redistribute it and/or modify
2.11 - it under the terms of the GNU General Public License as published by
2.12 - the Free Software Foundation, version 2 of the License.
2.13 -
2.14 - This program is distributed in the hope that it will be useful,
2.15 - but WITHOUT ANY WARRANTY; without even the implied warranty of
2.16 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.17 - GNU General Public License for more details.
2.18 -
2.19 - You should have received a copy of the GNU General Public License
2.20 - along with this program. Look for COPYING file in the top folder.
2.21 - If not, see http://opensource.org/licenses/GPL-2.0.
2.22 -
2.23 --->
2.24 -<actions>
2.25 - <action>
2.26 - <actionName>run</actionName>
2.27 - <goals>
2.28 - <goal>process-classes</goal>
2.29 - <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
2.30 - </goals>
2.31 - </action>
2.32 -</actions>
3.1 --- a/benchmarks/matrix-multiplication/pom.xml Fri Jan 18 14:23:18 2013 +0100
3.2 +++ b/benchmarks/matrix-multiplication/pom.xml Fri Jan 18 14:27:22 2013 +0100
3.3 @@ -25,62 +25,9 @@
3.4 <target>1.7</target>
3.5 </configuration>
3.6 </plugin>
3.7 -
3.8 - <plugin>
3.9 - <groupId>org.apidesign.bck2brwsr</groupId>
3.10 - <artifactId>mojo</artifactId>
3.11 - <version>0.3-SNAPSHOT</version>
3.12 - <executions>
3.13 - <execution>
3.14 - <goals>
3.15 - <goal>j2js</goal>
3.16 - </goals>
3.17 - </execution>
3.18 - </executions>
3.19 - </plugin>
3.20 -
3.21 </plugins>
3.22 </build>
3.23
3.24 - <profiles>
3.25 - <profile>
3.26 - <id>run-benchmarks</id>
3.27 - <activation>
3.28 - <property><name>bck2brwsr.runBenchmarks.browsers</name></property>
3.29 - </activation>
3.30 -
3.31 - <build>
3.32 - <plugins>
3.33 -
3.34 - <plugin>
3.35 - <groupId>com.googlecode.jstd-maven-plugin</groupId>
3.36 - <artifactId>jstd-maven-plugin</artifactId>
3.37 - <version>1.3.2.5</version>
3.38 - <configuration>
3.39 - <port>9876</port>
3.40 - <browser>${bck2brwsr.runBenchmarks.browsers}</browser>
3.41 - <browserTimeout>720</browserTimeout>
3.42 - <tests>all</tests>
3.43 - <config>jsTestDriver.conf</config>
3.44 - <reset>true</reset>
3.45 - <testOutput>${basedir}/target/testOutput</testOutput>
3.46 - <!-- runnerMode>DEBUG</runnerMode -->
3.47 - </configuration>
3.48 - <executions>
3.49 - <execution>
3.50 - <id>run-tests</id>
3.51 - <goals>
3.52 - <goal>test</goal>
3.53 - </goals>
3.54 - </execution>
3.55 - </executions>
3.56 - </plugin>
3.57 -
3.58 - </plugins>
3.59 - </build>
3.60 - </profile>
3.61 - </profiles>
3.62 -
3.63 <dependencies>
3.64 <dependency>
3.65 <groupId>org.apidesign.bck2brwsr</groupId>
3.66 @@ -88,24 +35,22 @@
3.67 <version>0.3-SNAPSHOT</version>
3.68 </dependency>
3.69 <dependency>
3.70 - <groupId>com.googlecode.jstd-maven-plugin</groupId>
3.71 - <artifactId>jstd-maven-plugin</artifactId>
3.72 - <version>1.3.2.5</version>
3.73 - <scope>test</scope>
3.74 + <groupId>org.testng</groupId>
3.75 + <artifactId>testng</artifactId>
3.76 + <version>6.5.2</version>
3.77 + <scope>test</scope>
3.78 + <exclusions>
3.79 + <exclusion>
3.80 + <artifactId>junit</artifactId>
3.81 + <groupId>junit</groupId>
3.82 + </exclusion>
3.83 + </exclusions>
3.84 + </dependency>
3.85 + <dependency>
3.86 + <groupId>org.apidesign.bck2brwsr</groupId>
3.87 + <artifactId>vmtest</artifactId>
3.88 + <version>0.3-SNAPSHOT</version>
3.89 + <scope>test</scope>
3.90 </dependency>
3.91 </dependencies>
3.92 -
3.93 - <repositories>
3.94 - <repository>
3.95 - <id>jstd-maven-plugin google code repo</id>
3.96 - <url>http://jstd-maven-plugin.googlecode.com/svn/maven2</url>
3.97 - </repository>
3.98 - </repositories>
3.99 - <pluginRepositories>
3.100 - <pluginRepository>
3.101 - <id>jstd-maven-plugin google code repo</id>
3.102 - <url>http://jstd-maven-plugin.googlecode.com/svn/maven2</url>
3.103 - </pluginRepository>
3.104 - </pluginRepositories>
3.105 -
3.106 </project>
4.1 --- a/benchmarks/matrix-multiplication/src/main/java/org/apidesign/benchmark/matrixmul/Main.java Fri Jan 18 14:23:18 2013 +0100
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,42 +0,0 @@
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.benchmark.matrixmul;
4.22 -
4.23 -public class Main {
4.24 -
4.25 - public static final int ITERATION_COUNT = 100000;
4.26 -
4.27 - public static void main(String[] args) {
4.28 - Matrix m1 = new Matrix(5);
4.29 - Matrix m2 = new Matrix(5);
4.30 -
4.31 - m1.generateData();
4.32 - m2.generateData();
4.33 -
4.34 - //m1.printOn(System.out);
4.35 - //System.out.println("x");
4.36 - //m2.printOn(System.out);
4.37 -
4.38 - for (int i = 0; i < ITERATION_COUNT; i++) {
4.39 - m1.multiply(m2);
4.40 - }
4.41 -
4.42 - //System.out.println("=");
4.43 - //m1.printOn(System.out);
4.44 - }
4.45 -}
5.1 --- a/benchmarks/matrix-multiplication/src/main/java/org/apidesign/benchmark/matrixmul/Matrix.java Fri Jan 18 14:23:18 2013 +0100
5.2 +++ b/benchmarks/matrix-multiplication/src/main/java/org/apidesign/benchmark/matrixmul/Matrix.java Fri Jan 18 14:27:22 2013 +0100
5.3 @@ -17,17 +17,20 @@
5.4 */
5.5 package org.apidesign.benchmark.matrixmul;
5.6
5.7 -//import java.io.PrintStream;
5.8 -//import java.util.Random;
5.9 +import java.io.IOException;
5.10 +import java.util.Arrays;
5.11
5.12 public class Matrix {
5.13 -
5.14 private final int rank;
5.15 - private float data[][];
5.16 + private final float data[][];
5.17
5.18 public Matrix(int r) {
5.19 - rank = r;
5.20 - data = new float[r][r];
5.21 + this(r, new float[r][r]);
5.22 + }
5.23 +
5.24 + private Matrix(int r, float[][] data) {
5.25 + this.rank = r;
5.26 + this.data = data;
5.27 }
5.28
5.29 public void setElement(int i, int j, float value) {
5.30 @@ -62,20 +65,44 @@
5.31 res[i][j] = ij;
5.32 }
5.33 }
5.34 - data = res;
5.35 -
5.36 - return this;
5.37 + return new Matrix(rank, res);
5.38 }
5.39
5.40 - /*
5.41 - public void printOn(PrintStream s) {
5.42 + public void printOn(Appendable s) throws IOException {
5.43 for (int i = 0; i < rank; i++) {
5.44 + String sep = "";
5.45 for (int j = 0; j < rank; j++) {
5.46 - s.printf("%f ", data[i][j]);
5.47 + s.append(sep + data[i][j]);
5.48 + sep = " ";
5.49 }
5.50 - s.println();
5.51 + s.append("\n");
5.52 }
5.53 }
5.54 - */
5.55 -
5.56 +
5.57 + @Override
5.58 + public boolean equals(Object obj) {
5.59 + if (obj instanceof Matrix) {
5.60 + Matrix snd = (Matrix)obj;
5.61 + if (snd.rank != rank) {
5.62 + return false;
5.63 + }
5.64 + for (int i = 0; i < rank; i++) {
5.65 + for (int j = 0; j < rank; j++) {
5.66 + if (data[i][j] != snd.data[i][j]) {
5.67 + return false;
5.68 + }
5.69 + }
5.70 + }
5.71 + return true;
5.72 + }
5.73 + return false;
5.74 + }
5.75 +
5.76 + @Override
5.77 + public int hashCode() {
5.78 + int hash = 3;
5.79 + hash = 97 * hash + this.rank;
5.80 + hash = 97 * hash + Arrays.deepHashCode(this.data);
5.81 + return hash;
5.82 + }
5.83 }
6.1 --- a/benchmarks/matrix-multiplication/src/main/resources/org/apidesign/benchmark/matrixmul/multiplication-test.js Fri Jan 18 14:23:18 2013 +0100
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,25 +0,0 @@
6.4 -/*
6.5 - * Back 2 Browser Bytecode Translator
6.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
6.7 - *
6.8 - * This program is free software: you can redistribute it and/or modify
6.9 - * it under the terms of the GNU General Public License as published by
6.10 - * the Free Software Foundation, version 2 of the License.
6.11 - *
6.12 - * This program is distributed in the hope that it will be useful,
6.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.15 - * GNU General Public License for more details.
6.16 - *
6.17 - * You should have received a copy of the GNU General Public License
6.18 - * along with this program. Look for COPYING file in the top folder.
6.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
6.20 - */
6.21 -MatrixTest = TestCase("MatrixTest");
6.22 -
6.23 -
6.24 -MatrixTest.prototype.testMultiplication = function() {
6.25 - var vm = new bck2brwsr();
6.26 - var x = vm.loadClass("org.apidesign.benchmark.matrixmul.Main");
6.27 - x.main__V_3Ljava_lang_String_2(null);
6.28 -};
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/benchmarks/matrix-multiplication/src/test/java/org/apidesign/benchmark/matrixmul/MatrixTest.java Fri Jan 18 14:27:22 2013 +0100
7.3 @@ -0,0 +1,61 @@
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.benchmark.matrixmul;
7.22 +
7.23 +import java.io.IOException;
7.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
7.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
7.26 +import org.testng.annotations.Factory;
7.27 +
7.28 +/**
7.29 + *
7.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
7.31 + */
7.32 +public class MatrixTest {
7.33 + public static final int ITERATION_COUNT = 10;
7.34 +
7.35 + public MatrixTest() {
7.36 + }
7.37 +
7.38 + @Compare public String tenThousandIterations() throws IOException {
7.39 +
7.40 + Matrix m1 = new Matrix(5);
7.41 + Matrix m2 = new Matrix(5);
7.42 +
7.43 + m1.generateData();
7.44 + m2.generateData();
7.45 +
7.46 + Matrix res = null;
7.47 + for (int i = 0; i < ITERATION_COUNT; i++) {
7.48 + Matrix m = m1.multiply(m2);
7.49 + if (res != null && !res.equals(m)) {
7.50 + return "different";
7.51 + }
7.52 + res = m;
7.53 + }
7.54 +
7.55 + StringBuilder sb = new StringBuilder();
7.56 + res.printOn(sb);
7.57 + return sb.toString();
7.58 + }
7.59 +
7.60 + @Factory
7.61 + public static Object[] create() {
7.62 + return VMTest.create(MatrixTest.class);
7.63 + }
7.64 +}
8.1 --- a/benchmarks/run-firefox.sh Fri Jan 18 14:23:18 2013 +0100
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,20 +0,0 @@
8.4 -#!/bin/bash
8.5 -#
8.6 -# Back 2 Browser Bytecode Translator
8.7 -# Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
8.8 -#
8.9 -# This program is free software: you can redistribute it and/or modify
8.10 -# it under the terms of the GNU General Public License as published by
8.11 -# the Free Software Foundation, version 2 of the License.
8.12 -#
8.13 -# This program is distributed in the hope that it will be useful,
8.14 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
8.15 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.16 -# GNU General Public License for more details.
8.17 -#
8.18 -# You should have received a copy of the GNU General Public License
8.19 -# along with this program. Look for COPYING file in the top folder.
8.20 -# If not, see http://opensource.org/licenses/GPL-2.0.
8.21 -#
8.22 -
8.23 -/usr/bin/firefox --display=`echo $DISPLAY` "$@"
9.1 --- a/core/pom.xml Fri Jan 18 14:23:18 2013 +0100
9.2 +++ b/core/pom.xml Fri Jan 18 14:27:22 2013 +0100
9.3 @@ -19,8 +19,8 @@
9.4 <artifactId>maven-compiler-plugin</artifactId>
9.5 <version>2.3.2</version>
9.6 <configuration>
9.7 - <source>1.6</source>
9.8 - <target>1.6</target>
9.9 + <source>1.7</source>
9.10 + <target>1.7</target>
9.11 </configuration>
9.12 </plugin>
9.13 </plugins>
9.14 @@ -35,6 +35,10 @@
9.15 <version>3.8.1</version>
9.16 <scope>test</scope>
9.17 </dependency>
9.18 + <dependency>
9.19 + <groupId>org.netbeans.api</groupId>
9.20 + <artifactId>org-openide-util-lookup</artifactId>
9.21 + </dependency>
9.22 </dependencies>
9.23 <description>Contains esential annotations for associating JavaScript code with
9.24 methods and classes.</description>
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/core/src/main/java/org/apidesign/bck2brwsr/core/impl/JavaScriptProcesor.java Fri Jan 18 14:27:22 2013 +0100
10.3 @@ -0,0 +1,92 @@
10.4 +/**
10.5 + * Back 2 Browser Bytecode Translator
10.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
10.7 + *
10.8 + * This program is free software: you can redistribute it and/or modify
10.9 + * it under the terms of the GNU General Public License as published by
10.10 + * the Free Software Foundation, version 2 of the License.
10.11 + *
10.12 + * This program is distributed in the hope that it will be useful,
10.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.15 + * GNU General Public License for more details.
10.16 + *
10.17 + * You should have received a copy of the GNU General Public License
10.18 + * along with this program. Look for COPYING file in the top folder.
10.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
10.20 + */
10.21 +package org.apidesign.bck2brwsr.core.impl;
10.22 +
10.23 +import java.util.Collections;
10.24 +import java.util.HashSet;
10.25 +import java.util.List;
10.26 +import java.util.Set;
10.27 +import javax.annotation.processing.AbstractProcessor;
10.28 +import javax.annotation.processing.Completion;
10.29 +import javax.annotation.processing.Completions;
10.30 +import javax.annotation.processing.Processor;
10.31 +import javax.annotation.processing.RoundEnvironment;
10.32 +import javax.lang.model.element.AnnotationMirror;
10.33 +import javax.lang.model.element.Element;
10.34 +import javax.lang.model.element.ElementKind;
10.35 +import javax.lang.model.element.ExecutableElement;
10.36 +import javax.lang.model.element.Modifier;
10.37 +import javax.lang.model.element.TypeElement;
10.38 +import javax.lang.model.element.VariableElement;
10.39 +import javax.tools.Diagnostic;
10.40 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
10.41 +import org.openide.util.lookup.ServiceProvider;
10.42 +
10.43 +/**
10.44 + *
10.45 + * @author Jaroslav Tulach <jtulach@netbeans.org>
10.46 + */
10.47 +@ServiceProvider(service = Processor.class)
10.48 +public final class JavaScriptProcesor extends AbstractProcessor {
10.49 + @Override
10.50 + public Set<String> getSupportedAnnotationTypes() {
10.51 + Set<String> set = new HashSet<>();
10.52 + set.add(JavaScriptBody.class.getName());
10.53 + return set;
10.54 + }
10.55 +
10.56 + @Override
10.57 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
10.58 + for (Element e : roundEnv.getElementsAnnotatedWith(JavaScriptBody.class)) {
10.59 + if (e.getKind() != ElementKind.METHOD && e.getKind() != ElementKind.CONSTRUCTOR) {
10.60 + continue;
10.61 + }
10.62 + ExecutableElement ee = (ExecutableElement)e;
10.63 + List<? extends VariableElement> params = ee.getParameters();
10.64 +
10.65 + JavaScriptBody jsb = e.getAnnotation(JavaScriptBody.class);
10.66 + String[] arr = jsb.args();
10.67 + if (params.size() != arr.length) {
10.68 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Number of args arguments does not match real arguments!", e);
10.69 + }
10.70 + }
10.71 + return true;
10.72 + }
10.73 +
10.74 + @Override
10.75 + public Iterable<? extends Completion> getCompletions(Element e,
10.76 + AnnotationMirror annotation, ExecutableElement member, String userText
10.77 + ) {
10.78 + StringBuilder sb = new StringBuilder();
10.79 + if (e.getKind() == ElementKind.METHOD && member.getSimpleName().contentEquals("args")) {
10.80 + ExecutableElement ee = (ExecutableElement) e;
10.81 + String sep = "";
10.82 + sb.append("{ ");
10.83 + for (VariableElement ve : ee.getParameters()) {
10.84 + sb.append(sep).append('"').append(ve.getSimpleName())
10.85 + .append('"');
10.86 + sep = ", ";
10.87 + }
10.88 + sb.append(" }");
10.89 + return Collections.nCopies(1, Completions.of(sb.toString()));
10.90 + }
10.91 + return null;
10.92 + }
10.93 +
10.94 +
10.95 +}
11.1 --- a/emul/src/main/java/java/lang/AbstractStringBuilder.java Fri Jan 18 14:23:18 2013 +0100
11.2 +++ b/emul/src/main/java/java/lang/AbstractStringBuilder.java Fri Jan 18 14:27:22 2013 +0100
11.3 @@ -1271,8 +1271,7 @@
11.4 * <code>null</code>.
11.5 */
11.6 public int indexOf(String str, int fromIndex) {
11.7 - return String.indexOf(value, 0, count,
11.8 - str.toCharArray(), 0, str.length(), fromIndex);
11.9 + return toString().indexOf(str, fromIndex);
11.10 }
11.11
11.12 /**
12.1 --- a/emul/src/main/java/java/lang/Character.java Fri Jan 18 14:23:18 2013 +0100
12.2 +++ b/emul/src/main/java/java/lang/Character.java Fri Jan 18 14:27:22 2013 +0100
12.3 @@ -25,6 +25,8 @@
12.4
12.5 package java.lang;
12.6
12.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
12.8 +
12.9 /**
12.10 * The {@code Character} class wraps a value of the primitive
12.11 * type {@code char} in an object. An object of type
12.12 @@ -1525,7 +1527,7 @@
12.13 * @see Character#getType(char)
12.14 */
12.15 public static boolean isLowerCase(char ch) {
12.16 - throw new UnsupportedOperationException();
12.17 + return ch == toLowerCase(ch);
12.18 }
12.19
12.20 /**
12.21 @@ -1560,7 +1562,7 @@
12.22 * @since 1.0
12.23 */
12.24 public static boolean isUpperCase(char ch) {
12.25 - throw new UnsupportedOperationException();
12.26 + return ch == toUpperCase(ch);
12.27 }
12.28
12.29 /**
12.30 @@ -1676,7 +1678,7 @@
12.31 * @see Character#getType(char)
12.32 */
12.33 public static boolean isDigit(char ch) {
12.34 - return isDigit((int)ch);
12.35 + return String.valueOf(ch).matches("\\d");
12.36 }
12.37
12.38 /**
12.39 @@ -1710,8 +1712,11 @@
12.40 * @since 1.5
12.41 */
12.42 public static boolean isDigit(int codePoint) {
12.43 - return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
12.44 + return fromCodeChars(codePoint).matches("\\d");
12.45 }
12.46 +
12.47 + @JavaScriptBody(args = "c", body = "return String.fromCharCode(c);")
12.48 + private native static String fromCodeChars(int codePoint);
12.49
12.50 /**
12.51 * Determines if a character is defined in Unicode.
12.52 @@ -1802,7 +1807,7 @@
12.53 * @see Character#isUpperCase(char)
12.54 */
12.55 public static boolean isLetter(char ch) {
12.56 - return isLetter((int)ch);
12.57 + return String.valueOf(ch).matches("\\w") && !isDigit(ch);
12.58 }
12.59
12.60 /**
12.61 @@ -1835,12 +1840,7 @@
12.62 * @since 1.5
12.63 */
12.64 public static boolean isLetter(int codePoint) {
12.65 - return ((((1 << Character.UPPERCASE_LETTER) |
12.66 - (1 << Character.LOWERCASE_LETTER) |
12.67 - (1 << Character.TITLECASE_LETTER) |
12.68 - (1 << Character.MODIFIER_LETTER) |
12.69 - (1 << Character.OTHER_LETTER)) >> getType(codePoint)) & 1)
12.70 - != 0;
12.71 + return fromCodeChars(codePoint).matches("\\w") && !isDigit(codePoint);
12.72 }
12.73
12.74 /**
12.75 @@ -1868,7 +1868,7 @@
12.76 * @since 1.0.2
12.77 */
12.78 public static boolean isLetterOrDigit(char ch) {
12.79 - return isLetterOrDigit((int)ch);
12.80 + return String.valueOf(ch).matches("\\w");
12.81 }
12.82
12.83 /**
12.84 @@ -1889,13 +1889,7 @@
12.85 * @since 1.5
12.86 */
12.87 public static boolean isLetterOrDigit(int codePoint) {
12.88 - return ((((1 << Character.UPPERCASE_LETTER) |
12.89 - (1 << Character.LOWERCASE_LETTER) |
12.90 - (1 << Character.TITLECASE_LETTER) |
12.91 - (1 << Character.MODIFIER_LETTER) |
12.92 - (1 << Character.OTHER_LETTER) |
12.93 - (1 << Character.DECIMAL_DIGIT_NUMBER)) >> getType(codePoint)) & 1)
12.94 - != 0;
12.95 + return fromCodeChars(codePoint).matches("\\w");
12.96 }
12.97
12.98 static int getType(int x) {
12.99 @@ -1930,7 +1924,7 @@
12.100 * @see String#toLowerCase()
12.101 */
12.102 public static char toLowerCase(char ch) {
12.103 - throw new UnsupportedOperationException();
12.104 + return String.valueOf(ch).toLowerCase().charAt(0);
12.105 }
12.106
12.107 /**
12.108 @@ -1961,7 +1955,7 @@
12.109 * @see String#toUpperCase()
12.110 */
12.111 public static char toUpperCase(char ch) {
12.112 - throw new UnsupportedOperationException();
12.113 + return String.valueOf(ch).toUpperCase().charAt(0);
12.114 }
12.115
12.116 /**
13.1 --- a/emul/src/main/java/java/lang/Class.java Fri Jan 18 14:23:18 2013 +0100
13.2 +++ b/emul/src/main/java/java/lang/Class.java Fri Jan 18 14:27:22 2013 +0100
13.3 @@ -25,6 +25,7 @@
13.4
13.5 package java.lang;
13.6
13.7 +import java.io.ByteArrayInputStream;
13.8 import org.apidesign.bck2brwsr.emul.AnnotationImpl;
13.9 import java.io.InputStream;
13.10 import java.lang.annotation.Annotation;
13.11 @@ -32,6 +33,7 @@
13.12 import java.lang.reflect.Method;
13.13 import java.lang.reflect.TypeVariable;
13.14 import org.apidesign.bck2brwsr.core.JavaScriptBody;
13.15 +import org.apidesign.bck2brwsr.emul.MethodImpl;
13.16
13.17 /**
13.18 * Instances of the class {@code Class} represent classes and
13.19 @@ -143,9 +145,31 @@
13.20 * @exception ClassNotFoundException if the class cannot be located
13.21 */
13.22 public static Class<?> forName(String className)
13.23 - throws ClassNotFoundException {
13.24 - throw new UnsupportedOperationException();
13.25 + throws ClassNotFoundException {
13.26 + if (className.startsWith("[")) {
13.27 + Class<?> arrType = defineArray(className);
13.28 + Class<?> c = arrType;
13.29 + while (c != null && c.isArray()) {
13.30 + c = c.getComponentType0(); // verify component type is sane
13.31 + }
13.32 + return arrType;
13.33 + }
13.34 + Class<?> c = loadCls(className, className.replace('.', '_'));
13.35 + if (c == null) {
13.36 + throw new ClassNotFoundException(className);
13.37 + }
13.38 + return c;
13.39 }
13.40 +
13.41 + @JavaScriptBody(args = {"n", "c" }, body =
13.42 + "if (vm[c]) return vm[c].$class;\n"
13.43 + + "if (vm.loadClass) {\n"
13.44 + + " vm.loadClass(n);\n"
13.45 + + " if (vm[c]) return vm[c].$class;\n"
13.46 + + "}\n"
13.47 + + "return null;"
13.48 + )
13.49 + private static native Class<?> loadCls(String n, String c);
13.50
13.51
13.52 /**
13.53 @@ -195,15 +219,32 @@
13.54 * </ul>
13.55 *
13.56 */
13.57 - @JavaScriptBody(args = "self", body =
13.58 - "var inst = self.cnstr();"
13.59 - + "inst.cons__V(inst);"
13.60 - + "return inst;"
13.61 + @JavaScriptBody(args = { "self", "illegal" }, body =
13.62 + "\nvar c = self.cnstr;"
13.63 + + "\nif (c['cons__V']) {"
13.64 + + "\n if ((c.cons__V.access & 0x1) != 0) {"
13.65 + + "\n var inst = c();"
13.66 + + "\n c.cons__V.call(inst);"
13.67 + + "\n return inst;"
13.68 + + "\n }"
13.69 + + "\n return illegal;"
13.70 + + "\n}"
13.71 + + "\nreturn null;"
13.72 )
13.73 + private static native Object newInstance0(Class<?> self, Object illegal);
13.74 +
13.75 public T newInstance()
13.76 throws InstantiationException, IllegalAccessException
13.77 {
13.78 - throw new UnsupportedOperationException();
13.79 + Object illegal = new Object();
13.80 + Object inst = newInstance0(this, illegal);
13.81 + if (inst == null) {
13.82 + throw new InstantiationException(getName());
13.83 + }
13.84 + if (inst == illegal) {
13.85 + throw new IllegalAccessException();
13.86 + }
13.87 + return (T)inst;
13.88 }
13.89
13.90 /**
13.91 @@ -236,7 +277,15 @@
13.92 *
13.93 * @since JDK1.1
13.94 */
13.95 - public native boolean isInstance(Object obj);
13.96 + public boolean isInstance(Object obj) {
13.97 + String prop = "$instOf_" + getName().replace('.', '_');
13.98 + return hasProperty(obj, prop);
13.99 + }
13.100 +
13.101 + @JavaScriptBody(args = { "who", "prop" }, body =
13.102 + "if (who[prop]) return true; else return false;"
13.103 + )
13.104 + private static native boolean hasProperty(Object who, String prop);
13.105
13.106
13.107 /**
13.108 @@ -273,7 +322,12 @@
13.109 * @return {@code true} if this object represents an interface;
13.110 * {@code false} otherwise.
13.111 */
13.112 - public native boolean isInterface();
13.113 + public boolean isInterface() {
13.114 + return (getAccess() & 0x200) != 0;
13.115 + }
13.116 +
13.117 + @JavaScriptBody(args = {}, body = "return this.access;")
13.118 + private native int getAccess();
13.119
13.120
13.121 /**
13.122 @@ -284,7 +338,7 @@
13.123 * @since JDK1.1
13.124 */
13.125 public boolean isArray() {
13.126 - return false;
13.127 + return hasProperty(this, "array"); // NOI18N
13.128 }
13.129
13.130
13.131 @@ -316,6 +370,10 @@
13.132 * @see java.lang.Void#TYPE
13.133 * @since JDK1.1
13.134 */
13.135 + @JavaScriptBody(args = {}, body =
13.136 + "if (this.primitive) return true;"
13.137 + + "else return false;"
13.138 + )
13.139 public native boolean isPrimitive();
13.140
13.141 /**
13.142 @@ -397,7 +455,7 @@
13.143 return jvmName().replace('/', '.');
13.144 }
13.145
13.146 - @JavaScriptBody(args = "self", body = "return self.jvmName;")
13.147 + @JavaScriptBody(args = {}, body = "return this.jvmName;")
13.148 private native String jvmName();
13.149
13.150
13.151 @@ -431,7 +489,7 @@
13.152 *
13.153 * @return the superclass of the class represented by this object.
13.154 */
13.155 - @JavaScriptBody(args = "self", body = "return self.superclass;")
13.156 + @JavaScriptBody(args = {}, body = "return this.superclass;")
13.157 public native Class<? super T> getSuperclass();
13.158
13.159 /**
13.160 @@ -617,7 +675,7 @@
13.161 * @since JDK1.1
13.162 */
13.163 public Method[] getMethods() throws SecurityException {
13.164 - return Method.findMethods(this);
13.165 + return MethodImpl.findMethods(this, 0x01);
13.166 }
13.167
13.168 /**
13.169 @@ -747,10 +805,18 @@
13.170 * @since JDK1.1
13.171 */
13.172 public Method getMethod(String name, Class<?>... parameterTypes)
13.173 - throws SecurityException {
13.174 - Method m = Method.findMethod(this, name, parameterTypes);
13.175 + throws SecurityException, NoSuchMethodException {
13.176 + Method m = MethodImpl.findMethod(this, name, parameterTypes);
13.177 if (m == null) {
13.178 - throw new SecurityException(); // XXX: NoSuchMethodException
13.179 + StringBuilder sb = new StringBuilder();
13.180 + sb.append(getName()).append('.').append(name).append('(');
13.181 + String sep = "";
13.182 + for (int i = 0; i < parameterTypes.length; i++) {
13.183 + sb.append(sep).append(parameterTypes[i].getName());
13.184 + sep = ", ";
13.185 + }
13.186 + sb.append(')');
13.187 + throw new NoSuchMethodException(sb.toString());
13.188 }
13.189 return m;
13.190 }
13.191 @@ -832,13 +898,14 @@
13.192 */
13.193 public InputStream getResourceAsStream(String name) {
13.194 name = resolveName(name);
13.195 - ClassLoader cl = getClassLoader0();
13.196 - if (cl==null) {
13.197 - // A system class.
13.198 - return ClassLoader.getSystemResourceAsStream(name);
13.199 - }
13.200 - return cl.getResourceAsStream(name);
13.201 - }
13.202 + byte[] arr = getResourceAsStream0(name);
13.203 + return arr == null ? null : new ByteArrayInputStream(arr);
13.204 + }
13.205 +
13.206 + @JavaScriptBody(args = "name", body =
13.207 + "return (vm.loadBytes) ? vm.loadBytes(name) : null;"
13.208 + )
13.209 + private static native byte[] getResourceAsStream0(String name);
13.210
13.211 /**
13.212 * Finds a resource with a given name. The rules for searching resources
13.213 @@ -876,7 +943,7 @@
13.214 */
13.215 public java.net.URL getResource(String name) {
13.216 name = resolveName(name);
13.217 - ClassLoader cl = getClassLoader0();
13.218 + ClassLoader cl = null;
13.219 if (cl==null) {
13.220 // A system class.
13.221 return ClassLoader.getSystemResource(name);
13.222 @@ -940,9 +1007,6 @@
13.223 throw new SecurityException();
13.224 }
13.225
13.226 - // Package-private to allow ClassLoader access
13.227 - native ClassLoader getClassLoader0();
13.228 -
13.229 /**
13.230 * Returns the {@code Class} representing the component type of an
13.231 * array. If this class does not represent an array class this method
13.232 @@ -954,9 +1018,59 @@
13.233 * @since JDK1.1
13.234 */
13.235 public Class<?> getComponentType() {
13.236 + if (isArray()) {
13.237 + try {
13.238 + return getComponentType0();
13.239 + } catch (ClassNotFoundException cnfe) {
13.240 + throw new IllegalStateException(cnfe);
13.241 + }
13.242 + }
13.243 return null;
13.244 }
13.245
13.246 + private Class<?> getComponentType0() throws ClassNotFoundException {
13.247 + String n = getName().substring(1);
13.248 + switch (n.charAt(0)) {
13.249 + case 'L':
13.250 + n = n.substring(1, n.length() - 1);
13.251 + return Class.forName(n);
13.252 + case 'I':
13.253 + return Integer.TYPE;
13.254 + case 'J':
13.255 + return Long.TYPE;
13.256 + case 'D':
13.257 + return Double.TYPE;
13.258 + case 'F':
13.259 + return Float.TYPE;
13.260 + case 'B':
13.261 + return Byte.TYPE;
13.262 + case 'Z':
13.263 + return Boolean.TYPE;
13.264 + case 'S':
13.265 + return Short.TYPE;
13.266 + case 'V':
13.267 + return Void.TYPE;
13.268 + case 'C':
13.269 + return Character.TYPE;
13.270 + case '[':
13.271 + return defineArray(n);
13.272 + default:
13.273 + throw new ClassNotFoundException("Unknown component type of " + getName());
13.274 + }
13.275 + }
13.276 +
13.277 + @JavaScriptBody(args = { "sig" }, body =
13.278 + "var c = Array[sig];\n" +
13.279 + "if (c) return c;\n" +
13.280 + "c = vm.java_lang_Class(true);\n" +
13.281 + "c.jvmName = sig;\n" +
13.282 + "c.superclass = vm.java_lang_Object(false).$class;\n" +
13.283 + "c.array = true;\n" +
13.284 + "Array[sig] = c;\n" +
13.285 + "return c;"
13.286 + )
13.287 + private static native Class<?> defineArray(String sig);
13.288 +
13.289 /**
13.290 * Returns true if and only if this class was declared as an enum in the
13.291 * source code.
13.292 @@ -1022,10 +1136,10 @@
13.293 throw new ClassCastException(this.toString());
13.294 }
13.295
13.296 - @JavaScriptBody(args = { "self", "ac" },
13.297 + @JavaScriptBody(args = { "ac" },
13.298 body =
13.299 - "if (self.anno) {"
13.300 - + " return self.anno['L' + ac.jvmName + ';'];"
13.301 + "if (this.anno) {"
13.302 + + " return this.anno['L' + ac.jvmName + ';'];"
13.303 + "} else return null;"
13.304 )
13.305 private Object getAnnotationData(Class<?> annotationClass) {
13.306 @@ -1044,8 +1158,8 @@
13.307 * @throws NullPointerException {@inheritDoc}
13.308 * @since 1.5
13.309 */
13.310 - @JavaScriptBody(args = { "self", "ac" },
13.311 - body = "if (self.anno && self.anno['L' + ac.jvmName + ';']) { return true; }"
13.312 + @JavaScriptBody(args = { "ac" },
13.313 + body = "if (this.anno && this.anno['L' + ac.jvmName + ';']) { return true; }"
13.314 + "else return false;"
13.315 )
13.316 public boolean isAnnotationPresent(
13.317 @@ -1056,7 +1170,7 @@
13.318 return getAnnotation(annotationClass) != null;
13.319 }
13.320
13.321 - @JavaScriptBody(args = "self", body = "return self.anno;")
13.322 + @JavaScriptBody(args = {}, body = "return this.anno;")
13.323 private Object getAnnotationData() {
13.324 throw new UnsupportedOperationException();
13.325 }
13.326 @@ -1076,10 +1190,13 @@
13.327 throw new UnsupportedOperationException();
13.328 }
13.329
13.330 - static Class getPrimitiveClass(String type) {
13.331 - // XXX
13.332 - return Object.class;
13.333 - }
13.334 + @JavaScriptBody(args = "type", body = ""
13.335 + + "var c = vm.java_lang_Class(true);"
13.336 + + "c.jvmName = type;"
13.337 + + "c.primitive = true;"
13.338 + + "return c;"
13.339 + )
13.340 + native static Class getPrimitiveClass(String type);
13.341
13.342 public boolean desiredAssertionStatus() {
13.343 return false;
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/emul/src/main/java/java/lang/NoSuchMethodException.java Fri Jan 18 14:27:22 2013 +0100
14.3 @@ -0,0 +1,53 @@
14.4 +/*
14.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.7 + *
14.8 + * This code is free software; you can redistribute it and/or modify it
14.9 + * under the terms of the GNU General Public License version 2 only, as
14.10 + * published by the Free Software Foundation. Oracle designates this
14.11 + * particular file as subject to the "Classpath" exception as provided
14.12 + * by Oracle in the LICENSE file that accompanied this code.
14.13 + *
14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.17 + * version 2 for more details (a copy is included in the LICENSE file that
14.18 + * accompanied this code).
14.19 + *
14.20 + * You should have received a copy of the GNU General Public License version
14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.23 + *
14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
14.25 + * or visit www.oracle.com if you need additional information or have any
14.26 + * questions.
14.27 + */
14.28 +
14.29 +package java.lang;
14.30 +
14.31 +/**
14.32 + * Thrown when a particular method cannot be found.
14.33 + *
14.34 + * @author unascribed
14.35 + * @since JDK1.0
14.36 + */
14.37 +public
14.38 +class NoSuchMethodException extends ReflectiveOperationException {
14.39 + private static final long serialVersionUID = 5034388446362600923L;
14.40 +
14.41 + /**
14.42 + * Constructs a <code>NoSuchMethodException</code> without a detail message.
14.43 + */
14.44 + public NoSuchMethodException() {
14.45 + super();
14.46 + }
14.47 +
14.48 + /**
14.49 + * Constructs a <code>NoSuchMethodException</code> with a detail message.
14.50 + *
14.51 + * @param s the detail message.
14.52 + */
14.53 + public NoSuchMethodException(String s) {
14.54 + super(s);
14.55 + }
14.56 +}
15.1 --- a/emul/src/main/java/java/lang/Number.java Fri Jan 18 14:23:18 2013 +0100
15.2 +++ b/emul/src/main/java/java/lang/Number.java Fri Jan 18 14:27:22 2013 +0100
15.3 @@ -25,6 +25,8 @@
15.4
15.5 package java.lang;
15.6
15.7 +import org.apidesign.bck2brwsr.core.ExtraJavaScript;
15.8 +
15.9 /**
15.10 * The abstract class <code>Number</code> is the superclass of classes
15.11 * <code>BigDecimal</code>, <code>BigInteger</code>,
15.12 @@ -46,6 +48,10 @@
15.13 * @see java.lang.Short
15.14 * @since JDK1.0
15.15 */
15.16 +@ExtraJavaScript(
15.17 + resource="/org/apidesign/vm4brwsr/emul/java_lang_Number.js",
15.18 + processByteCode=true
15.19 +)
15.20 public abstract class Number implements java.io.Serializable {
15.21 /**
15.22 * Returns the value of the specified number as an <code>int</code>.
16.1 --- a/emul/src/main/java/java/lang/Object.java Fri Jan 18 14:23:18 2013 +0100
16.2 +++ b/emul/src/main/java/java/lang/Object.java Fri Jan 18 14:27:22 2013 +0100
16.3 @@ -66,7 +66,7 @@
16.4 * @see Class Literals, section 15.8.2 of
16.5 * <cite>The Java™ Language Specification</cite>.
16.6 */
16.7 - @JavaScriptBody(args="self", body="return self.constructor.$class;")
16.8 + @JavaScriptBody(args={}, body="return this.constructor.$class;")
16.9 public final native Class<?> getClass();
16.10
16.11 /**
16.12 @@ -104,8 +104,16 @@
16.13 * @see java.lang.Object#equals(java.lang.Object)
16.14 * @see java.lang.System#identityHashCode
16.15 */
16.16 + @JavaScriptBody(args = {}, body =
16.17 + "if (this.$hashCode) return this.$hashCode;\n"
16.18 + + "var h = this.computeHashCode__I();\n"
16.19 + + "return this.$hashCode = h & h;"
16.20 + )
16.21 public native int hashCode();
16.22
16.23 + @JavaScriptBody(args = {}, body = "Math.random() * Math.pow(2, 32);")
16.24 + native int computeHashCode();
16.25 +
16.26 /**
16.27 * Indicates whether some other object is "equal to" this one.
16.28 * <p>
16.29 @@ -216,7 +224,28 @@
16.30 * be cloned.
16.31 * @see java.lang.Cloneable
16.32 */
16.33 - protected native Object clone() throws CloneNotSupportedException;
16.34 + protected Object clone() throws CloneNotSupportedException {
16.35 + Object ret = clone(this);
16.36 + if (ret == null) {
16.37 + throw new CloneNotSupportedException(getClass().getName());
16.38 + }
16.39 + return ret;
16.40 + }
16.41 +
16.42 + @JavaScriptBody(args = "self", body =
16.43 + "\nif (!self.$instOf_java_lang_Cloneable) {"
16.44 + + "\n return null;"
16.45 + + "\n} else {"
16.46 + + "\n var clone = self.constructor(true);"
16.47 + + "\n var props = Object.getOwnPropertyNames(self);"
16.48 + + "\n for (var i = 0; i < props.length; i++) {"
16.49 + + "\n var p = props[i];"
16.50 + + "\n clone[p] = self[p];"
16.51 + + "\n };"
16.52 + + "\n return clone;"
16.53 + + "\n}"
16.54 + )
16.55 + private static native Object clone(Object self) throws CloneNotSupportedException;
16.56
16.57 /**
16.58 * Returns a string representation of the object. In general, the
17.1 --- a/emul/src/main/java/java/lang/String.java Fri Jan 18 14:23:18 2013 +0100
17.2 +++ b/emul/src/main/java/java/lang/String.java Fri Jan 18 14:27:22 2013 +0100
17.3 @@ -108,10 +108,6 @@
17.4 public final class String
17.5 implements java.io.Serializable, Comparable<String>, CharSequence
17.6 {
17.7 - @JavaScriptOnly
17.8 - /** Cache the hash code for the string */
17.9 - private int hash; // Default to 0
17.10 -
17.11 /** real string to delegate to */
17.12 private Object r;
17.13
17.14 @@ -173,11 +169,11 @@
17.15 * @param value
17.16 * The initial value of the string
17.17 */
17.18 - @JavaScriptBody(args = { "self", "charArr" }, body=
17.19 + @JavaScriptBody(args = { "charArr" }, body=
17.20 "for (var i = 0; i < charArr.length; i++) {\n"
17.21 + " if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n"
17.22 + "}\n"
17.23 - + "self.fld_r = charArr.join('');\n"
17.24 + + "this.fld_r = charArr.join('');\n"
17.25 )
17.26 public String(char value[]) {
17.27 }
17.28 @@ -203,12 +199,12 @@
17.29 * If the {@code offset} and {@code count} arguments index
17.30 * characters outside the bounds of the {@code value} array
17.31 */
17.32 - @JavaScriptBody(args = { "self", "charArr", "off", "cnt" }, body =
17.33 + @JavaScriptBody(args = { "charArr", "off", "cnt" }, body =
17.34 "var up = off + cnt;\n" +
17.35 "for (var i = off; i < up; i++) {\n" +
17.36 " if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n" +
17.37 "}\n" +
17.38 - "self.fld_r = charArr.slice(off, up).join(\"\");\n"
17.39 + "this.fld_r = charArr.slice(off, up).join(\"\");\n"
17.40 )
17.41 public String(char value[], int offset, int count) {
17.42 }
17.43 @@ -622,7 +618,7 @@
17.44 * @return the length of the sequence of characters represented by this
17.45 * object.
17.46 */
17.47 - @JavaScriptBody(args = "self", body = "return self.toString().length;")
17.48 + @JavaScriptBody(args = {}, body = "return this.toString().length;")
17.49 public int length() {
17.50 throw new UnsupportedOperationException();
17.51 }
17.52 @@ -635,7 +631,7 @@
17.53 *
17.54 * @since 1.6
17.55 */
17.56 - @JavaScriptBody(args = "self", body="return self.toString().length === 0;")
17.57 + @JavaScriptBody(args = {}, body="return this.toString().length === 0;")
17.58 public boolean isEmpty() {
17.59 return length() == 0;
17.60 }
17.61 @@ -658,8 +654,8 @@
17.62 * argument is negative or not less than the length of this
17.63 * string.
17.64 */
17.65 - @JavaScriptBody(args = { "self", "index" },
17.66 - body = "return self.toString().charCodeAt(index);"
17.67 + @JavaScriptBody(args = { "index" },
17.68 + body = "return this.toString().charCodeAt(index);"
17.69 )
17.70 public char charAt(int index) {
17.71 throw new UnsupportedOperationException();
17.72 @@ -784,8 +780,8 @@
17.73 * Copy characters from this string into dst starting at dstBegin.
17.74 * This method doesn't perform any range checking.
17.75 */
17.76 - @JavaScriptBody(args = { "self", "arr", "to" }, body =
17.77 - "var s = self.toString();\n" +
17.78 + @JavaScriptBody(args = { "arr", "to" }, body =
17.79 + "var s = this.toString();\n" +
17.80 "for (var i = 0; i < s.length; i++) {\n" +
17.81 " arr[to++] = s[i];\n" +
17.82 "}"
17.83 @@ -824,8 +820,8 @@
17.84 * <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
17.85 * <code>dst.length</code></ul>
17.86 */
17.87 - @JavaScriptBody(args = { "self", "beg", "end", "arr", "dst" }, body=
17.88 - "var s = self.toString();\n" +
17.89 + @JavaScriptBody(args = { "beg", "end", "arr", "dst" }, body=
17.90 + "var s = this.toString();\n" +
17.91 "while (beg < end) {\n" +
17.92 " arr[dst++] = s[beg++];\n" +
17.93 "}\n"
17.94 @@ -997,9 +993,9 @@
17.95 * @see #compareTo(String)
17.96 * @see #equalsIgnoreCase(String)
17.97 */
17.98 - @JavaScriptBody(args = { "self", "obj" }, body =
17.99 + @JavaScriptBody(args = { "obj" }, body =
17.100 "return obj.$instOf_java_lang_String && "
17.101 - + "self.toString() === obj.toString();"
17.102 + + "this.toString() === obj.toString();"
17.103 )
17.104 public boolean equals(Object anObject) {
17.105 if (this == anObject) {
17.106 @@ -1424,9 +1420,9 @@
17.107 * this.substring(toffset).startsWith(prefix)
17.108 * </pre>
17.109 */
17.110 - @JavaScriptBody(args = { "self", "find", "from" }, body=
17.111 + @JavaScriptBody(args = { "find", "from" }, body=
17.112 "find = find.toString();\n" +
17.113 - "return self.toString().substring(from, from + find.length) === find;\n"
17.114 + "return this.toString().substring(from, from + find.length) === find;\n"
17.115 )
17.116 public boolean startsWith(String prefix, int toffset) {
17.117 char ta[] = toCharArray();
17.118 @@ -1491,26 +1487,18 @@
17.119 *
17.120 * @return a hash code value for this object.
17.121 */
17.122 - @JavaScriptBody(args = "self", body =
17.123 - "var h = 0;\n" +
17.124 - "var s = self.toString();\n" +
17.125 - "for (var i = 0; i < s.length; i++) {\n" +
17.126 - " var high = (h >> 16) & 0xffff, low = h & 0xffff;\n" +
17.127 - " h = (((((31 * high) & 0xffff) << 16) >>> 0) + (31 * low) + s.charCodeAt(i)) & 0xffffffff;\n" +
17.128 - "}\n" +
17.129 - "return h;\n"
17.130 - )
17.131 public int hashCode() {
17.132 - int h = hash;
17.133 + return super.hashCode();
17.134 + }
17.135 + int computeHashCode() {
17.136 + int h = 0;
17.137 if (h == 0 && length() > 0) {
17.138 int off = offset();
17.139 - char val[] = toCharArray();
17.140 int len = length();
17.141
17.142 for (int i = 0; i < len; i++) {
17.143 - h = 31*h + val[off++];
17.144 + h = 31*h + charAt(off++);
17.145 }
17.146 - hash = h;
17.147 }
17.148 return h;
17.149 }
17.150 @@ -1582,9 +1570,9 @@
17.151 * than or equal to <code>fromIndex</code>, or <code>-1</code>
17.152 * if the character does not occur.
17.153 */
17.154 - @JavaScriptBody(args = { "self", "ch", "from" }, body =
17.155 + @JavaScriptBody(args = { "ch", "from" }, body =
17.156 "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" +
17.157 - "return self.toString().indexOf(ch, from);\n"
17.158 + "return this.toString().indexOf(ch, from);\n"
17.159 )
17.160 public int indexOf(int ch, int fromIndex) {
17.161 if (fromIndex < 0) {
17.162 @@ -1691,9 +1679,9 @@
17.163 * than or equal to <code>fromIndex</code>, or <code>-1</code>
17.164 * if the character does not occur before that point.
17.165 */
17.166 - @JavaScriptBody(args = { "self", "ch", "from" }, body =
17.167 + @JavaScriptBody(args = { "ch", "from" }, body =
17.168 "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" +
17.169 - "return self.toString().lastIndexOf(ch, from);"
17.170 + "return this.toString().lastIndexOf(ch, from);"
17.171 )
17.172 public int lastIndexOf(int ch, int fromIndex) {
17.173 if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
17.174 @@ -1766,63 +1754,10 @@
17.175 * starting at the specified index,
17.176 * or {@code -1} if there is no such occurrence.
17.177 */
17.178 - @JavaScriptBody(args = { "self", "str", "fromIndex" }, body =
17.179 - "return self.toString().indexOf(str.toString(), fromIndex);"
17.180 + @JavaScriptBody(args = { "str", "fromIndex" }, body =
17.181 + "return this.toString().indexOf(str.toString(), fromIndex);"
17.182 )
17.183 - public int indexOf(String str, int fromIndex) {
17.184 - return indexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
17.185 - }
17.186 -
17.187 - /**
17.188 - * Code shared by String and StringBuffer to do searches. The
17.189 - * source is the character array being searched, and the target
17.190 - * is the string being searched for.
17.191 - *
17.192 - * @param source the characters being searched.
17.193 - * @param sourceOffset offset of the source string.
17.194 - * @param sourceCount count of the source string.
17.195 - * @param target the characters being searched for.
17.196 - * @param targetOffset offset of the target string.
17.197 - * @param targetCount count of the target string.
17.198 - * @param fromIndex the index to begin searching from.
17.199 - */
17.200 - static int indexOf(char[] source, int sourceOffset, int sourceCount,
17.201 - char[] target, int targetOffset, int targetCount,
17.202 - int fromIndex) {
17.203 - if (fromIndex >= sourceCount) {
17.204 - return (targetCount == 0 ? sourceCount : -1);
17.205 - }
17.206 - if (fromIndex < 0) {
17.207 - fromIndex = 0;
17.208 - }
17.209 - if (targetCount == 0) {
17.210 - return fromIndex;
17.211 - }
17.212 -
17.213 - char first = target[targetOffset];
17.214 - int max = sourceOffset + (sourceCount - targetCount);
17.215 -
17.216 - for (int i = sourceOffset + fromIndex; i <= max; i++) {
17.217 - /* Look for first character. */
17.218 - if (source[i] != first) {
17.219 - while (++i <= max && source[i] != first);
17.220 - }
17.221 -
17.222 - /* Found first character, now look at the rest of v2 */
17.223 - if (i <= max) {
17.224 - int j = i + 1;
17.225 - int end = j + targetCount - 1;
17.226 - for (int k = targetOffset + 1; j < end && source[j] ==
17.227 - target[k]; j++, k++);
17.228 -
17.229 - if (j == end) {
17.230 - /* Found whole string. */
17.231 - return i - sourceOffset;
17.232 - }
17.233 - }
17.234 - }
17.235 - return -1;
17.236 - }
17.237 + public native int indexOf(String str, int fromIndex);
17.238
17.239 /**
17.240 * Returns the index within this string of the last occurrence of the
17.241 @@ -1859,8 +1794,8 @@
17.242 * searching backward from the specified index,
17.243 * or {@code -1} if there is no such occurrence.
17.244 */
17.245 - @JavaScriptBody(args = { "self", "s", "from" }, body =
17.246 - "return self.toString().lastIndexOf(s.toString(), from);"
17.247 + @JavaScriptBody(args = { "s", "from" }, body =
17.248 + "return this.toString().lastIndexOf(s.toString(), from);"
17.249 )
17.250 public int lastIndexOf(String str, int fromIndex) {
17.251 return lastIndexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
17.252 @@ -1968,8 +1903,8 @@
17.253 * <code>beginIndex</code> is larger than
17.254 * <code>endIndex</code>.
17.255 */
17.256 - @JavaScriptBody(args = { "self", "beginIndex", "endIndex" }, body =
17.257 - "return self.toString().substring(beginIndex, endIndex);"
17.258 + @JavaScriptBody(args = { "beginIndex", "endIndex" }, body =
17.259 + "return this.toString().substring(beginIndex, endIndex);"
17.260 )
17.261 public String substring(int beginIndex, int endIndex) {
17.262 if (beginIndex < 0) {
17.263 @@ -2077,10 +2012,10 @@
17.264 * @return a string derived from this string by replacing every
17.265 * occurrence of <code>oldChar</code> with <code>newChar</code>.
17.266 */
17.267 - @JavaScriptBody(args = { "self", "arg1", "arg2" }, body =
17.268 + @JavaScriptBody(args = { "arg1", "arg2" }, body =
17.269 "if (typeof arg1 === 'number') arg1 = String.fromCharCode(arg1);\n" +
17.270 "if (typeof arg2 === 'number') arg2 = String.fromCharCode(arg2);\n" +
17.271 - "var s = self.toString();\n" +
17.272 + "var s = this.toString();\n" +
17.273 "for (;;) {\n" +
17.274 " var ret = s.replace(arg1, arg2);\n" +
17.275 " if (ret === s) {\n" +
17.276 @@ -2143,6 +2078,12 @@
17.277 * @since 1.4
17.278 * @spec JSR-51
17.279 */
17.280 + @JavaScriptBody(args = { "regex" }, body =
17.281 + "var self = this.toString();\n"
17.282 + + "var re = new RegExp(regex.toString());\n"
17.283 + + "var r = re.exec(self);\n"
17.284 + + "return r != null && r.length > 0 && self.length == r[0].length;"
17.285 + )
17.286 public boolean matches(String regex) {
17.287 throw new UnsupportedOperationException();
17.288 }
17.289 @@ -2555,6 +2496,7 @@
17.290 * @return the <code>String</code>, converted to lowercase.
17.291 * @see java.lang.String#toLowerCase(Locale)
17.292 */
17.293 + @JavaScriptBody(args = {}, body = "return this.toLowerCase();")
17.294 public String toLowerCase() {
17.295 throw new UnsupportedOperationException("Should be supported but without connection to locale");
17.296 }
17.297 @@ -2720,6 +2662,7 @@
17.298 * @return the <code>String</code>, converted to uppercase.
17.299 * @see java.lang.String#toUpperCase(Locale)
17.300 */
17.301 + @JavaScriptBody(args = {}, body = "return this.toUpperCase();")
17.302 public String toUpperCase() {
17.303 throw new UnsupportedOperationException();
17.304 }
17.305 @@ -2775,7 +2718,7 @@
17.306 *
17.307 * @return the string itself.
17.308 */
17.309 - @JavaScriptBody(args = "self", body = "return self.toString();")
17.310 + @JavaScriptBody(args = {}, body = "return this.toString();")
17.311 public String toString() {
17.312 return this;
17.313 }
17.314 @@ -2787,7 +2730,6 @@
17.315 * of this string and whose contents are initialized to contain
17.316 * the character sequence represented by this string.
17.317 */
17.318 - @JavaScriptBody(args = "self", body = "return self.toString().split('');")
17.319 public char[] toCharArray() {
17.320 char result[] = new char[length()];
17.321 getChars(0, length(), result, 0);
18.1 --- a/emul/src/main/java/java/lang/StringBuffer.java Fri Jan 18 14:23:18 2013 +0100
18.2 +++ b/emul/src/main/java/java/lang/StringBuffer.java Fri Jan 18 14:27:22 2013 +0100
18.3 @@ -527,8 +527,7 @@
18.4 * @since 1.4
18.5 */
18.6 public synchronized int indexOf(String str, int fromIndex) {
18.7 - return String.indexOf(value, 0, count,
18.8 - str.toCharArray(), 0, str.length(), fromIndex);
18.9 + return super.indexOf(str, fromIndex);
18.10 }
18.11
18.12 /**
19.1 --- a/emul/src/main/java/java/lang/StringBuilder.java Fri Jan 18 14:23:18 2013 +0100
19.2 +++ b/emul/src/main/java/java/lang/StringBuilder.java Fri Jan 18 14:27:22 2013 +0100
19.3 @@ -376,8 +376,7 @@
19.4 * @throws NullPointerException {@inheritDoc}
19.5 */
19.6 public int indexOf(String str, int fromIndex) {
19.7 - return String.indexOf(value, 0, count,
19.8 - str.toCharArray(), 0, str.length(), fromIndex);
19.9 + return super.indexOf(str, fromIndex);
19.10 }
19.11
19.12 /**
20.1 --- a/emul/src/main/java/java/lang/Throwable.java Fri Jan 18 14:23:18 2013 +0100
20.2 +++ b/emul/src/main/java/java/lang/Throwable.java Fri Jan 18 14:27:22 2013 +0100
20.3 @@ -783,7 +783,7 @@
20.4 return this;
20.5 }
20.6
20.7 - @JavaScriptBody(args = { "self", "dummy" }, body = "")
20.8 + @JavaScriptBody(args = { "dummy" }, body = "")
20.9 private native Throwable fillInStackTrace(int dummy);
20.10
20.11 /**
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/emul/src/main/java/java/lang/Void.java Fri Jan 18 14:27:22 2013 +0100
21.3 @@ -0,0 +1,49 @@
21.4 +/*
21.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.7 + *
21.8 + * This code is free software; you can redistribute it and/or modify it
21.9 + * under the terms of the GNU General Public License version 2 only, as
21.10 + * published by the Free Software Foundation. Oracle designates this
21.11 + * particular file as subject to the "Classpath" exception as provided
21.12 + * by Oracle in the LICENSE file that accompanied this code.
21.13 + *
21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21.17 + * version 2 for more details (a copy is included in the LICENSE file that
21.18 + * accompanied this code).
21.19 + *
21.20 + * You should have received a copy of the GNU General Public License version
21.21 + * 2 along with this work; if not, write to the Free Software Foundation,
21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21.23 + *
21.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21.25 + * or visit www.oracle.com if you need additional information or have any
21.26 + * questions.
21.27 + */
21.28 +
21.29 +package java.lang;
21.30 +
21.31 +/**
21.32 + * The {@code Void} class is an uninstantiable placeholder class to hold a
21.33 + * reference to the {@code Class} object representing the Java keyword
21.34 + * void.
21.35 + *
21.36 + * @author unascribed
21.37 + * @since JDK1.1
21.38 + */
21.39 +public final
21.40 +class Void {
21.41 +
21.42 + /**
21.43 + * The {@code Class} object representing the pseudo-type corresponding to
21.44 + * the keyword {@code void}.
21.45 + */
21.46 + public static final Class<Void> TYPE = Class.getPrimitiveClass("void");
21.47 +
21.48 + /*
21.49 + * The Void class cannot be instantiated.
21.50 + */
21.51 + private Void() {}
21.52 +}
22.1 --- a/emul/src/main/java/java/lang/reflect/Method.java Fri Jan 18 14:23:18 2013 +0100
22.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java Fri Jan 18 14:27:22 2013 +0100
22.3 @@ -26,8 +26,10 @@
22.4 package java.lang.reflect;
22.5
22.6 import java.lang.annotation.Annotation;
22.7 +import java.util.Enumeration;
22.8 import org.apidesign.bck2brwsr.core.JavaScriptBody;
22.9 import org.apidesign.bck2brwsr.emul.AnnotationImpl;
22.10 +import org.apidesign.bck2brwsr.emul.MethodImpl;
22.11
22.12 /**
22.13 * A {@code Method} provides information about, and access to, a single method
22.14 @@ -56,7 +58,6 @@
22.15 private final String name;
22.16 private final Object data;
22.17 private final String sig;
22.18 - private int modifiers;
22.19
22.20 // Generics infrastructure
22.21
22.22 @@ -108,9 +109,12 @@
22.23 * @see Modifier
22.24 */
22.25 public int getModifiers() {
22.26 - return modifiers;
22.27 + return getAccess(data);
22.28 }
22.29 -
22.30 +
22.31 + @JavaScriptBody(args = "self", body = "return self.access;")
22.32 + private static native int getAccess(Object self);
22.33 +
22.34 /**
22.35 * Returns an array of {@code TypeVariable} objects that represent the
22.36 * type variables declared by the generic declaration represented by this
22.37 @@ -137,7 +141,7 @@
22.38 * @return the return type for the method this object represents
22.39 */
22.40 public Class<?> getReturnType() {
22.41 - throw new UnsupportedOperationException();
22.42 + return MethodImpl.signatureParser(sig).nextElement();
22.43 }
22.44
22.45 /**
22.46 @@ -179,8 +183,13 @@
22.47 * represents
22.48 */
22.49 public Class<?>[] getParameterTypes() {
22.50 - throw new UnsupportedOperationException();
22.51 - //return (Class<?>[]) parameterTypes.clone();
22.52 + Class[] arr = new Class[MethodImpl.signatureElements(sig) - 1];
22.53 + Enumeration<Class> en = MethodImpl.signatureParser(sig);
22.54 + en.nextElement(); // return type
22.55 + for (int i = 0; i < arr.length; i++) {
22.56 + arr[i] = en.nextElement();
22.57 + }
22.58 + return arr;
22.59 }
22.60
22.61 /**
22.62 @@ -311,14 +320,14 @@
22.63 sb.append(Field.getTypeName(getReturnType())).append(' ');
22.64 sb.append(Field.getTypeName(getDeclaringClass())).append('.');
22.65 sb.append(getName()).append('(');
22.66 - /*
22.67 - Class<?>[] params = parameterTypes; // avoid clone
22.68 + Class<?>[] params = getParameterTypes(); // avoid clone
22.69 for (int j = 0; j < params.length; j++) {
22.70 sb.append(Field.getTypeName(params[j]));
22.71 if (j < (params.length - 1))
22.72 sb.append(',');
22.73 }
22.74 sb.append(')');
22.75 + /*
22.76 Class<?>[] exceptions = exceptionTypes; // avoid clone
22.77 if (exceptions.length > 0) {
22.78 sb.append(" throws ");
22.79 @@ -488,17 +497,118 @@
22.80 * @exception ExceptionInInitializerError if the initialization
22.81 * provoked by this method fails.
22.82 */
22.83 - @JavaScriptBody(args = { "method", "self", "args" }, body =
22.84 - "if (args.length > 0) throw 'unsupported now';"
22.85 - + "return method.fld_data(self);"
22.86 - )
22.87 public Object invoke(Object obj, Object... args)
22.88 throws IllegalAccessException, IllegalArgumentException,
22.89 InvocationTargetException
22.90 {
22.91 - throw new UnsupportedOperationException();
22.92 + final boolean isStatic = (getModifiers() & Modifier.STATIC) == 0;
22.93 + if (isStatic && obj == null) {
22.94 + throw new NullPointerException();
22.95 + }
22.96 + Class[] types = getParameterTypes();
22.97 + if (types.length != args.length) {
22.98 + throw new IllegalArgumentException("Types len " + types.length + " args: " + args.length);
22.99 + } else {
22.100 + args = args.clone();
22.101 + for (int i = 0; i < types.length; i++) {
22.102 + Class c = types[i];
22.103 + if (c.isPrimitive()) {
22.104 + args[i] = toPrimitive(c, args[i]);
22.105 + }
22.106 + }
22.107 + }
22.108 + Object res = invoke0(isStatic, this, obj, args);
22.109 + if (getReturnType().isPrimitive()) {
22.110 + res = fromPrimitive(getReturnType(), res);
22.111 + }
22.112 + return res;
22.113 }
22.114 +
22.115 + @JavaScriptBody(args = { "st", "method", "self", "args" }, body =
22.116 + "var p;\n"
22.117 + + "if (st) {\n"
22.118 + + " p = new Array(1);\n"
22.119 + + " p[0] = self;\n"
22.120 + + " p = p.concat(args);\n"
22.121 + + "} else {\n"
22.122 + + " p = args;\n"
22.123 + + "}\n"
22.124 + + "return method.fld_data.apply(self, p);\n"
22.125 + )
22.126 + private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
22.127
22.128 + private static Object fromPrimitive(Class<?> type, Object o) {
22.129 + if (type == Integer.TYPE) {
22.130 + return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
22.131 + }
22.132 + if (type == Long.TYPE) {
22.133 + return fromRaw(Long.class, "valueOf__Ljava_lang_Long_2J", o);
22.134 + }
22.135 + if (type == Double.TYPE) {
22.136 + return fromRaw(Double.class, "valueOf__Ljava_lang_Double_2D", o);
22.137 + }
22.138 + if (type == Float.TYPE) {
22.139 + return fromRaw(Float.class, "valueOf__Ljava_lang_Float_2F", o);
22.140 + }
22.141 + if (type == Byte.TYPE) {
22.142 + return fromRaw(Byte.class, "valueOf__Ljava_lang_Byte_2B", o);
22.143 + }
22.144 + if (type == Boolean.TYPE) {
22.145 + return fromRaw(Boolean.class, "valueOf__Ljava_lang_Boolean_2Z", o);
22.146 + }
22.147 + if (type == Short.TYPE) {
22.148 + return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
22.149 + }
22.150 + if (type == Character.TYPE) {
22.151 + return fromRaw(Character.class, "valueOf__Ljava_lang_Character_2C", o);
22.152 + }
22.153 + if (type.getName().equals("void")) {
22.154 + return null;
22.155 + }
22.156 + throw new IllegalStateException("Can't convert " + o);
22.157 + }
22.158 +
22.159 + @JavaScriptBody(args = { "cls", "m", "o" },
22.160 + body = "return cls.cnstr(false)[m](o);"
22.161 + )
22.162 + private static native Integer fromRaw(Class<?> cls, String m, Object o);
22.163 +
22.164 + private static Object toPrimitive(Class<?> type, Object o) {
22.165 + if (type == Integer.TYPE) {
22.166 + return toRaw("intValue__I", o);
22.167 + }
22.168 + if (type == Long.TYPE) {
22.169 + return toRaw("longValue__J", o);
22.170 + }
22.171 + if (type == Double.TYPE) {
22.172 + return toRaw("doubleValue__D", o);
22.173 + }
22.174 + if (type == Float.TYPE) {
22.175 + return toRaw("floatValue__F", o);
22.176 + }
22.177 + if (type == Byte.TYPE) {
22.178 + return toRaw("byteValue__B", o);
22.179 + }
22.180 + if (type == Boolean.TYPE) {
22.181 + return toRaw("booleanValue__Z", o);
22.182 + }
22.183 + if (type == Short.TYPE) {
22.184 + return toRaw("shortValue__S", o);
22.185 + }
22.186 + if (type == Character.TYPE) {
22.187 + return toRaw("charValue__C", o);
22.188 + }
22.189 + if (type.getName().equals("void")) {
22.190 + return o;
22.191 + }
22.192 + throw new IllegalStateException("Can't convert " + o);
22.193 + }
22.194 +
22.195 + @JavaScriptBody(args = { "m", "o" },
22.196 + body = "return o[m](o);"
22.197 + )
22.198 + private static native Object toRaw(String m, Object o);
22.199 +
22.200 /**
22.201 * Returns {@code true} if this method is a bridge
22.202 * method; returns {@code false} otherwise.
22.203 @@ -536,10 +646,10 @@
22.204 return Modifier.isSynthetic(getModifiers());
22.205 }
22.206
22.207 - @JavaScriptBody(args = { "self", "ac" },
22.208 + @JavaScriptBody(args = { "ac" },
22.209 body =
22.210 - "if (self.fld_data.anno) {"
22.211 - + " return self.fld_data.anno['L' + ac.jvmName + ';'];"
22.212 + "if (this.fld_data.anno) {"
22.213 + + " return this.fld_data.anno['L' + ac.jvmName + ';'];"
22.214 + "} else return null;"
22.215 )
22.216 private Object getAnnotationData(Class<?> annotationClass) {
22.217 @@ -599,57 +709,12 @@
22.218 public Annotation[][] getParameterAnnotations() {
22.219 throw new UnsupportedOperationException();
22.220 }
22.221 -
22.222 - //
22.223 - // bck2brwsr implementation
22.224 - //
22.225
22.226 - @JavaScriptBody(args = { "clazz", "prefix" },
22.227 - body = ""
22.228 - + "var c = clazz.cnstr.prototype;"
22.229 - + "var arr = new Array();\n"
22.230 - + "for (m in c) {\n"
22.231 - + " if (m.indexOf(prefix) === 0) {\n"
22.232 - + " arr.push(m);\n"
22.233 - + " arr.push(c[m]);\n"
22.234 - + " }"
22.235 - + "}\n"
22.236 - + "return arr;"
22.237 - )
22.238 - private static native Object[] findMethodData(
22.239 - Class<?> clazz, String prefix
22.240 - );
22.241 -
22.242 - // XXX should not be public
22.243 - public static Method findMethod(
22.244 - Class<?> clazz, String name, Class<?>... parameterTypes
22.245 - ) {
22.246 - Object[] data = findMethodData(clazz, name + "__");
22.247 - if (data.length == 0) {
22.248 - return null;
22.249 - }
22.250 - String sig = ((String)data[0]).substring(name.length() + 2);
22.251 - return new Method(clazz, name, data[1], sig);
22.252 - }
22.253 -
22.254 - public static Method[] findMethods(Class<?> clazz) {
22.255 - Object[] namesAndData = findMethodData(clazz, "");
22.256 - int cnt = 0;
22.257 - for (int i = 0; i < namesAndData.length; i += 2) {
22.258 - String sig = (String) namesAndData[i];
22.259 - Object data = namesAndData[i + 1];
22.260 - int middle = sig.indexOf("__");
22.261 - if (middle == -1) {
22.262 - continue;
22.263 + static {
22.264 + MethodImpl.INSTANCE = new MethodImpl() {
22.265 + protected Method create(Class<?> declaringClass, String name, Object data, String sig) {
22.266 + return new Method(declaringClass, name, data, sig);
22.267 }
22.268 - String name = sig.substring(0, middle);
22.269 - sig = sig.substring(middle + 2);
22.270 - namesAndData[cnt++] = new Method(clazz, name, data, sig);
22.271 - }
22.272 - Method[] arr = new Method[cnt];
22.273 - for (int i = 0; i < cnt; i++) {
22.274 - arr[i] = (Method)namesAndData[i];
22.275 - }
22.276 - return arr;
22.277 + };
22.278 }
22.279 }
23.1 --- a/emul/src/main/java/java/net/URL.java Fri Jan 18 14:23:18 2013 +0100
23.2 +++ b/emul/src/main/java/java/net/URL.java Fri Jan 18 14:27:22 2013 +0100
23.3 @@ -27,6 +27,7 @@
23.4
23.5 import java.io.IOException;
23.6 import java.io.InputStream;
23.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
23.8
23.9 /**
23.10 * Class <code>URL</code> represents a Uniform Resource
23.11 @@ -196,6 +197,17 @@
23.12 */
23.13 private String ref;
23.14
23.15 + /**
23.16 + * The host's IP address, used in equals and hashCode.
23.17 + * Computed on demand. An uninitialized or unknown hostAddress is null.
23.18 + */
23.19 + transient Object hostAddress;
23.20 +
23.21 + /**
23.22 + * The URLStreamHandler for this URL.
23.23 + */
23.24 + transient URLStreamHandler handler;
23.25 +
23.26 /* Our hash code.
23.27 * @serial
23.28 */
23.29 @@ -308,8 +320,47 @@
23.30 this(protocol, host, -1, file);
23.31 }
23.32
23.33 - private URL(String protocol, String host, int port, String file,
23.34 - Object handler) throws MalformedURLException {
23.35 + /**
23.36 + * Creates a <code>URL</code> object from the specified
23.37 + * <code>protocol</code>, <code>host</code>, <code>port</code>
23.38 + * number, <code>file</code>, and <code>handler</code>. Specifying
23.39 + * a <code>port</code> number of <code>-1</code> indicates that
23.40 + * the URL should use the default port for the protocol. Specifying
23.41 + * a <code>handler</code> of <code>null</code> indicates that the URL
23.42 + * should use a default stream handler for the protocol, as outlined
23.43 + * for:
23.44 + * java.net.URL#URL(java.lang.String, java.lang.String, int,
23.45 + * java.lang.String)
23.46 + *
23.47 + * <p>If the handler is not null and there is a security manager,
23.48 + * the security manager's <code>checkPermission</code>
23.49 + * method is called with a
23.50 + * <code>NetPermission("specifyStreamHandler")</code> permission.
23.51 + * This may result in a SecurityException.
23.52 + *
23.53 + * No validation of the inputs is performed by this constructor.
23.54 + *
23.55 + * @param protocol the name of the protocol to use.
23.56 + * @param host the name of the host.
23.57 + * @param port the port number on the host.
23.58 + * @param file the file on the host
23.59 + * @param handler the stream handler for the URL.
23.60 + * @exception MalformedURLException if an unknown protocol is specified.
23.61 + * @exception SecurityException
23.62 + * if a security manager exists and its
23.63 + * <code>checkPermission</code> method doesn't allow
23.64 + * specifying a stream handler explicitly.
23.65 + * @see java.lang.System#getProperty(java.lang.String)
23.66 + * @see java.net.URL#setURLStreamHandlerFactory(
23.67 + * java.net.URLStreamHandlerFactory)
23.68 + * @see java.net.URLStreamHandler
23.69 + * @see java.net.URLStreamHandlerFactory#createURLStreamHandler(
23.70 + * java.lang.String)
23.71 + * @see SecurityManager#checkPermission
23.72 + * @see java.net.NetPermission
23.73 + */
23.74 + public URL(String protocol, String host, int port, String file,
23.75 + URLStreamHandler handler) throws MalformedURLException {
23.76 if (handler != null) {
23.77 throw new SecurityException();
23.78 }
23.79 @@ -348,10 +399,11 @@
23.80
23.81 // Note: we don't do validation of the URL here. Too risky to change
23.82 // right now, but worth considering for future reference. -br
23.83 -// if (handler == null &&
23.84 -// (handler = getURLStreamHandler(protocol)) == null) {
23.85 -// throw new MalformedURLException("unknown protocol: " + protocol);
23.86 -// }
23.87 + if (handler == null &&
23.88 + (handler = getURLStreamHandler(protocol)) == null) {
23.89 + throw new MalformedURLException("unknown protocol: " + protocol);
23.90 + }
23.91 + this.handler = handler;
23.92 }
23.93
23.94 /**
23.95 @@ -441,7 +493,7 @@
23.96 * @see java.net.URLStreamHandler#parseURL(java.net.URL,
23.97 * java.lang.String, int, int)
23.98 */
23.99 - private URL(URL context, String spec, Object handler)
23.100 + public URL(URL context, String spec, URLStreamHandler handler)
23.101 throws MalformedURLException
23.102 {
23.103 String original = spec;
23.104 @@ -494,9 +546,9 @@
23.105 newProtocol.equalsIgnoreCase(context.protocol))) {
23.106 // inherit the protocol handler from the context
23.107 // if not specified to the constructor
23.108 -// if (handler == null) {
23.109 -// handler = context.handler;
23.110 -// }
23.111 + if (handler == null) {
23.112 + handler = context.handler;
23.113 + }
23.114
23.115 // If the context is a hierarchical URL scheme and the spec
23.116 // contains a matching scheme then maintain backwards
23.117 @@ -523,15 +575,15 @@
23.118
23.119 // Get the protocol handler if not specified or the protocol
23.120 // of the context could not be used
23.121 -// if (handler == null &&
23.122 -// (handler = getURLStreamHandler(protocol)) == null) {
23.123 -// throw new MalformedURLException("unknown protocol: "+protocol);
23.124 -// }
23.125 -
23.126 -// this.handler = handler;
23.127 + if (handler == null &&
23.128 + (handler = getURLStreamHandler(protocol)) == null) {
23.129 + throw new MalformedURLException("unknown protocol: "+protocol);
23.130 + }
23.131 + this.handler = handler;
23.132
23.133 i = spec.indexOf('#', start);
23.134 if (i >= 0) {
23.135 +//thrw(protocol + " hnd: " + handler.getClass().getName() + " i: " + i);
23.136 ref = spec.substring(i + 1, limit);
23.137 limit = i;
23.138 }
23.139 @@ -547,7 +599,7 @@
23.140 }
23.141 }
23.142
23.143 -// handler.parseURL(this, spec, start, limit);
23.144 + handler.parseURL(this, spec, start, limit);
23.145
23.146 } catch(MalformedURLException e) {
23.147 throw e;
23.148 @@ -557,7 +609,7 @@
23.149 throw exception;
23.150 }
23.151 }
23.152 -
23.153 +
23.154 /*
23.155 * Returns true if specified string is a valid protocol name.
23.156 */
23.157 @@ -601,6 +653,7 @@
23.158 /* This is very important. We must recompute this after the
23.159 * URL has been changed. */
23.160 hashCode = -1;
23.161 + hostAddress = null;
23.162 int q = file.lastIndexOf('?');
23.163 if (q != -1) {
23.164 query = file.substring(q+1);
23.165 @@ -639,6 +692,7 @@
23.166 /* This is very important. We must recompute this after the
23.167 * URL has been changed. */
23.168 hashCode = -1;
23.169 + hostAddress = null;
23.170 this.query = query;
23.171 this.authority = authority;
23.172 }
23.173 @@ -697,6 +751,19 @@
23.174 }
23.175
23.176 /**
23.177 + * Gets the default port number of the protocol associated
23.178 + * with this <code>URL</code>. If the URL scheme or the URLStreamHandler
23.179 + * for the URL do not define a default port number,
23.180 + * then -1 is returned.
23.181 + *
23.182 + * @return the port number
23.183 + * @since 1.4
23.184 + */
23.185 + public int getDefaultPort() {
23.186 + return handler.getDefaultPort();
23.187 + }
23.188 +
23.189 + /**
23.190 * Gets the protocol name of this <code>URL</code>.
23.191 *
23.192 * @return the protocol of this <code>URL</code>.
23.193 @@ -773,8 +840,7 @@
23.194 return false;
23.195 URL u2 = (URL)obj;
23.196
23.197 - // return handler.equals(this, u2);
23.198 - return u2 == this;
23.199 + return handler.equals(this, u2);
23.200 }
23.201
23.202 /**
23.203 @@ -789,7 +855,7 @@
23.204 if (hashCode != -1)
23.205 return hashCode;
23.206
23.207 - // hashCode = handler.hashCode(this);
23.208 + hashCode = handler.hashCode(this);
23.209 return hashCode;
23.210 }
23.211
23.212 @@ -805,8 +871,7 @@
23.213 * <code>false</code> otherwise.
23.214 */
23.215 public boolean sameFile(URL other) {
23.216 -// return handler.sameFile(this, other);
23.217 - throw new UnsupportedOperationException();
23.218 + return handler.sameFile(this, other);
23.219 }
23.220
23.221 /**
23.222 @@ -834,8 +899,7 @@
23.223 * @see java.net.URLStreamHandler#toExternalForm(java.net.URL)
23.224 */
23.225 public String toExternalForm() {
23.226 - throw new UnsupportedOperationException();
23.227 -// return handler.toExternalForm(this);
23.228 + return handler.toExternalForm(this);
23.229 }
23.230
23.231 /**
23.232 @@ -901,9 +965,16 @@
23.233 * @see java.net.URLConnection#getContent()
23.234 */
23.235 public final Object getContent() throws java.io.IOException {
23.236 - throw new IOException();
23.237 -// return openConnection().getContent();
23.238 + return loadText(toExternalForm());
23.239 }
23.240 +
23.241 + @JavaScriptBody(args = "url", body = ""
23.242 + + "var request = new XMLHttpRequest();\n"
23.243 + + "request.open('GET', url, false);\n"
23.244 + + "request.send();\n"
23.245 + + "return request.responseText;\n"
23.246 + )
23.247 + private static native String loadText(String url) throws IOException;
23.248
23.249 /**
23.250 * Gets the contents of this URL. This method is a shorthand for:
23.251 @@ -921,10 +992,18 @@
23.252 */
23.253 public final Object getContent(Class[] classes)
23.254 throws java.io.IOException {
23.255 - throw new IOException();
23.256 -// return openConnection().getContent(classes);
23.257 + for (Class<?> c : classes) {
23.258 + if (c == String.class) {
23.259 + return getContent();
23.260 + }
23.261 + }
23.262 + return null;
23.263 }
23.264
23.265 + static URLStreamHandler getURLStreamHandler(String protocol) {
23.266 + URLStreamHandler universal = new URLStreamHandler() {};
23.267 + return universal;
23.268 + }
23.269
23.270 }
23.271
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/emul/src/main/java/java/net/URLStreamHandler.java Fri Jan 18 14:27:22 2013 +0100
24.3 @@ -0,0 +1,568 @@
24.4 +/*
24.5 + * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
24.7 + *
24.8 + * This code is free software; you can redistribute it and/or modify it
24.9 + * under the terms of the GNU General Public License version 2 only, as
24.10 + * published by the Free Software Foundation. Oracle designates this
24.11 + * particular file as subject to the "Classpath" exception as provided
24.12 + * by Oracle in the LICENSE file that accompanied this code.
24.13 + *
24.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
24.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24.17 + * version 2 for more details (a copy is included in the LICENSE file that
24.18 + * accompanied this code).
24.19 + *
24.20 + * You should have received a copy of the GNU General Public License version
24.21 + * 2 along with this work; if not, write to the Free Software Foundation,
24.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24.23 + *
24.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
24.25 + * or visit www.oracle.com if you need additional information or have any
24.26 + * questions.
24.27 + */
24.28 +
24.29 +package java.net;
24.30 +
24.31 +
24.32 +/**
24.33 + * The abstract class <code>URLStreamHandler</code> is the common
24.34 + * superclass for all stream protocol handlers. A stream protocol
24.35 + * handler knows how to make a connection for a particular protocol
24.36 + * type, such as <code>http</code>, <code>ftp</code>, or
24.37 + * <code>gopher</code>.
24.38 + * <p>
24.39 + * In most cases, an instance of a <code>URLStreamHandler</code>
24.40 + * subclass is not created directly by an application. Rather, the
24.41 + * first time a protocol name is encountered when constructing a
24.42 + * <code>URL</code>, the appropriate stream protocol handler is
24.43 + * automatically loaded.
24.44 + *
24.45 + * @author James Gosling
24.46 + * @see java.net.URL#URL(java.lang.String, java.lang.String, int, java.lang.String)
24.47 + * @since JDK1.0
24.48 + */
24.49 +public abstract class URLStreamHandler {
24.50 + /**
24.51 + * Opens a connection to the object referenced by the
24.52 + * <code>URL</code> argument.
24.53 + * This method should be overridden by a subclass.
24.54 + *
24.55 + * <p>If for the handler's protocol (such as HTTP or JAR), there
24.56 + * exists a public, specialized URLConnection subclass belonging
24.57 + * to one of the following packages or one of their subpackages:
24.58 + * java.lang, java.io, java.util, java.net, the connection
24.59 + * returned will be of that subclass. For example, for HTTP an
24.60 + * HttpURLConnection will be returned, and for JAR a
24.61 + * JarURLConnection will be returned.
24.62 + *
24.63 + * @param u the URL that this connects to.
24.64 + * @return a <code>URLConnection</code> object for the <code>URL</code>.
24.65 + * @exception IOException if an I/O error occurs while opening the
24.66 + * connection.
24.67 + */
24.68 +// abstract protected URLConnection openConnection(URL u) throws IOException;
24.69 +
24.70 + /**
24.71 + * Same as openConnection(URL), except that the connection will be
24.72 + * made through the specified proxy; Protocol handlers that do not
24.73 + * support proxying will ignore the proxy parameter and make a
24.74 + * normal connection.
24.75 + *
24.76 + * Calling this method preempts the system's default ProxySelector
24.77 + * settings.
24.78 + *
24.79 + * @param u the URL that this connects to.
24.80 + * @param p the proxy through which the connection will be made.
24.81 + * If direct connection is desired, Proxy.NO_PROXY
24.82 + * should be specified.
24.83 + * @return a <code>URLConnection</code> object for the <code>URL</code>.
24.84 + * @exception IOException if an I/O error occurs while opening the
24.85 + * connection.
24.86 + * @exception IllegalArgumentException if either u or p is null,
24.87 + * or p has the wrong type.
24.88 + * @exception UnsupportedOperationException if the subclass that
24.89 + * implements the protocol doesn't support this method.
24.90 + * @since 1.5
24.91 + */
24.92 +// protected URLConnection openConnection(URL u, Proxy p) throws IOException {
24.93 +// throw new UnsupportedOperationException("Method not implemented.");
24.94 +// }
24.95 +
24.96 + /**
24.97 + * Parses the string representation of a <code>URL</code> into a
24.98 + * <code>URL</code> object.
24.99 + * <p>
24.100 + * If there is any inherited context, then it has already been
24.101 + * copied into the <code>URL</code> argument.
24.102 + * <p>
24.103 + * The <code>parseURL</code> method of <code>URLStreamHandler</code>
24.104 + * parses the string representation as if it were an
24.105 + * <code>http</code> specification. Most URL protocol families have a
24.106 + * similar parsing. A stream protocol handler for a protocol that has
24.107 + * a different syntax must override this routine.
24.108 + *
24.109 + * @param u the <code>URL</code> to receive the result of parsing
24.110 + * the spec.
24.111 + * @param spec the <code>String</code> representing the URL that
24.112 + * must be parsed.
24.113 + * @param start the character index at which to begin parsing. This is
24.114 + * just past the '<code>:</code>' (if there is one) that
24.115 + * specifies the determination of the protocol name.
24.116 + * @param limit the character position to stop parsing at. This is the
24.117 + * end of the string or the position of the
24.118 + * "<code>#</code>" character, if present. All information
24.119 + * after the sharp sign indicates an anchor.
24.120 + */
24.121 + protected void parseURL(URL u, String spec, int start, int limit) {
24.122 + // These fields may receive context content if this was relative URL
24.123 + String protocol = u.getProtocol();
24.124 + String authority = u.getAuthority();
24.125 + String userInfo = u.getUserInfo();
24.126 + String host = u.getHost();
24.127 + int port = u.getPort();
24.128 + String path = u.getPath();
24.129 + String query = u.getQuery();
24.130 +
24.131 + // This field has already been parsed
24.132 + String ref = u.getRef();
24.133 +
24.134 + boolean isRelPath = false;
24.135 + boolean queryOnly = false;
24.136 +
24.137 +// FIX: should not assume query if opaque
24.138 + // Strip off the query part
24.139 + if (start < limit) {
24.140 + int queryStart = spec.indexOf('?');
24.141 + queryOnly = queryStart == start;
24.142 + if ((queryStart != -1) && (queryStart < limit)) {
24.143 + query = spec.substring(queryStart+1, limit);
24.144 + if (limit > queryStart)
24.145 + limit = queryStart;
24.146 + spec = spec.substring(0, queryStart);
24.147 + }
24.148 + }
24.149 +
24.150 + int i = 0;
24.151 + // Parse the authority part if any
24.152 + boolean isUNCName = (start <= limit - 4) &&
24.153 + (spec.charAt(start) == '/') &&
24.154 + (spec.charAt(start + 1) == '/') &&
24.155 + (spec.charAt(start + 2) == '/') &&
24.156 + (spec.charAt(start + 3) == '/');
24.157 + if (!isUNCName && (start <= limit - 2) && (spec.charAt(start) == '/') &&
24.158 + (spec.charAt(start + 1) == '/')) {
24.159 + start += 2;
24.160 + i = spec.indexOf('/', start);
24.161 + if (i < 0) {
24.162 + i = spec.indexOf('?', start);
24.163 + if (i < 0)
24.164 + i = limit;
24.165 + }
24.166 +
24.167 + host = authority = spec.substring(start, i);
24.168 +
24.169 + int ind = authority.indexOf('@');
24.170 + if (ind != -1) {
24.171 + userInfo = authority.substring(0, ind);
24.172 + host = authority.substring(ind+1);
24.173 + } else {
24.174 + userInfo = null;
24.175 + }
24.176 + if (host != null) {
24.177 + // If the host is surrounded by [ and ] then its an IPv6
24.178 + // literal address as specified in RFC2732
24.179 + if (host.length()>0 && (host.charAt(0) == '[')) {
24.180 + if ((ind = host.indexOf(']')) > 2) {
24.181 +
24.182 + String nhost = host ;
24.183 + host = nhost.substring(0,ind+1);
24.184 +// if (!IPAddressUtil.
24.185 +// isIPv6LiteralAddress(host.substring(1, ind))) {
24.186 +// throw new IllegalArgumentException(
24.187 +// "Invalid host: "+ host);
24.188 +// }
24.189 +
24.190 + port = -1 ;
24.191 + if (nhost.length() > ind+1) {
24.192 + if (nhost.charAt(ind+1) == ':') {
24.193 + ++ind ;
24.194 + // port can be null according to RFC2396
24.195 + if (nhost.length() > (ind + 1)) {
24.196 + port = Integer.parseInt(nhost.substring(ind+1));
24.197 + }
24.198 + } else {
24.199 + throw new IllegalArgumentException(
24.200 + "Invalid authority field: " + authority);
24.201 + }
24.202 + }
24.203 + } else {
24.204 + throw new IllegalArgumentException(
24.205 + "Invalid authority field: " + authority);
24.206 + }
24.207 + } else {
24.208 + ind = host.indexOf(':');
24.209 + port = -1;
24.210 + if (ind >= 0) {
24.211 + // port can be null according to RFC2396
24.212 + if (host.length() > (ind + 1)) {
24.213 + port = Integer.parseInt(host.substring(ind + 1));
24.214 + }
24.215 + host = host.substring(0, ind);
24.216 + }
24.217 + }
24.218 + } else {
24.219 + host = "";
24.220 + }
24.221 + if (port < -1)
24.222 + throw new IllegalArgumentException("Invalid port number :" +
24.223 + port);
24.224 + start = i;
24.225 + // If the authority is defined then the path is defined by the
24.226 + // spec only; See RFC 2396 Section 5.2.4.
24.227 + if (authority != null && authority.length() > 0)
24.228 + path = "";
24.229 + }
24.230 +
24.231 + if (host == null) {
24.232 + host = "";
24.233 + }
24.234 +
24.235 + // Parse the file path if any
24.236 + if (start < limit) {
24.237 + if (spec.charAt(start) == '/') {
24.238 + path = spec.substring(start, limit);
24.239 + } else if (path != null && path.length() > 0) {
24.240 + isRelPath = true;
24.241 + int ind = path.lastIndexOf('/');
24.242 + String seperator = "";
24.243 + if (ind == -1 && authority != null)
24.244 + seperator = "/";
24.245 + path = path.substring(0, ind + 1) + seperator +
24.246 + spec.substring(start, limit);
24.247 +
24.248 + } else {
24.249 + String seperator = (authority != null) ? "/" : "";
24.250 + path = seperator + spec.substring(start, limit);
24.251 + }
24.252 + } else if (queryOnly && path != null) {
24.253 + int ind = path.lastIndexOf('/');
24.254 + if (ind < 0)
24.255 + ind = 0;
24.256 + path = path.substring(0, ind) + "/";
24.257 + }
24.258 + if (path == null)
24.259 + path = "";
24.260 +
24.261 + if (isRelPath) {
24.262 + // Remove embedded /./
24.263 + while ((i = path.indexOf("/./")) >= 0) {
24.264 + path = path.substring(0, i) + path.substring(i + 2);
24.265 + }
24.266 + // Remove embedded /../ if possible
24.267 + i = 0;
24.268 + while ((i = path.indexOf("/../", i)) >= 0) {
24.269 + /*
24.270 + * A "/../" will cancel the previous segment and itself,
24.271 + * unless that segment is a "/../" itself
24.272 + * i.e. "/a/b/../c" becomes "/a/c"
24.273 + * but "/../../a" should stay unchanged
24.274 + */
24.275 + if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
24.276 + (path.indexOf("/../", limit) != 0)) {
24.277 + path = path.substring(0, limit) + path.substring(i + 3);
24.278 + i = 0;
24.279 + } else {
24.280 + i = i + 3;
24.281 + }
24.282 + }
24.283 + // Remove trailing .. if possible
24.284 + while (path.endsWith("/..")) {
24.285 + i = path.indexOf("/..");
24.286 + if ((limit = path.lastIndexOf('/', i - 1)) >= 0) {
24.287 + path = path.substring(0, limit+1);
24.288 + } else {
24.289 + break;
24.290 + }
24.291 + }
24.292 + // Remove starting .
24.293 + if (path.startsWith("./") && path.length() > 2)
24.294 + path = path.substring(2);
24.295 +
24.296 + // Remove trailing .
24.297 + if (path.endsWith("/."))
24.298 + path = path.substring(0, path.length() -1);
24.299 + }
24.300 +
24.301 + setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
24.302 + }
24.303 +
24.304 + /**
24.305 + * Returns the default port for a URL parsed by this handler. This method
24.306 + * is meant to be overidden by handlers with default port numbers.
24.307 + * @return the default port for a <code>URL</code> parsed by this handler.
24.308 + * @since 1.3
24.309 + */
24.310 + protected int getDefaultPort() {
24.311 + return -1;
24.312 + }
24.313 +
24.314 + /**
24.315 + * Provides the default equals calculation. May be overidden by handlers
24.316 + * for other protocols that have different requirements for equals().
24.317 + * This method requires that none of its arguments is null. This is
24.318 + * guaranteed by the fact that it is only called by java.net.URL class.
24.319 + * @param u1 a URL object
24.320 + * @param u2 a URL object
24.321 + * @return <tt>true</tt> if the two urls are
24.322 + * considered equal, ie. they refer to the same
24.323 + * fragment in the same file.
24.324 + * @since 1.3
24.325 + */
24.326 + protected boolean equals(URL u1, URL u2) {
24.327 + String ref1 = u1.getRef();
24.328 + String ref2 = u2.getRef();
24.329 + return (ref1 == ref2 || (ref1 != null && ref1.equals(ref2))) &&
24.330 + sameFile(u1, u2);
24.331 + }
24.332 +
24.333 + /**
24.334 + * Provides the default hash calculation. May be overidden by handlers for
24.335 + * other protocols that have different requirements for hashCode
24.336 + * calculation.
24.337 + * @param u a URL object
24.338 + * @return an <tt>int</tt> suitable for hash table indexing
24.339 + * @since 1.3
24.340 + */
24.341 + protected int hashCode(URL u) {
24.342 + int h = 0;
24.343 +
24.344 + // Generate the protocol part.
24.345 + String protocol = u.getProtocol();
24.346 + if (protocol != null)
24.347 + h += protocol.hashCode();
24.348 +
24.349 + // Generate the host part.
24.350 + Object addr = getHostAddress(u);
24.351 + if (addr != null) {
24.352 + h += addr.hashCode();
24.353 + } else {
24.354 + String host = u.getHost();
24.355 + if (host != null)
24.356 + h += host.toLowerCase().hashCode();
24.357 + }
24.358 +
24.359 + // Generate the file part.
24.360 + String file = u.getFile();
24.361 + if (file != null)
24.362 + h += file.hashCode();
24.363 +
24.364 + // Generate the port part.
24.365 + if (u.getPort() == -1)
24.366 + h += getDefaultPort();
24.367 + else
24.368 + h += u.getPort();
24.369 +
24.370 + // Generate the ref part.
24.371 + String ref = u.getRef();
24.372 + if (ref != null)
24.373 + h += ref.hashCode();
24.374 +
24.375 + return h;
24.376 + }
24.377 +
24.378 + /**
24.379 + * Compare two urls to see whether they refer to the same file,
24.380 + * i.e., having the same protocol, host, port, and path.
24.381 + * This method requires that none of its arguments is null. This is
24.382 + * guaranteed by the fact that it is only called indirectly
24.383 + * by java.net.URL class.
24.384 + * @param u1 a URL object
24.385 + * @param u2 a URL object
24.386 + * @return true if u1 and u2 refer to the same file
24.387 + * @since 1.3
24.388 + */
24.389 + protected boolean sameFile(URL u1, URL u2) {
24.390 + // Compare the protocols.
24.391 + if (!((u1.getProtocol() == u2.getProtocol()) ||
24.392 + (u1.getProtocol() != null &&
24.393 + u1.getProtocol().equalsIgnoreCase(u2.getProtocol()))))
24.394 + return false;
24.395 +
24.396 + // Compare the files.
24.397 + if (!(u1.getFile() == u2.getFile() ||
24.398 + (u1.getFile() != null && u1.getFile().equals(u2.getFile()))))
24.399 + return false;
24.400 +
24.401 + // Compare the ports.
24.402 + int port1, port2;
24.403 + port1 = (u1.getPort() != -1) ? u1.getPort() : u1.handler.getDefaultPort();
24.404 + port2 = (u2.getPort() != -1) ? u2.getPort() : u2.handler.getDefaultPort();
24.405 + if (port1 != port2)
24.406 + return false;
24.407 +
24.408 + // Compare the hosts.
24.409 + if (!hostsEqual(u1, u2))
24.410 + return false;
24.411 +
24.412 + return true;
24.413 + }
24.414 +
24.415 + /**
24.416 + * Get the IP address of our host. An empty host field or a DNS failure
24.417 + * will result in a null return.
24.418 + *
24.419 + * @param u a URL object
24.420 + * @return an <code>InetAddress</code> representing the host
24.421 + * IP address.
24.422 + * @since 1.3
24.423 + */
24.424 + private synchronized Object getHostAddress(URL u) {
24.425 + return u.hostAddress;
24.426 + }
24.427 +
24.428 + /**
24.429 + * Compares the host components of two URLs.
24.430 + * @param u1 the URL of the first host to compare
24.431 + * @param u2 the URL of the second host to compare
24.432 + * @return <tt>true</tt> if and only if they
24.433 + * are equal, <tt>false</tt> otherwise.
24.434 + * @since 1.3
24.435 + */
24.436 + protected boolean hostsEqual(URL u1, URL u2) {
24.437 + Object a1 = getHostAddress(u1);
24.438 + Object a2 = getHostAddress(u2);
24.439 + // if we have internet address for both, compare them
24.440 + if (a1 != null && a2 != null) {
24.441 + return a1.equals(a2);
24.442 + // else, if both have host names, compare them
24.443 + } else if (u1.getHost() != null && u2.getHost() != null)
24.444 + return u1.getHost().equalsIgnoreCase(u2.getHost());
24.445 + else
24.446 + return u1.getHost() == null && u2.getHost() == null;
24.447 + }
24.448 +
24.449 + /**
24.450 + * Converts a <code>URL</code> of a specific protocol to a
24.451 + * <code>String</code>.
24.452 + *
24.453 + * @param u the URL.
24.454 + * @return a string representation of the <code>URL</code> argument.
24.455 + */
24.456 + protected String toExternalForm(URL u) {
24.457 +
24.458 + // pre-compute length of StringBuffer
24.459 + int len = u.getProtocol().length() + 1;
24.460 + if (u.getAuthority() != null && u.getAuthority().length() > 0)
24.461 + len += 2 + u.getAuthority().length();
24.462 + if (u.getPath() != null) {
24.463 + len += u.getPath().length();
24.464 + }
24.465 + if (u.getQuery() != null) {
24.466 + len += 1 + u.getQuery().length();
24.467 + }
24.468 + if (u.getRef() != null)
24.469 + len += 1 + u.getRef().length();
24.470 +
24.471 + StringBuffer result = new StringBuffer(len);
24.472 + result.append(u.getProtocol());
24.473 + result.append(":");
24.474 + if (u.getAuthority() != null && u.getAuthority().length() > 0) {
24.475 + result.append("//");
24.476 + result.append(u.getAuthority());
24.477 + }
24.478 + if (u.getPath() != null) {
24.479 + result.append(u.getPath());
24.480 + }
24.481 + if (u.getQuery() != null) {
24.482 + result.append('?');
24.483 + result.append(u.getQuery());
24.484 + }
24.485 + if (u.getRef() != null) {
24.486 + result.append("#");
24.487 + result.append(u.getRef());
24.488 + }
24.489 + return result.toString();
24.490 + }
24.491 +
24.492 + /**
24.493 + * Sets the fields of the <code>URL</code> argument to the indicated values.
24.494 + * Only classes derived from URLStreamHandler are supposed to be able
24.495 + * to call the set method on a URL.
24.496 + *
24.497 + * @param u the URL to modify.
24.498 + * @param protocol the protocol name.
24.499 + * @param host the remote host value for the URL.
24.500 + * @param port the port on the remote machine.
24.501 + * @param authority the authority part for the URL.
24.502 + * @param userInfo the userInfo part of the URL.
24.503 + * @param path the path component of the URL.
24.504 + * @param query the query part for the URL.
24.505 + * @param ref the reference.
24.506 + * @exception SecurityException if the protocol handler of the URL is
24.507 + * different from this one
24.508 + * @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
24.509 + * @since 1.3
24.510 + */
24.511 + protected void setURL(URL u, String protocol, String host, int port,
24.512 + String authority, String userInfo, String path,
24.513 + String query, String ref) {
24.514 + if (this != u.handler) {
24.515 + throw new SecurityException("handler for url different from " +
24.516 + "this handler");
24.517 + }
24.518 + // ensure that no one can reset the protocol on a given URL.
24.519 + u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);
24.520 + }
24.521 +
24.522 + /**
24.523 + * Sets the fields of the <code>URL</code> argument to the indicated values.
24.524 + * Only classes derived from URLStreamHandler are supposed to be able
24.525 + * to call the set method on a URL.
24.526 + *
24.527 + * @param u the URL to modify.
24.528 + * @param protocol the protocol name. This value is ignored since 1.2.
24.529 + * @param host the remote host value for the URL.
24.530 + * @param port the port on the remote machine.
24.531 + * @param file the file.
24.532 + * @param ref the reference.
24.533 + * @exception SecurityException if the protocol handler of the URL is
24.534 + * different from this one
24.535 + * @deprecated Use setURL(URL, String, String, int, String, String, String,
24.536 + * String);
24.537 + */
24.538 + @Deprecated
24.539 + protected void setURL(URL u, String protocol, String host, int port,
24.540 + String file, String ref) {
24.541 + /*
24.542 + * Only old URL handlers call this, so assume that the host
24.543 + * field might contain "user:passwd@host". Fix as necessary.
24.544 + */
24.545 + String authority = null;
24.546 + String userInfo = null;
24.547 + if (host != null && host.length() != 0) {
24.548 + authority = (port == -1) ? host : host + ":" + port;
24.549 + int at = host.lastIndexOf('@');
24.550 + if (at != -1) {
24.551 + userInfo = host.substring(0, at);
24.552 + host = host.substring(at+1);
24.553 + }
24.554 + }
24.555 +
24.556 + /*
24.557 + * Assume file might contain query part. Fix as necessary.
24.558 + */
24.559 + String path = null;
24.560 + String query = null;
24.561 + if (file != null) {
24.562 + int q = file.lastIndexOf('?');
24.563 + if (q != -1) {
24.564 + query = file.substring(q+1);
24.565 + path = file.substring(0, q);
24.566 + } else
24.567 + path = file;
24.568 + }
24.569 + setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
24.570 + }
24.571 +}
25.1 --- a/emul/src/main/java/org/apidesign/bck2brwsr/emul/AnnotationImpl.java Fri Jan 18 14:23:18 2013 +0100
25.2 +++ b/emul/src/main/java/org/apidesign/bck2brwsr/emul/AnnotationImpl.java Fri Jan 18 14:27:22 2013 +0100
25.3 @@ -1,6 +1,19 @@
25.4 -/*
25.5 - * To change this template, choose Tools | Templates
25.6 - * and open the template in the editor.
25.7 +/**
25.8 + * Back 2 Browser Bytecode Translator
25.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
25.10 + *
25.11 + * This program is free software: you can redistribute it and/or modify
25.12 + * it under the terms of the GNU General Public License as published by
25.13 + * the Free Software Foundation, version 2 of the License.
25.14 + *
25.15 + * This program is distributed in the hope that it will be useful,
25.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25.18 + * GNU General Public License for more details.
25.19 + *
25.20 + * You should have received a copy of the GNU General Public License
25.21 + * along with this program. Look for COPYING file in the top folder.
25.22 + * If not, see http://opensource.org/licenses/GPL-2.0.
25.23 */
25.24 package org.apidesign.bck2brwsr.emul;
25.25
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/emul/src/main/java/org/apidesign/bck2brwsr/emul/MethodImpl.java Fri Jan 18 14:27:22 2013 +0100
26.3 @@ -0,0 +1,164 @@
26.4 +/*
26.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
26.7 + *
26.8 + * This code is free software; you can redistribute it and/or modify it
26.9 + * under the terms of the GNU General Public License version 2 only, as
26.10 + * published by the Free Software Foundation. Oracle designates this
26.11 + * particular file as subject to the "Classpath" exception as provided
26.12 + * by Oracle in the LICENSE file that accompanied this code.
26.13 + *
26.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
26.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26.17 + * version 2 for more details (a copy is included in the LICENSE file that
26.18 + * accompanied this code).
26.19 + *
26.20 + * You should have received a copy of the GNU General Public License version
26.21 + * 2 along with this work; if not, write to the Free Software Foundation,
26.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26.23 + *
26.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
26.25 + * or visit www.oracle.com if you need additional information or have any
26.26 + * questions.
26.27 + */
26.28 +package org.apidesign.bck2brwsr.emul;
26.29 +
26.30 +import java.lang.reflect.Method;
26.31 +import java.util.Enumeration;
26.32 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
26.33 +
26.34 +/** Utilities to work on methods.
26.35 + *
26.36 + * @author Jaroslav Tulach <jtulach@netbeans.org>
26.37 + */
26.38 +public abstract class MethodImpl {
26.39 + public static MethodImpl INSTANCE;
26.40 + static {
26.41 + try {
26.42 + Class.forName(Method.class.getName());
26.43 + } catch (ClassNotFoundException ex) {
26.44 + throw new IllegalStateException(ex);
26.45 + }
26.46 + }
26.47 +
26.48 + protected abstract Method create(Class<?> declaringClass, String name, Object data, String sig);
26.49 +
26.50 +
26.51 + //
26.52 + // bck2brwsr implementation
26.53 + //
26.54 +
26.55 + @JavaScriptBody(args = {"clazz", "prefix"},
26.56 + body = ""
26.57 + + "var c = clazz.cnstr.prototype;"
26.58 + + "var arr = new Array();\n"
26.59 + + "for (m in c) {\n"
26.60 + + " if (m.indexOf(prefix) === 0) {\n"
26.61 + + " arr.push(m);\n"
26.62 + + " arr.push(c[m]);\n"
26.63 + + " }"
26.64 + + "}\n"
26.65 + + "return arr;")
26.66 + private static native Object[] findMethodData(
26.67 + Class<?> clazz, String prefix);
26.68 +
26.69 + public static Method findMethod(
26.70 + Class<?> clazz, String name, Class<?>... parameterTypes) {
26.71 + Object[] data = findMethodData(clazz, name + "__");
26.72 + BIG: for (int i = 0; i < data.length; i += 2) {
26.73 + String sig = ((String) data[0]).substring(name.length() + 2);
26.74 + Method tmp = INSTANCE.create(clazz, name, data[1], sig);
26.75 + Class<?>[] tmpParms = tmp.getParameterTypes();
26.76 + if (parameterTypes.length != tmpParms.length) {
26.77 + continue;
26.78 + }
26.79 + for (int j = 0; j < tmpParms.length; j++) {
26.80 + if (!parameterTypes[j].equals(tmpParms[j])) {
26.81 + continue BIG;
26.82 + }
26.83 + }
26.84 + return tmp;
26.85 + }
26.86 + return null;
26.87 + }
26.88 +
26.89 + public static Method[] findMethods(Class<?> clazz, int mask) {
26.90 + Object[] namesAndData = findMethodData(clazz, "");
26.91 + int cnt = 0;
26.92 + for (int i = 0; i < namesAndData.length; i += 2) {
26.93 + String sig = (String) namesAndData[i];
26.94 + Object data = namesAndData[i + 1];
26.95 + int middle = sig.indexOf("__");
26.96 + if (middle == -1) {
26.97 + continue;
26.98 + }
26.99 + String name = sig.substring(0, middle);
26.100 + sig = sig.substring(middle + 2);
26.101 + final Method m = INSTANCE.create(clazz, name, data, sig);
26.102 + if ((m.getModifiers() & mask) == 0) {
26.103 + continue;
26.104 + }
26.105 + namesAndData[cnt++] = m;
26.106 + }
26.107 + Method[] arr = new Method[cnt];
26.108 + for (int i = 0; i < cnt; i++) {
26.109 + arr[i] = (Method) namesAndData[i];
26.110 + }
26.111 + return arr;
26.112 + }
26.113 +
26.114 + public static int signatureElements(String sig) {
26.115 + Enumeration<Class> en = signatureParser(sig);
26.116 + int cnt = 0;
26.117 + while (en.hasMoreElements()) {
26.118 + en.nextElement();
26.119 + cnt++;
26.120 + }
26.121 + return cnt;
26.122 + }
26.123 +
26.124 + public static Enumeration<Class> signatureParser(final String sig) {
26.125 + class E implements Enumeration<Class> {
26.126 + int pos;
26.127 +
26.128 + public boolean hasMoreElements() {
26.129 + return pos < sig.length();
26.130 + }
26.131 +
26.132 + public Class nextElement() {
26.133 + switch (sig.charAt(pos++)) {
26.134 + case 'I':
26.135 + return Integer.TYPE;
26.136 + case 'J':
26.137 + return Long.TYPE;
26.138 + case 'D':
26.139 + return Double.TYPE;
26.140 + case 'F':
26.141 + return Float.TYPE;
26.142 + case 'B':
26.143 + return Byte.TYPE;
26.144 + case 'Z':
26.145 + return Boolean.TYPE;
26.146 + case 'S':
26.147 + return Short.TYPE;
26.148 + case 'V':
26.149 + return Void.TYPE;
26.150 + case 'C':
26.151 + return Character.TYPE;
26.152 + case 'L':
26.153 + try {
26.154 + int up = sig.indexOf("_2");
26.155 + String type = sig.substring(1, up);
26.156 + pos = up + 2;
26.157 + return Class.forName(type);
26.158 + } catch (ClassNotFoundException ex) {
26.159 + // should not happen
26.160 + }
26.161 + }
26.162 + throw new UnsupportedOperationException(sig + " at " + pos);
26.163 + }
26.164 + }
26.165 + return new E();
26.166 + }
26.167 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_Number.js Fri Jan 18 14:27:22 2013 +0100
27.3 @@ -0,0 +1,9 @@
27.4 +// empty line needed here
27.5 +Number.prototype.add32 = function(x) { return (this + x) | 0; };
27.6 +Number.prototype.sub32 = function(x) { return (this - x) | 0; };
27.7 +Number.prototype.mul32 = function(x) {
27.8 + return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
27.9 +};
27.10 +
27.11 +Number.prototype.toInt8 = function() { return (this << 24) >> 24; };
27.12 +Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
27.13 \ No newline at end of file
28.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Fri Jan 18 14:23:18 2013 +0100
28.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js Fri Jan 18 14:27:22 2013 +0100
28.3 @@ -2,8 +2,30 @@
28.4 vm.java_lang_String(false);
28.5
28.6 // we need initialized arrays
28.7 -Array.prototype.fillNulls = function() {
28.8 - for(var i = 0; i < this.length; i++) this[i] = null;
28.9 +Array.prototype.initWith = function(sig, value) {
28.10 + for(var i = 0; i < this.length; i++) this[i] = value;
28.11 + this.jvmName = sig;
28.12 return this;
28.13 };
28.14 -
28.15 +Array.prototype.at = function(indx, value) {
28.16 + if (indx < 0 || indx > this.length) {
28.17 + var e = vm.java_lang_ArrayIndexOutOfBoundsException(true);
28.18 + e.constructor.cons__VLjava_lang_String_2.call(e, indx.toString());
28.19 + throw e;
28.20 + }
28.21 + if (arguments.length === 2) {
28.22 + this[indx] = value;
28.23 + }
28.24 + return this[indx];
28.25 +};
28.26 +Array.prototype.getClass__Ljava_lang_Class_2 = function() {
28.27 + return vm.java_lang_Class(false).defineArray__Ljava_lang_Class_2Ljava_lang_String_2(this.jvmName);
28.28 +};
28.29 +Array.prototype.clone__Ljava_lang_Object_2 = function() {
28.30 + var s = this.length;
28.31 + var ret = new Array(s);
28.32 + for (var i = 0; i < s; i++) {
28.33 + ret[i] = this[i];
28.34 + }
28.35 + return ret;
28.36 +};
29.1 --- a/javap/src/main/java/org/apidesign/javap/ClassData.java Fri Jan 18 14:23:18 2013 +0100
29.2 +++ b/javap/src/main/java/org/apidesign/javap/ClassData.java Fri Jan 18 14:27:22 2013 +0100
29.3 @@ -326,6 +326,10 @@
29.4 return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
29.5 }
29.6 }
29.7 +
29.8 + public int getAccessFlags() {
29.9 + return access;
29.10 + }
29.11
29.12 /**
29.13 * Returns true if it is a class
30.1 --- a/javap/src/main/java/org/apidesign/javap/Hashtable.java Fri Jan 18 14:23:18 2013 +0100
30.2 +++ b/javap/src/main/java/org/apidesign/javap/Hashtable.java Fri Jan 18 14:27:22 2013 +0100
30.3 @@ -1,11 +1,22 @@
30.4 -/*
30.5 - * To change this template, choose Tools | Templates
30.6 - * and open the template in the editor.
30.7 +/**
30.8 + * Back 2 Browser Bytecode Translator
30.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
30.10 + *
30.11 + * This program is free software: you can redistribute it and/or modify
30.12 + * it under the terms of the GNU General Public License as published by
30.13 + * the Free Software Foundation, version 2 of the License.
30.14 + *
30.15 + * This program is distributed in the hope that it will be useful,
30.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.18 + * GNU General Public License for more details.
30.19 + *
30.20 + * You should have received a copy of the GNU General Public License
30.21 + * along with this program. Look for COPYING file in the top folder.
30.22 + * If not, see http://opensource.org/licenses/GPL-2.0.
30.23 */
30.24 package org.apidesign.javap;
30.25
30.26 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
30.27 -
30.28 /** A JavaScript optimized replacement for Hashtable.
30.29 *
30.30 * @author Jaroslav Tulach <jtulach@netbeans.org>
30.31 @@ -25,9 +36,6 @@
30.32 Hashtable() {
30.33 }
30.34
30.35 - @JavaScriptBody(args = { "self", "key", "val" }, body =
30.36 - "self[key] = val;"
30.37 - )
30.38 synchronized void put(Object key, Object val) {
30.39 int[] where = { -1, -1 };
30.40 Object found = get(key, where);
30.41 @@ -61,9 +69,6 @@
30.42 }
30.43 }
30.44
30.45 - @JavaScriptBody(args = {"self", "key" }, body =
30.46 - "return self[key];"
30.47 - )
30.48 Object get(Object key) {
30.49 return get(key, null);
30.50 }
31.1 --- a/javap/src/main/java/org/apidesign/javap/MethodData.java Fri Jan 18 14:23:18 2013 +0100
31.2 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java Fri Jan 18 14:27:22 2013 +0100
31.3 @@ -25,9 +25,9 @@
31.4
31.5 package org.apidesign.javap;
31.6
31.7 -import java.io.*;
31.8 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
31.9
31.10 +import java.io.DataInputStream;
31.11 +import java.io.IOException;
31.12 import static org.apidesign.javap.RuntimeConstants.*;
31.13
31.14 /**
31.15 @@ -235,22 +235,8 @@
31.16 /**
31.17 * Return access of the method.
31.18 */
31.19 - public String[] getAccess(){
31.20 -
31.21 - Vector v = new Vector();
31.22 - if ((access & ACC_PUBLIC) !=0) v.addElement("public");
31.23 - if ((access & ACC_PRIVATE) !=0) v.addElement("private");
31.24 - if ((access & ACC_PROTECTED) !=0) v.addElement("protected");
31.25 - if ((access & ACC_STATIC) !=0) v.addElement("static");
31.26 - if ((access & ACC_FINAL) !=0) v.addElement("final");
31.27 - if ((access & ACC_SYNCHRONIZED) !=0) v.addElement("synchronized");
31.28 - if ((access & ACC_NATIVE) !=0) v.addElement("native");
31.29 - if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
31.30 - if ((access & ACC_STRICT) !=0) v.addElement("strictfp");
31.31 -
31.32 - String[] accflags = new String[v.size()];
31.33 - v.copyInto(accflags);
31.34 - return accflags;
31.35 + public int getAccess(){
31.36 + return access;
31.37 }
31.38
31.39 /**
31.40 @@ -357,10 +343,10 @@
31.41 /**
31.42 * Return exception table in code attributre.
31.43 */
31.44 - public Vector getexception_table(){
31.45 - return exception_table;
31.46 + public TrapDataIterator getTrapDataIterator(){
31.47 + return new TrapDataIterator(exception_table);
31.48 }
31.49 -
31.50 +
31.51
31.52 /**
31.53 * Return method attributes.
31.54 @@ -401,4 +387,8 @@
31.55 attrs.copyInto(arr);
31.56 return ClassData.findAttr(n, arr);
31.57 }
31.58 +
31.59 + public boolean isConstructor() {
31.60 + return "<init>".equals(getName());
31.61 + }
31.62 }
32.1 --- a/javap/src/main/java/org/apidesign/javap/TrapData.java Fri Jan 18 14:23:18 2013 +0100
32.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapData.java Fri Jan 18 14:27:22 2013 +0100
32.3 @@ -26,7 +26,6 @@
32.4
32.5 package org.apidesign.javap;
32.6
32.7 -import java.util.*;
32.8 import java.io.*;
32.9
32.10 /**
32.11 @@ -34,15 +33,18 @@
32.12 *
32.13 * @author Sucheta Dambalkar (Adopted code from jdis)
32.14 */
32.15 -class TrapData {
32.16 - short start_pc, end_pc, handler_pc, catch_cpx;
32.17 - int num;
32.18 +public final class TrapData {
32.19 + public final short start_pc;
32.20 + public final short end_pc;
32.21 + public final short handler_pc;
32.22 + public final short catch_cpx;
32.23 + final int num;
32.24
32.25
32.26 /**
32.27 * Read and store exception table data in code attribute.
32.28 */
32.29 - public TrapData(DataInputStream in, int num) throws IOException {
32.30 + TrapData(DataInputStream in, int num) throws IOException {
32.31 this.num=num;
32.32 start_pc = in.readShort();
32.33 end_pc=in.readShort();
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java Fri Jan 18 14:27:22 2013 +0100
33.3 @@ -0,0 +1,114 @@
33.4 +/**
33.5 + * Back 2 Browser Bytecode Translator
33.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
33.7 + *
33.8 + * This program is free software: you can redistribute it and/or modify
33.9 + * it under the terms of the GNU General Public License as published by
33.10 + * the Free Software Foundation, version 2 of the License.
33.11 + *
33.12 + * This program is distributed in the hope that it will be useful,
33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33.15 + * GNU General Public License for more details.
33.16 + *
33.17 + * You should have received a copy of the GNU General Public License
33.18 + * along with this program. Look for COPYING file in the top folder.
33.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
33.20 + */
33.21 +package org.apidesign.javap;
33.22 +
33.23 +/**
33.24 + *
33.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
33.26 + */
33.27 +public final class TrapDataIterator {
33.28 + private final Hashtable exStart = new Hashtable();
33.29 + private final Hashtable exStop = new Hashtable();
33.30 + private TrapData[] current = new TrapData[10];
33.31 + private int currentCount;
33.32 +
33.33 + TrapDataIterator(Vector exceptionTable) {
33.34 + for (int i=0 ; i < exceptionTable.size(); i++) {
33.35 + final TrapData td = (TrapData)exceptionTable.elementAt(i);
33.36 + put(exStart, td.start_pc, td);
33.37 + put(exStop, td.end_pc, td);
33.38 + }
33.39 + }
33.40 +
33.41 + private static void put(Hashtable h, short key, TrapData td) {
33.42 + Short s = Short.valueOf((short)key);
33.43 + Vector v = (Vector) h.get(s);
33.44 + if (v == null) {
33.45 + v = new Vector(1);
33.46 + h.put(s, v);
33.47 + }
33.48 + v.add(td);
33.49 + }
33.50 +
33.51 + private boolean processAll(Hashtable h, Short key, boolean add) {
33.52 + boolean change = false;
33.53 + Vector v = (Vector)h.get(key);
33.54 + if (v != null) {
33.55 + int s = v.size();
33.56 + for (int i = 0; i < s; i++) {
33.57 + TrapData td = (TrapData)v.elementAt(i);
33.58 + if (add) {
33.59 + add(td);
33.60 + change = true;
33.61 + } else {
33.62 + remove(td);
33.63 + change = true;
33.64 + }
33.65 + }
33.66 + }
33.67 + return change;
33.68 + }
33.69 +
33.70 + public boolean advanceTo(int i) {
33.71 + Short s = Short.valueOf((short)i);
33.72 + boolean ch1 = processAll(exStart, s, true);
33.73 + boolean ch2 = processAll(exStop, s, false);
33.74 + return ch1 || ch2;
33.75 + }
33.76 +
33.77 + public boolean useTry() {
33.78 + return currentCount > 0;
33.79 + }
33.80 +
33.81 + public TrapData[] current() {
33.82 + TrapData[] copy = new TrapData[currentCount];
33.83 + for (int i = 0; i < currentCount; i++) {
33.84 + copy[i] = current[i];
33.85 + }
33.86 + return copy;
33.87 + }
33.88 +
33.89 + private void add(TrapData e) {
33.90 + if (currentCount == current.length) {
33.91 + TrapData[] data = new TrapData[currentCount * 2];
33.92 + for (int i = 0; i < currentCount; i++) {
33.93 + data[i] = current[i];
33.94 + }
33.95 + current = data;
33.96 + }
33.97 + current[currentCount++] = e;
33.98 + }
33.99 +
33.100 + private void remove(TrapData e) {
33.101 + if (currentCount == 0) {
33.102 + return;
33.103 + }
33.104 + int from = 0;
33.105 + while (from < currentCount) {
33.106 + if (e == current[from++]) {
33.107 + break;
33.108 + }
33.109 + }
33.110 + while (from < currentCount) {
33.111 + current[from - 1] = current[from];
33.112 + current[from] = null;
33.113 + from++;
33.114 + }
33.115 + currentCount--;
33.116 + }
33.117 +}
34.1 --- a/javap/src/main/java/org/apidesign/javap/Vector.java Fri Jan 18 14:23:18 2013 +0100
34.2 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java Fri Jan 18 14:27:22 2013 +0100
34.3 @@ -1,6 +1,19 @@
34.4 -/*
34.5 - * To change this template, choose Tools | Templates
34.6 - * and open the template in the editor.
34.7 +/**
34.8 + * Back 2 Browser Bytecode Translator
34.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
34.10 + *
34.11 + * This program is free software: you can redistribute it and/or modify
34.12 + * it under the terms of the GNU General Public License as published by
34.13 + * the Free Software Foundation, version 2 of the License.
34.14 + *
34.15 + * This program is distributed in the hope that it will be useful,
34.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
34.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34.18 + * GNU General Public License for more details.
34.19 + *
34.20 + * You should have received a copy of the GNU General Public License
34.21 + * along with this program. Look for COPYING file in the top folder.
34.22 + * If not, see http://opensource.org/licenses/GPL-2.0.
34.23 */
34.24 package org.apidesign.javap;
34.25
34.26 @@ -24,8 +37,8 @@
34.27 void add(Object objectType) {
34.28 addElement(objectType);
34.29 }
34.30 - @JavaScriptBody(args = { "self", "obj" }, body =
34.31 - "self.push(obj);"
34.32 + @JavaScriptBody(args = { "obj" }, body =
34.33 + "this.push(obj);"
34.34 )
34.35 void addElement(Object obj) {
34.36 final int s = size();
34.37 @@ -33,16 +46,16 @@
34.38 setElementAt(obj, s);
34.39 }
34.40
34.41 - @JavaScriptBody(args = { "self" }, body =
34.42 - "return self.length;"
34.43 + @JavaScriptBody(args = { }, body =
34.44 + "return this.length;"
34.45 )
34.46 int size() {
34.47 return arr == null ? 0 : arr.length;
34.48 }
34.49
34.50 - @JavaScriptBody(args = { "self", "newArr" }, body =
34.51 - "for (var i = 0; i < self.length; i++) {\n"
34.52 - + " newArr[i] = self[i];\n"
34.53 + @JavaScriptBody(args = { "newArr" }, body =
34.54 + "for (var i = 0; i < this.length; i++) {\n"
34.55 + + " newArr[i] = this[i];\n"
34.56 + "}\n")
34.57 void copyInto(Object[] newArr) {
34.58 if (arr == null) {
34.59 @@ -54,8 +67,8 @@
34.60 }
34.61 }
34.62
34.63 - @JavaScriptBody(args = { "self", "index" }, body =
34.64 - "return self[index];"
34.65 + @JavaScriptBody(args = { "index" }, body =
34.66 + "return this[index];"
34.67 )
34.68 Object elementAt(int index) {
34.69 return arr[index];
34.70 @@ -67,8 +80,8 @@
34.71 arr = newArr;
34.72 }
34.73
34.74 - @JavaScriptBody(args = { "self", "val", "index" }, body =
34.75 - "self[index] = val;"
34.76 + @JavaScriptBody(args = { "val", "index" }, body =
34.77 + "this[index] = val;"
34.78 )
34.79 void setElementAt(Object val, int index) {
34.80 arr[index] = val;
35.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Fri Jan 18 14:23:18 2013 +0100
35.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java Fri Jan 18 14:27:22 2013 +0100
35.3 @@ -43,7 +43,7 @@
35.4 import javax.tools.Diagnostic;
35.5 import javax.tools.FileObject;
35.6 import javax.tools.StandardLocation;
35.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
35.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
35.9 import org.apidesign.bck2brwsr.htmlpage.api.Page;
35.10 import org.openide.util.lookup.ServiceProvider;
35.11
35.12 @@ -55,7 +55,7 @@
35.13 @ServiceProvider(service=Processor.class)
35.14 @SupportedAnnotationTypes({
35.15 "org.apidesign.bck2brwsr.htmlpage.api.Page",
35.16 - "org.apidesign.bck2brwsr.htmlpage.api.OnClick"
35.17 + "org.apidesign.bck2brwsr.htmlpage.api.On"
35.18 })
35.19 public final class PageProcessor extends AbstractProcessor {
35.20 @Override
35.21 @@ -146,11 +146,11 @@
35.22 }
35.23 TypeElement type = (TypeElement)clazz;
35.24 for (Element method : clazz.getEnclosedElements()) {
35.25 - OnClick oc = method.getAnnotation(OnClick.class);
35.26 + On oc = method.getAnnotation(On.class);
35.27 if (oc != null) {
35.28 for (String id : oc.id()) {
35.29 if (pp.tagNameForId(id) == null) {
35.30 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + oc.id() + " does not exist in the HTML page. Found only " + pp.ids(), method);
35.31 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "id = " + id + " does not exist in the HTML page. Found only " + pp.ids(), method);
35.32 return false;
35.33 }
35.34 ExecutableElement ee = (ExecutableElement)method;
35.35 @@ -159,21 +159,21 @@
35.36 hasParam = false;
35.37 } else {
35.38 if (ee.getParameters().size() != 1 || ee.getParameters().get(0).asType() != stringType) {
35.39 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method should either have no arguments or one String argument", ee);
35.40 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method should either have no arguments or one String argument", ee);
35.41 return false;
35.42 }
35.43 hasParam = true;
35.44 }
35.45 if (!ee.getModifiers().contains(Modifier.STATIC)) {
35.46 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method has to be static", ee);
35.47 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method has to be static", ee);
35.48 return false;
35.49 }
35.50 if (ee.getModifiers().contains(Modifier.PRIVATE)) {
35.51 - processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@OnClick method can't be private", ee);
35.52 + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "@On method can't be private", ee);
35.53 return false;
35.54 }
35.55 - w.append(" ").append(cnstnt(id)).
35.56 - append(".addOnClick(new Runnable() { public void run() {\n");
35.57 + w.append(" OnEvent." + oc.event()).append(".of(").append(cnstnt(id)).
35.58 + append(").perform(new Runnable() { public void run() {\n");
35.59 w.append(" ").append(type.getSimpleName().toString()).
35.60 append('.').append(ee.getSimpleName()).append("(");
35.61 if (hasParam) {
36.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java Fri Jan 18 14:23:18 2013 +0100
36.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java Fri Jan 18 14:27:22 2013 +0100
36.3 @@ -37,29 +37,45 @@
36.4 body="var e = window.document.getElementById(el.fld_id);\n"
36.5 + "e[property] = value;\n"
36.6 )
36.7 - static void setAttribute(Element el, String property, Object value) {
36.8 - throw new UnsupportedOperationException("Needs JavaScript!");
36.9 - }
36.10 + static native void setAttribute(Element el, String property, Object value);
36.11
36.12 @JavaScriptBody(
36.13 args={"el", "property"},
36.14 body="var e = window.document.getElementById(el.fld_id);\n"
36.15 + "return e[property];\n"
36.16 )
36.17 - static Object getAttribute(Element el, String property) {
36.18 - throw new UnsupportedOperationException("Needs JavaScript!");
36.19 - }
36.20 + static native Object getAttribute(Element el, String property);
36.21
36.22 /** Executes given runnable when user performs a "click" on the given
36.23 * element.
36.24 * @param r the runnable to execute, never null
36.25 */
36.26 @JavaScriptBody(
36.27 - args={"el", "r"},
36.28 - body="var e = window.document.getElementById(el.fld_id);\n"
36.29 - + "e.onclick = function() { r.run__V(); };\n"
36.30 + args={ "ev", "r" },
36.31 + body="var e = window.document.getElementById(this.fld_id);\n"
36.32 + + "e[ev.fld_id] = function() { r.run__V(); };\n"
36.33 )
36.34 - public final void addOnClick(Runnable r) {
36.35 - throw new UnsupportedOperationException("Needs JavaScript!");
36.36 + final native void on(OnEvent ev, Runnable r);
36.37 +
36.38 + /** Shows alert message dialog in a browser.
36.39 + * @param msg the message to show
36.40 + */
36.41 + @JavaScriptBody(args = "msg", body = "alert(msg);")
36.42 + public static native void alert(String msg);
36.43 +
36.44 + /** Generic way to query any attribute of this element.
36.45 + * @param property name of the attribute
36.46 + */
36.47 + public final Object getAttribute(String property) {
36.48 + return getAttribute(this, property);
36.49 + }
36.50 +
36.51 + /** Generic way to change an attribute of this element.
36.52 + *
36.53 + * @param property name of the attribute
36.54 + * @param value value to associate with the attribute
36.55 + */
36.56 + public final void setAttribute(String property, Object value) {
36.57 + setAttribute(this, property, value);
36.58 }
36.59 }
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/On.java Fri Jan 18 14:27:22 2013 +0100
37.3 @@ -0,0 +1,35 @@
37.4 +/**
37.5 + * Back 2 Browser Bytecode Translator
37.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
37.7 + *
37.8 + * This program is free software: you can redistribute it and/or modify
37.9 + * it under the terms of the GNU General Public License as published by
37.10 + * the Free Software Foundation, version 2 of the License.
37.11 + *
37.12 + * This program is distributed in the hope that it will be useful,
37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37.15 + * GNU General Public License for more details.
37.16 + *
37.17 + * You should have received a copy of the GNU General Public License
37.18 + * along with this program. Look for COPYING file in the top folder.
37.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
37.20 + */
37.21 +package org.apidesign.bck2brwsr.htmlpage.api;
37.22 +
37.23 +import java.lang.annotation.ElementType;
37.24 +import java.lang.annotation.Retention;
37.25 +import java.lang.annotation.RetentionPolicy;
37.26 +import java.lang.annotation.Target;
37.27 +
37.28 +/** Adds an onClick handler to an element identified by given <em>id</em>.
37.29 + * Apply on a <code>public static void</code> method with no arguments.
37.30 + *
37.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
37.32 + */
37.33 +@Retention(RetentionPolicy.SOURCE)
37.34 +@Target(ElementType.METHOD)
37.35 +public @interface On {
37.36 + OnEvent event();
37.37 + String[] id();
37.38 +}
38.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnClick.java Fri Jan 18 14:23:18 2013 +0100
38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
38.3 @@ -1,34 +0,0 @@
38.4 -/**
38.5 - * Back 2 Browser Bytecode Translator
38.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
38.7 - *
38.8 - * This program is free software: you can redistribute it and/or modify
38.9 - * it under the terms of the GNU General Public License as published by
38.10 - * the Free Software Foundation, version 2 of the License.
38.11 - *
38.12 - * This program is distributed in the hope that it will be useful,
38.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
38.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38.15 - * GNU General Public License for more details.
38.16 - *
38.17 - * You should have received a copy of the GNU General Public License
38.18 - * along with this program. Look for COPYING file in the top folder.
38.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
38.20 - */
38.21 -package org.apidesign.bck2brwsr.htmlpage.api;
38.22 -
38.23 -import java.lang.annotation.ElementType;
38.24 -import java.lang.annotation.Retention;
38.25 -import java.lang.annotation.RetentionPolicy;
38.26 -import java.lang.annotation.Target;
38.27 -
38.28 -/** Adds an onClick handler to an element identified by given <em>id</em>.
38.29 - * Apply on a <code>public static void</code> method with no arguments.
38.30 - *
38.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
38.32 - */
38.33 -@Retention(RetentionPolicy.SOURCE)
38.34 -@Target(ElementType.METHOD)
38.35 -public @interface OnClick {
38.36 - String[] id();
38.37 -}
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnController.java Fri Jan 18 14:27:22 2013 +0100
39.3 @@ -0,0 +1,43 @@
39.4 +/**
39.5 + * Back 2 Browser Bytecode Translator
39.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
39.7 + *
39.8 + * This program is free software: you can redistribute it and/or modify
39.9 + * it under the terms of the GNU General Public License as published by
39.10 + * the Free Software Foundation, version 2 of the License.
39.11 + *
39.12 + * This program is distributed in the hope that it will be useful,
39.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
39.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39.15 + * GNU General Public License for more details.
39.16 + *
39.17 + * You should have received a copy of the GNU General Public License
39.18 + * along with this program. Look for COPYING file in the top folder.
39.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
39.20 + */
39.21 +package org.apidesign.bck2brwsr.htmlpage.api;
39.22 +
39.23 +/** Controller created via {@link OnEvent#of(org.apidesign.bck2brwsr.htmlpage.api.Element[])}.
39.24 + *
39.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
39.26 + */
39.27 +public final class OnController {
39.28 + private final Element[] arr;
39.29 + private final OnEvent event;
39.30 +
39.31 + OnController(OnEvent event, Element[] arr) {
39.32 + this.event = event;
39.33 + this.arr = arr;
39.34 + }
39.35 +
39.36 + /** Registers a runnable to be performed on associated {@link OnEvent}
39.37 + * and {@link Element}.
39.38 + *
39.39 + * @see OnEvent#of
39.40 + */
39.41 + public void perform(Runnable r) {
39.42 + for (Element e : arr) {
39.43 + e.on(event, r);
39.44 + }
39.45 + }
39.46 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/OnEvent.java Fri Jan 18 14:27:22 2013 +0100
40.3 @@ -0,0 +1,95 @@
40.4 +/**
40.5 + * Back 2 Browser Bytecode Translator
40.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
40.7 + *
40.8 + * This program is free software: you can redistribute it and/or modify
40.9 + * it under the terms of the GNU General Public License as published by
40.10 + * the Free Software Foundation, version 2 of the License.
40.11 + *
40.12 + * This program is distributed in the hope that it will be useful,
40.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
40.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40.15 + * GNU General Public License for more details.
40.16 + *
40.17 + * You should have received a copy of the GNU General Public License
40.18 + * along with this program. Look for COPYING file in the top folder.
40.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
40.20 + */
40.21 +package org.apidesign.bck2brwsr.htmlpage.api;
40.22 +
40.23 +/** Type of events to use in connection with {@link On} annotation.
40.24 + *
40.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
40.26 + */
40.27 +public enum OnEvent {
40.28 + ABORT("onabort"),
40.29 + BLUR("onblur"),
40.30 + CAN_PLAY("oncanplay"),
40.31 + CAN_PLAY_THROUGH("oncanplaythrough"),
40.32 + CLICK("onclick"),
40.33 + CONTEXT_MENU("oncontextmenu"),
40.34 + DBL_CLICK("ondblclick"),
40.35 + DRAG("ondrag"),
40.36 + DRAG_END("ondragend"),
40.37 + DRAG_ENTER("ondragenter"),
40.38 + DRAG_LEAVE("ondragleave"),
40.39 + DRAG_OVER("ondragover"),
40.40 + DRAG_START("ondragstart"),
40.41 + DROP("ondrop"),
40.42 + DURATION_CHANGE("ondurationchange"),
40.43 + EMPTIED("onemptied"),
40.44 + ENDED("onended"),
40.45 + ERROR("onerror"),
40.46 + FOCUS("onfocus"),
40.47 + FORM_CHANGE("onformchange"),
40.48 + FORM_INPUT("onforminput"),
40.49 + INPUT("oninput"),
40.50 + INVALID("oninvalid"),
40.51 + KEY_DOWN("onkeydown"),
40.52 + KEY_PRESS("onkeypress"),
40.53 + KEY_UP("onkeyup"),
40.54 + LOAD("onload"),
40.55 + LOADED_DATA("onloadeddata"),
40.56 + LOADED_META_DATA("onloadedmetadata"),
40.57 + LOAD_START("onloadstart"),
40.58 + MOUSE_DOWN("onmousedown"),
40.59 + MOUSE_MOVE("onmousemove"),
40.60 + MOUSE_OUT("onmouseout"),
40.61 + MOUSE_OVER("onmouseover"),
40.62 + MOUSE_UP("onmouseup"),
40.63 + MOUSE_WHEEL("onmousewheel"),
40.64 + PAUSE("onpause"),
40.65 + PLAY("onplay"),
40.66 + PLAYING("onplaying"),
40.67 + PROGRESS("onprogress"),
40.68 + RATE_CHANGE("onratechange"),
40.69 + READY_STATE_CHANGE("onreadystatechange"),
40.70 + SCROLL("onscroll"),
40.71 + SEEKED("onseeked"),
40.72 + SEEKING("onseeking"),
40.73 + SELECT("onselect"),
40.74 + SHOW("onshow"),
40.75 + STALLED("onstalled"),
40.76 + SUBMIT("onsubmit"),
40.77 + SUSPEND("onsuspend"),
40.78 + TIME_UPDATE("ontimeupdate"),
40.79 + VOLUME_CHANGE("onvolumechange"),
40.80 + WAITING("onwaiting");
40.81 +
40.82 + final String id;
40.83 +
40.84 + private OnEvent(String id) {
40.85 + this.id = id;
40.86 + }
40.87 +
40.88 + /** What should happen when this even happen on one
40.89 + * of associated elements. Continue by calling {@link OnController#perform(java.lang.Runnable)}
40.90 + * method.
40.91 + *
40.92 + * @param elmnts one or more elements
40.93 + * @return controller with <code>perform</code> method.
40.94 + */
40.95 + public OnController of(Element... elmnts) {
40.96 + return new OnController(this, elmnts);
40.97 + }
40.98 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Timer.java Fri Jan 18 14:27:22 2013 +0100
41.3 @@ -0,0 +1,59 @@
41.4 +/**
41.5 + * Back 2 Browser Bytecode Translator
41.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
41.7 + *
41.8 + * This program is free software: you can redistribute it and/or modify
41.9 + * it under the terms of the GNU General Public License as published by
41.10 + * the Free Software Foundation, version 2 of the License.
41.11 + *
41.12 + * This program is distributed in the hope that it will be useful,
41.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
41.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41.15 + * GNU General Public License for more details.
41.16 + *
41.17 + * You should have received a copy of the GNU General Public License
41.18 + * along with this program. Look for COPYING file in the top folder.
41.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
41.20 + */
41.21 +package org.apidesign.bck2brwsr.htmlpage.api;
41.22 +
41.23 +import java.io.Closeable;
41.24 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
41.25 +
41.26 +/**
41.27 + *
41.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
41.29 + */
41.30 +public class Timer implements Closeable {
41.31 + private final Object t;
41.32 +
41.33 + private Timer(Object t) {
41.34 + this.t = t;
41.35 + }
41.36 +
41.37 + /** Creates a timer that invokes provided runnable on a fixed interval
41.38 + *
41.39 + * @param r the runnable to execute
41.40 + * @param time milliseconds to invoke the timer periodically
41.41 + */
41.42 + public static Timer create(Runnable r, int time) {
41.43 + return new Timer(interval(r, time));
41.44 + }
41.45 +
41.46 + @JavaScriptBody(args = { "r", "time" }, body =
41.47 + "return window.setInterval(function() { r.run__V(); }, time);"
41.48 + )
41.49 + private static native Object interval(Runnable r, int time);
41.50 +
41.51 + @JavaScriptBody(args = { "self" }, body =
41.52 + "window.clearInterval(self);"
41.53 + )
41.54 + private static native void close(Object self);
41.55 +
41.56 + /** Cancels this timer.
41.57 + */
41.58 + @Override
41.59 + public void close() {
41.60 + close(t);
41.61 + }
41.62 +}
42.1 --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Fri Jan 18 14:23:18 2013 +0100
42.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/PageController.java Fri Jan 18 14:27:22 2013 +0100
42.3 @@ -17,7 +17,8 @@
42.4 */
42.5 package org.apidesign.bck2brwsr.htmlpage;
42.6
42.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
42.8 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
42.9 +import org.apidesign.bck2brwsr.htmlpage.api.On;
42.10 import org.apidesign.bck2brwsr.htmlpage.api.Page;
42.11
42.12 /** Trivial demo for the bck2brwsr project. First of all start
42.13 @@ -42,12 +43,12 @@
42.14 */
42.15 @Page(xhtml="TestPage.html")
42.16 public class PageController {
42.17 - @OnClick(id="pg.button")
42.18 + @On(event = CLICK, id="pg.button")
42.19 static void updateTitle() {
42.20 TestPage.PG_TITLE.setText("You want this window to be named " + TestPage.PG_TEXT.getValue());
42.21 }
42.22
42.23 - @OnClick(id={ "pg.title", "pg.text" })
42.24 + @On(event = CLICK, id={ "pg.title", "pg.text" })
42.25 static void click(String id) {
42.26 if (!id.equals("pg.title")) {
42.27 throw new IllegalStateException();
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/javaquery/demo-calculator-dynamic/nbactions.xml Fri Jan 18 14:27:22 2013 +0100
43.3 @@ -0,0 +1,29 @@
43.4 +<?xml version="1.0" encoding="UTF-8"?>
43.5 +<!--
43.6 +
43.7 + Back 2 Browser Bytecode Translator
43.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
43.9 +
43.10 + This program is free software: you can redistribute it and/or modify
43.11 + it under the terms of the GNU General Public License as published by
43.12 + the Free Software Foundation, version 2 of the License.
43.13 +
43.14 + This program is distributed in the hope that it will be useful,
43.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
43.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43.17 + GNU General Public License for more details.
43.18 +
43.19 + You should have received a copy of the GNU General Public License
43.20 + along with this program. Look for COPYING file in the top folder.
43.21 + If not, see http://opensource.org/licenses/GPL-2.0.
43.22 +
43.23 +-->
43.24 +<actions>
43.25 + <action>
43.26 + <actionName>run</actionName>
43.27 + <goals>
43.28 + <goal>process-classes</goal>
43.29 + <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
43.30 + </goals>
43.31 + </action>
43.32 + </actions>
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/javaquery/demo-calculator-dynamic/pom.xml Fri Jan 18 14:27:22 2013 +0100
44.3 @@ -0,0 +1,58 @@
44.4 +<?xml version="1.0"?>
44.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44.6 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
44.7 + <modelVersion>4.0.0</modelVersion>
44.8 +
44.9 + <groupId>org.apidesign.bck2brwsr</groupId>
44.10 + <artifactId>demo.calculator</artifactId>
44.11 + <version>0.3-SNAPSHOT</version>
44.12 + <packaging>jar</packaging>
44.13 +
44.14 + <name>JavaQuery Demo - Calculator</name>
44.15 + <url>http://maven.apache.org</url>
44.16 +
44.17 + <properties>
44.18 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
44.19 + </properties>
44.20 + <build>
44.21 + <plugins>
44.22 + <plugin>
44.23 + <groupId>org.apidesign.bck2brwsr</groupId>
44.24 + <artifactId>mojo</artifactId>
44.25 + <version>0.3-SNAPSHOT</version>
44.26 + <executions>
44.27 + <execution>
44.28 + <goals>
44.29 + <goal>brwsr</goal>
44.30 + </goals>
44.31 + </execution>
44.32 + </executions>
44.33 + <configuration>
44.34 + <startpage>org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml</startpage>
44.35 + </configuration>
44.36 + </plugin>
44.37 + <plugin>
44.38 + <groupId>org.apache.maven.plugins</groupId>
44.39 + <artifactId>maven-compiler-plugin</artifactId>
44.40 + <version>2.3.2</version>
44.41 + <configuration>
44.42 + <source>1.7</source>
44.43 + <target>1.7</target>
44.44 + </configuration>
44.45 + </plugin>
44.46 + </plugins>
44.47 + </build>
44.48 +
44.49 + <dependencies>
44.50 + <dependency>
44.51 + <groupId>org.apidesign.bck2brwsr</groupId>
44.52 + <artifactId>emul</artifactId>
44.53 + <version>0.3-SNAPSHOT</version>
44.54 + </dependency>
44.55 + <dependency>
44.56 + <groupId>org.apidesign.bck2brwsr</groupId>
44.57 + <artifactId>javaquery.api</artifactId>
44.58 + <version>0.3-SNAPSHOT</version>
44.59 + </dependency>
44.60 + </dependencies>
44.61 +</project>
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java Fri Jan 18 14:27:22 2013 +0100
45.3 @@ -0,0 +1,89 @@
45.4 +/**
45.5 + * Back 2 Browser Bytecode Translator
45.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
45.7 + *
45.8 + * This program is free software: you can redistribute it and/or modify
45.9 + * it under the terms of the GNU General Public License as published by
45.10 + * the Free Software Foundation, version 2 of the License.
45.11 + *
45.12 + * This program is distributed in the hope that it will be useful,
45.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
45.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45.15 + * GNU General Public License for more details.
45.16 + *
45.17 + * You should have received a copy of the GNU General Public License
45.18 + * along with this program. Look for COPYING file in the top folder.
45.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
45.20 + */
45.21 +package org.apidesign.bck2brwsr.mavenhtml;
45.22 +
45.23 +import org.apidesign.bck2brwsr.htmlpage.api.On;
45.24 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
45.25 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
45.26 +
45.27 +/** HTML5 & Java demo showing the power of
45.28 + * <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation processors</a>
45.29 + * as well as other goodies.
45.30 + *
45.31 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
45.32 + */
45.33 +@Page(xhtml="Calculator.xhtml")
45.34 +public class App {
45.35 + private static double memory;
45.36 + private static String operation;
45.37 +
45.38 + @On(event = CLICK, id="clear")
45.39 + static void clear() {
45.40 + memory = 0;
45.41 + operation = null;
45.42 + Calculator.DISPLAY.setValue("0");
45.43 + }
45.44 +
45.45 + @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
45.46 + static void applyOp(String op) {
45.47 + memory = getValue();
45.48 + operation = op;
45.49 + Calculator.DISPLAY.setValue("0");
45.50 + }
45.51 +
45.52 + @On(event = CLICK, id="result")
45.53 + static void computeTheValue() {
45.54 + switch (operation) {
45.55 + case "plus": setValue(memory + getValue()); break;
45.56 + case "minus": setValue(memory - getValue()); break;
45.57 + case "mul": setValue(memory * getValue()); break;
45.58 + case "div": setValue(memory / getValue()); break;
45.59 + default: throw new IllegalStateException(operation);
45.60 + }
45.61 + }
45.62 +
45.63 + @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"})
45.64 + static void addDigit(String digit) {
45.65 + digit = digit.substring(1);
45.66 + String v = Calculator.DISPLAY.getValue();
45.67 + if (getValue() == 0.0) {
45.68 + Calculator.DISPLAY.setValue(digit);
45.69 + } else {
45.70 + Calculator.DISPLAY.setValue(v + digit);
45.71 + }
45.72 + }
45.73 +
45.74 + private static void setValue(double v) {
45.75 + StringBuilder sb = new StringBuilder();
45.76 + sb.append(v);
45.77 + if (sb.toString().endsWith(".0")) {
45.78 + final int l = sb.length();
45.79 + sb.delete(l - 2, l);
45.80 + }
45.81 + Calculator.DISPLAY.setValue(sb.toString());
45.82 + }
45.83 +
45.84 + private static double getValue() {
45.85 + try {
45.86 + return Double.parseDouble(Calculator.DISPLAY.getValue());
45.87 + } catch (NumberFormatException ex) {
45.88 + Calculator.DISPLAY.setValue("err");
45.89 + return 0.0;
45.90 + }
45.91 + }
45.92 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/javaquery/demo-calculator-dynamic/src/main/resources/org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml Fri Jan 18 14:27:22 2013 +0100
46.3 @@ -0,0 +1,158 @@
46.4 +<?xml version="1.0" encoding="UTF-8"?>
46.5 +<!--
46.6 +
46.7 + Back 2 Browser Bytecode Translator
46.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
46.9 +
46.10 + This program is free software: you can redistribute it and/or modify
46.11 + it under the terms of the GNU General Public License as published by
46.12 + the Free Software Foundation, version 2 of the License.
46.13 +
46.14 + This program is distributed in the hope that it will be useful,
46.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
46.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46.17 + GNU General Public License for more details.
46.18 +
46.19 + You should have received a copy of the GNU General Public License
46.20 + along with this program. Look for COPYING file in the top folder.
46.21 + If not, see http://opensource.org/licenses/GPL-2.0.
46.22 +
46.23 +-->
46.24 +<!DOCTYPE html>
46.25 +<html xmlns="http://www.w3.org/1999/xhtml">
46.26 + <head>
46.27 + <title>Simple Calculator in HTML5 and Java</title>
46.28 +
46.29 + <style type="text/css">
46.30 + body {color: #ffffff; background-color: #121e31; font-family: Monospaced}
46.31 + pre {color: #ffffff; background-color: #121e31; font-family: Monospaced}
46.32 + table {color: #ffffff; background-color: #121e31; font-family: Monospaced}
46.33 + .string {color: #e2ce00}
46.34 + a {color: #e2ce00}
46.35 + .ST1 {color: #0000cc; font-family: Monospaced; font-weight: bold}
46.36 + .ST0 {color: #0000ff}
46.37 + .comment {color: #428bdd}
46.38 + .keyword-directive {color: #f8bb00}
46.39 + .tag {color: #f8bb00}
46.40 + .ST0 {color: #628fb5; background-color: #1b3450}
46.41 + .sgml-comment {color: #808080}
46.42 + .value {color: #99006b}
46.43 + .argument {color: #007c00}
46.44 + .sgml-declaration {color: #bf9221}
46.45 + </style>
46.46 + </head>
46.47 + <body>
46.48 + <h1>Java and HTML5 - Together at Last!</h1>
46.49 + <table border="0" cellspacing="2">
46.50 + <tbody>
46.51 + <tr>
46.52 + <td colspan="4"><input id="display" value="0"
46.53 + style="text-align: right"/>
46.54 + </td>
46.55 + </tr>
46.56 + <tr>
46.57 + <td><button id="n1">1</button></td>
46.58 + <td><button id="n2">2</button></td>
46.59 + <td><button id="n3">3</button></td>
46.60 + <td><button id="plus">+</button></td>
46.61 + </tr>
46.62 + <tr>
46.63 + <td><button id="n4">4</button></td>
46.64 + <td><button id="n5">5</button></td>
46.65 + <td><button id="n6">6</button></td>
46.66 + <td><button id="minus">-</button></td>
46.67 + </tr>
46.68 + <tr>
46.69 + <td><button id="n7">7</button></td>
46.70 + <td><button id="n8">8</button></td>
46.71 + <td><button id="n9">9</button></td>
46.72 + <td><button id="mul">*</button></td>
46.73 + </tr>
46.74 + <tr>
46.75 + <td><button id="clear">C</button></td>
46.76 + <td><button id="n0">0</button></td>
46.77 + <td><button id="result">=</button></td>
46.78 + <td><button id="div">/</button></td>
46.79 + </tr>
46.80 + </tbody>
46.81 + </table>
46.82 +
46.83 + <script src="/bck2brwsr.js"></script>
46.84 + <script src="/vm.js"></script>
46.85 + <script type="text/javascript">
46.86 + vm.loadClass('org.apidesign.bck2brwsr.mavenhtml.Calculator');
46.87 + </script>
46.88 +
46.89 + <hr/>
46.90 + <pre>
46.91 + <span class="keyword-directive">package</span> org.apidesign.bck2brwsr.mavenhtml;
46.92 +
46.93 + <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.OnClick;
46.94 + <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.Page;
46.95 +
46.96 + <span class="comment">/**</span> <span class="comment">HTML5</span><span class="comment"> & </span><span class="comment">Java</span> <span class="comment">demo</span> <span class="comment">showing</span> <span class="comment">the</span> <span class="comment">power</span> <span class="comment">of</span> <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation processors</a>
46.97 + <span class="comment"> * </span><span class="comment">as</span> <span class="comment">well</span> <span class="comment">as</span> <span class="comment">other</span> <span class="comment">goodies</span><span class="comment">, including type-safe association between</span>
46.98 + <span class="comment"> * </span><span class="comment">an XHTML page and Java.</span>
46.99 + <span class="comment"> * </span>
46.100 + <span class="comment"> * </span><span class="ST1">@author</span> <span class="comment">Jaroslav</span> <span class="comment">Tulach</span> <span class="ST0"><jaroslav.tulach@apidesign.org></span>
46.101 + <span class="comment">*/</span>
46.102 + @Page(xhtml=<span class="string">"</span><span class="string">Calculator.xhtml</span><span class="string">"</span>)
46.103 + <span class="keyword-directive">public</span> <span class="keyword-directive">class</span> App {
46.104 + <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> memory;
46.105 + <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> String operation;
46.106 +
46.107 + @OnClick(id=<span class="string">"</span><span class="string">clear</span><span class="string">"</span>)
46.108 + <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> clear() {
46.109 + memory = <span class="number">0</span>;
46.110 + operation = <span class="keyword-directive">null</span>;
46.111 + Calculator.DISPLAY.setValue(<span class="string">"</span><span class="string">0</span><span class="string">"</span>);
46.112 + }
46.113 +
46.114 + @OnClick(id= { <span class="string">"</span><span class="string">plus</span><span class="string">"</span>, <span class="string">"</span><span class="string">minus</span><span class="string">"</span>, <span class="string">"</span><span class="string">mul</span><span class="string">"</span>, <span class="string">"</span><span class="string">div</span><span class="string">"</span> })
46.115 + <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> applyOp(String op) {
46.116 + memory = getValue();
46.117 + operation = op;
46.118 + Calculator.DISPLAY.setValue(<span class="string">"</span><span class="string">0</span><span class="string">"</span>);
46.119 + }
46.120 +
46.121 + @OnClick(id=<span class="string">"</span><span class="string">result</span><span class="string">"</span>)
46.122 + <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> computeTheValue() {
46.123 + <span class="keyword-directive">switch</span> (operation) {
46.124 + <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">plus</span><span class="string">"</span>: setValue(memory + getValue()); <span class="keyword-directive">break</span>;
46.125 + <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">minus</span><span class="string">"</span>: setValue(memory - getValue()); <span class="keyword-directive">break</span>;
46.126 + <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">mul</span><span class="string">"</span>: setValue(memory * getValue()); <span class="keyword-directive">break</span>;
46.127 + <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">div</span><span class="string">"</span>: setValue(memory / getValue()); <span class="keyword-directive">break</span>;
46.128 + <span class="keyword-directive">default</span>: <span class="keyword-directive">throw</span> <span class="keyword-directive">new</span> IllegalStateException(operation);
46.129 + }
46.130 + }
46.131 +
46.132 + @OnClick(id={<span class="string">"</span><span class="string">n0</span><span class="string">"</span>, <span class="string">"</span><span class="string">n1</span><span class="string">"</span>, <span class="string">"</span><span class="string">n2</span><span class="string">"</span>, <span class="string">"</span><span class="string">n3</span><span class="string">"</span>, <span class="string">"</span><span class="string">n4</span><span class="string">"</span>, <span class="string">"</span><span class="string">n5</span><span class="string">"</span>, <span class="string">"</span><span class="string">n6</span><span class="string">"</span>, <span class="string">"</span><span class="string">n7</span><span class="string">"</span>, <span class="string">"</span><span class="string">n8</span><span class="string">"</span>, <span class="string">"</span><span class="string">n9</span><span class="string">"</span>})
46.133 + <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> addDigit(String digit) {
46.134 + digit = digit.substring(<span class="number">1</span>);
46.135 + String v = Calculator.DISPLAY.getValue();
46.136 + <span class="keyword-directive">if</span> (getValue() == <span class="number">0.0</span>) {
46.137 + Calculator.DISPLAY.setValue(digit);
46.138 + } <span class="keyword-directive">else</span> {
46.139 + Calculator.DISPLAY.setValue(v + digit);
46.140 + }
46.141 + }
46.142 +
46.143 + <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> setValue(<span class="keyword-directive">double</span> v) {
46.144 + StringBuilder sb = <span class="keyword-directive">new</span> StringBuilder();
46.145 + sb.append(v);
46.146 + Calculator.DISPLAY.setValue(sb.toString());
46.147 + }
46.148 +
46.149 + <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> getValue() {
46.150 + <span class="keyword-directive">try</span> {
46.151 + <span class="keyword-directive">return</span> Double.parseDouble(Calculator.DISPLAY.getValue());
46.152 + } <span class="keyword-directive">catch</span> (NumberFormatException ex) {
46.153 + Calculator.DISPLAY.setValue(<span class="string">"</span><span class="string">err</span><span class="string">"</span>);
46.154 + <span class="keyword-directive">return</span> <span class="number">0.0</span>;
46.155 + }
46.156 + }
46.157 + }
46.158 +
46.159 + </pre>
46.160 + </body>
46.161 +</html>
47.1 --- a/javaquery/demo-calculator/pom.xml Fri Jan 18 14:23:18 2013 +0100
47.2 +++ b/javaquery/demo-calculator/pom.xml Fri Jan 18 14:27:22 2013 +0100
47.3 @@ -4,11 +4,11 @@
47.4 <modelVersion>4.0.0</modelVersion>
47.5
47.6 <groupId>org.apidesign.bck2brwsr</groupId>
47.7 - <artifactId>demo.calculator</artifactId>
47.8 + <artifactId>demo.static.calculator</artifactId>
47.9 <version>0.3-SNAPSHOT</version>
47.10 <packaging>jar</packaging>
47.11
47.12 - <name>JavaQuery Demo - Calculator</name>
47.13 + <name>JavaQuery Demo - Calculator - Static Compilation</name>
47.14 <url>http://maven.apache.org</url>
47.15
47.16 <properties>
48.1 --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java Fri Jan 18 14:23:18 2013 +0100
48.2 +++ b/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java Fri Jan 18 14:27:22 2013 +0100
48.3 @@ -17,7 +17,8 @@
48.4 */
48.5 package org.apidesign.bck2brwsr.mavenhtml;
48.6
48.7 -import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
48.8 +import org.apidesign.bck2brwsr.htmlpage.api.On;
48.9 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
48.10 import org.apidesign.bck2brwsr.htmlpage.api.Page;
48.11
48.12 /** HTML5 & Java demo showing the power of
48.13 @@ -31,21 +32,21 @@
48.14 private static double memory;
48.15 private static String operation;
48.16
48.17 - @OnClick(id="clear")
48.18 + @On(event = CLICK, id="clear")
48.19 static void clear() {
48.20 memory = 0;
48.21 operation = null;
48.22 Calculator.DISPLAY.setValue("0");
48.23 }
48.24
48.25 - @OnClick(id= { "plus", "minus", "mul", "div" })
48.26 + @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
48.27 static void applyOp(String op) {
48.28 memory = getValue();
48.29 operation = op;
48.30 Calculator.DISPLAY.setValue("0");
48.31 }
48.32
48.33 - @OnClick(id="result")
48.34 + @On(event = CLICK, id="result")
48.35 static void computeTheValue() {
48.36 switch (operation) {
48.37 case "plus": setValue(memory + getValue()); break;
48.38 @@ -56,7 +57,7 @@
48.39 }
48.40 }
48.41
48.42 - @OnClick(id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"})
48.43 + @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"})
48.44 static void addDigit(String digit) {
48.45 digit = digit.substring(1);
48.46 String v = Calculator.DISPLAY.getValue();
49.1 --- a/javaquery/pom.xml Fri Jan 18 14:23:18 2013 +0100
49.2 +++ b/javaquery/pom.xml Fri Jan 18 14:27:22 2013 +0100
49.3 @@ -14,5 +14,6 @@
49.4 <modules>
49.5 <module>api</module>
49.6 <module>demo-calculator</module>
49.7 + <module>demo-calculator-dynamic</module>
49.8 </modules>
49.9 </project>
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
50.2 +++ b/launcher/pom.xml Fri Jan 18 14:27:22 2013 +0100
50.3 @@ -0,0 +1,49 @@
50.4 +<?xml version="1.0"?>
50.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
50.6 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
50.7 + <modelVersion>4.0.0</modelVersion>
50.8 + <parent>
50.9 + <groupId>org.apidesign</groupId>
50.10 + <artifactId>bck2brwsr</artifactId>
50.11 + <version>0.3-SNAPSHOT</version>
50.12 + </parent>
50.13 + <groupId>org.apidesign.bck2brwsr</groupId>
50.14 + <artifactId>launcher</artifactId>
50.15 + <version>0.3-SNAPSHOT</version>
50.16 + <name>Bck2Brwsr Launcher</name>
50.17 + <url>http://maven.apache.org</url>
50.18 + <build>
50.19 + <plugins>
50.20 + <plugin>
50.21 + <groupId>org.apache.maven.plugins</groupId>
50.22 + <artifactId>maven-compiler-plugin</artifactId>
50.23 + <version>2.3.2</version>
50.24 + <configuration>
50.25 + <source>1.7</source>
50.26 + <target>1.7</target>
50.27 + </configuration>
50.28 + </plugin>
50.29 + </plugins>
50.30 + </build>
50.31 + <properties>
50.32 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
50.33 + </properties>
50.34 + <dependencies>
50.35 + <dependency>
50.36 + <groupId>junit</groupId>
50.37 + <artifactId>junit</artifactId>
50.38 + <version>3.8.1</version>
50.39 + <scope>test</scope>
50.40 + </dependency>
50.41 + <dependency>
50.42 + <groupId>org.glassfish.grizzly</groupId>
50.43 + <artifactId>grizzly-http-server</artifactId>
50.44 + <version>2.2.19</version>
50.45 + </dependency>
50.46 + <dependency>
50.47 + <groupId>${project.groupId}</groupId>
50.48 + <artifactId>vm4brwsr</artifactId>
50.49 + <version>${project.version}</version>
50.50 + </dependency>
50.51 + </dependencies>
50.52 +</project>
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
51.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Fri Jan 18 14:27:22 2013 +0100
51.3 @@ -0,0 +1,455 @@
51.4 +/**
51.5 + * Back 2 Browser Bytecode Translator
51.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
51.7 + *
51.8 + * This program is free software: you can redistribute it and/or modify
51.9 + * it under the terms of the GNU General Public License as published by
51.10 + * the Free Software Foundation, version 2 of the License.
51.11 + *
51.12 + * This program is distributed in the hope that it will be useful,
51.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
51.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51.15 + * GNU General Public License for more details.
51.16 + *
51.17 + * You should have received a copy of the GNU General Public License
51.18 + * along with this program. Look for COPYING file in the top folder.
51.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
51.20 + */
51.21 +package org.apidesign.bck2brwsr.launcher;
51.22 +
51.23 +import java.io.Closeable;
51.24 +import java.io.File;
51.25 +import java.io.IOException;
51.26 +import java.io.InputStream;
51.27 +import java.io.InterruptedIOException;
51.28 +import java.io.OutputStream;
51.29 +import java.io.Writer;
51.30 +import java.net.URI;
51.31 +import java.net.URISyntaxException;
51.32 +import java.net.URL;
51.33 +import java.util.ArrayList;
51.34 +import java.util.Arrays;
51.35 +import java.util.Enumeration;
51.36 +import java.util.LinkedHashSet;
51.37 +import java.util.List;
51.38 +import java.util.Set;
51.39 +import java.util.concurrent.BlockingQueue;
51.40 +import java.util.concurrent.CountDownLatch;
51.41 +import java.util.concurrent.LinkedBlockingQueue;
51.42 +import java.util.concurrent.TimeUnit;
51.43 +import java.util.logging.Level;
51.44 +import java.util.logging.Logger;
51.45 +import org.apidesign.vm4brwsr.Bck2Brwsr;
51.46 +import org.glassfish.grizzly.PortRange;
51.47 +import org.glassfish.grizzly.http.server.HttpHandler;
51.48 +import org.glassfish.grizzly.http.server.HttpServer;
51.49 +import org.glassfish.grizzly.http.server.NetworkListener;
51.50 +import org.glassfish.grizzly.http.server.Request;
51.51 +import org.glassfish.grizzly.http.server.Response;
51.52 +import org.glassfish.grizzly.http.server.ServerConfiguration;
51.53 +
51.54 +/**
51.55 + * Lightweight server to launch Bck2Brwsr applications and tests.
51.56 + * Supports execution in native browser as well as Java's internal
51.57 + * execution engine.
51.58 + */
51.59 +final class Bck2BrwsrLauncher extends Launcher implements Closeable {
51.60 + private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
51.61 + private static final MethodInvocation END = new MethodInvocation(null, null);
51.62 + private Set<ClassLoader> loaders = new LinkedHashSet<>();
51.63 + private BlockingQueue<MethodInvocation> methods = new LinkedBlockingQueue<>();
51.64 + private long timeOut;
51.65 + private final Res resources = new Res();
51.66 + private final String cmd;
51.67 + private Object[] brwsr;
51.68 + private HttpServer server;
51.69 + private CountDownLatch wait;
51.70 +
51.71 + public Bck2BrwsrLauncher(String cmd) {
51.72 + this.cmd = cmd;
51.73 + }
51.74 +
51.75 + @Override
51.76 + public MethodInvocation addMethod(Class<?> clazz, String method) throws IOException {
51.77 + loaders.add(clazz.getClassLoader());
51.78 + MethodInvocation c = new MethodInvocation(clazz.getName(), method);
51.79 + methods.add(c);
51.80 + try {
51.81 + c.await(timeOut);
51.82 + } catch (InterruptedException ex) {
51.83 + throw new IOException(ex);
51.84 + }
51.85 + return c;
51.86 + }
51.87 +
51.88 + public void setTimeout(long ms) {
51.89 + timeOut = ms;
51.90 + }
51.91 +
51.92 + public void addClassLoader(ClassLoader url) {
51.93 + this.loaders.add(url);
51.94 + }
51.95 +
51.96 + public void showURL(String startpage) throws IOException {
51.97 + if (!startpage.startsWith("/")) {
51.98 + startpage = "/" + startpage;
51.99 + }
51.100 + HttpServer s = initServer();
51.101 + s.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
51.102 + try {
51.103 + launchServerAndBrwsr(s, startpage);
51.104 + } catch (URISyntaxException | InterruptedException ex) {
51.105 + throw new IOException(ex);
51.106 + }
51.107 + }
51.108 +
51.109 + @Override
51.110 + public void initialize() throws IOException {
51.111 + try {
51.112 + executeInBrowser();
51.113 + } catch (InterruptedException ex) {
51.114 + final InterruptedIOException iio = new InterruptedIOException(ex.getMessage());
51.115 + iio.initCause(ex);
51.116 + throw iio;
51.117 + } catch (Exception ex) {
51.118 + if (ex instanceof IOException) {
51.119 + throw (IOException)ex;
51.120 + }
51.121 + if (ex instanceof RuntimeException) {
51.122 + throw (RuntimeException)ex;
51.123 + }
51.124 + throw new IOException(ex);
51.125 + }
51.126 + }
51.127 +
51.128 + private HttpServer initServer() {
51.129 + HttpServer s = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
51.130 +
51.131 + final ServerConfiguration conf = s.getServerConfiguration();
51.132 + conf.addHttpHandler(new Page(resources,
51.133 + "org/apidesign/bck2brwsr/launcher/console.xhtml",
51.134 + "org.apidesign.bck2brwsr.launcher.Console", "welcome", "false"
51.135 + ), "/console");
51.136 + conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
51.137 + conf.addHttpHandler(new VMInit(), "/vm.js");
51.138 + conf.addHttpHandler(new Classes(resources), "/classes/");
51.139 + return s;
51.140 + }
51.141 +
51.142 + private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
51.143 + wait = new CountDownLatch(1);
51.144 + server = initServer();
51.145 + ServerConfiguration conf = server.getServerConfiguration();
51.146 + conf.addHttpHandler(new Page(resources,
51.147 + "org/apidesign/bck2brwsr/launcher/harness.xhtml"
51.148 + ), "/execute");
51.149 + conf.addHttpHandler(new HttpHandler() {
51.150 + int cnt;
51.151 + List<MethodInvocation> cases = new ArrayList<>();
51.152 + @Override
51.153 + public void service(Request request, Response response) throws Exception {
51.154 + String id = request.getParameter("request");
51.155 + String value = request.getParameter("result");
51.156 +
51.157 + if (id != null && value != null) {
51.158 + LOG.log(Level.INFO, "Received result for case {0} = {1}", new Object[]{id, value});
51.159 + value = decodeURL(value);
51.160 + cases.get(Integer.parseInt(id)).result(value, null);
51.161 + }
51.162 +
51.163 + MethodInvocation mi = methods.take();
51.164 + if (mi == END) {
51.165 + response.getWriter().write("");
51.166 + wait.countDown();
51.167 + cnt = 0;
51.168 + LOG.log(Level.INFO, "End of data reached. Exiting.");
51.169 + return;
51.170 + }
51.171 +
51.172 + cases.add(mi);
51.173 + final String cn = mi.className;
51.174 + final String mn = mi.methodName;
51.175 + LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{cnt, cn, mn});
51.176 + response.getWriter().write("{"
51.177 + + "className: '" + cn + "', "
51.178 + + "methodName: '" + mn + "', "
51.179 + + "request: " + cnt
51.180 + + "}");
51.181 + cnt++;
51.182 + }
51.183 + }, "/data");
51.184 +
51.185 + this.brwsr = launchServerAndBrwsr(server, "/execute");
51.186 + }
51.187 +
51.188 + @Override
51.189 + public void shutdown() throws IOException {
51.190 + methods.offer(END);
51.191 + for (;;) {
51.192 + int prev = methods.size();
51.193 + try {
51.194 + if (wait != null && wait.await(timeOut, TimeUnit.MILLISECONDS)) {
51.195 + break;
51.196 + }
51.197 + } catch (InterruptedException ex) {
51.198 + throw new IOException(ex);
51.199 + }
51.200 + if (prev == methods.size()) {
51.201 + LOG.log(
51.202 + Level.WARNING,
51.203 + "Timeout and no test has been executed meanwhile (at {0}). Giving up.",
51.204 + methods.size()
51.205 + );
51.206 + break;
51.207 + }
51.208 + LOG.log(Level.INFO,
51.209 + "Timeout, but tests got from {0} to {1}. Trying again.",
51.210 + new Object[]{prev, methods.size()}
51.211 + );
51.212 + }
51.213 + stopServerAndBrwsr(server, brwsr);
51.214 + }
51.215 +
51.216 + static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
51.217 + for (;;) {
51.218 + int ch = is.read();
51.219 + if (ch == -1) {
51.220 + break;
51.221 + }
51.222 + if (ch == '$') {
51.223 + int cnt = is.read() - '0';
51.224 + if (cnt == 'U' - '0') {
51.225 + os.write(baseURL.getBytes());
51.226 + }
51.227 + if (cnt < params.length) {
51.228 + os.write(params[cnt].getBytes());
51.229 + }
51.230 + } else {
51.231 + os.write(ch);
51.232 + }
51.233 + }
51.234 + }
51.235 +
51.236 + private Object[] launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
51.237 + server.start();
51.238 + NetworkListener listener = server.getListeners().iterator().next();
51.239 + int port = listener.getPort();
51.240 +
51.241 + URI uri = new URI("http://localhost:" + port + page);
51.242 + LOG.log(Level.INFO, "Showing {0}", uri);
51.243 + if (cmd == null) {
51.244 + try {
51.245 + java.awt.Desktop.getDesktop().browse(uri);
51.246 + LOG.log(Level.INFO, "Desktop.browse successfully finished");
51.247 + return null;
51.248 + } catch (UnsupportedOperationException ex) {
51.249 + LOG.log(Level.INFO, "Desktop.browse not supported", ex);
51.250 + }
51.251 + }
51.252 + {
51.253 + String cmdName = cmd == null ? "xdg-open" : cmd;
51.254 + String[] cmdArr = {
51.255 + cmdName, uri.toString()
51.256 + };
51.257 + LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmdArr));
51.258 + final Process process = Runtime.getRuntime().exec(cmdArr);
51.259 + return new Object[] { process, null };
51.260 + }
51.261 + }
51.262 +
51.263 + private static String decodeURL(String s) {
51.264 + for (;;) {
51.265 + int pos = s.indexOf('%');
51.266 + if (pos == -1) {
51.267 + return s;
51.268 + }
51.269 + int i = Integer.parseInt(s.substring(pos + 1, pos + 2), 16);
51.270 + s = s.substring(0, pos) + (char)i + s.substring(pos + 2);
51.271 + }
51.272 + }
51.273 +
51.274 + private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException {
51.275 + if (brwsr == null) {
51.276 + return;
51.277 + }
51.278 + Process process = (Process)brwsr[0];
51.279 +
51.280 + server.stop();
51.281 + InputStream stdout = process.getInputStream();
51.282 + InputStream stderr = process.getErrorStream();
51.283 + drain("StdOut", stdout);
51.284 + drain("StdErr", stderr);
51.285 + process.destroy();
51.286 + int res;
51.287 + try {
51.288 + res = process.waitFor();
51.289 + } catch (InterruptedException ex) {
51.290 + throw new IOException(ex);
51.291 + }
51.292 + LOG.log(Level.INFO, "Exit code: {0}", res);
51.293 +
51.294 + deleteTree((File)brwsr[1]);
51.295 + }
51.296 +
51.297 + private static void drain(String name, InputStream is) throws IOException {
51.298 + int av = is.available();
51.299 + if (av > 0) {
51.300 + StringBuilder sb = new StringBuilder();
51.301 + sb.append("v== ").append(name).append(" ==v\n");
51.302 + while (av-- > 0) {
51.303 + sb.append((char)is.read());
51.304 + }
51.305 + sb.append("\n^== ").append(name).append(" ==^");
51.306 + LOG.log(Level.INFO, sb.toString());
51.307 + }
51.308 + }
51.309 +
51.310 + private void deleteTree(File file) {
51.311 + if (file == null) {
51.312 + return;
51.313 + }
51.314 + File[] arr = file.listFiles();
51.315 + if (arr != null) {
51.316 + for (File s : arr) {
51.317 + deleteTree(s);
51.318 + }
51.319 + }
51.320 + file.delete();
51.321 + }
51.322 +
51.323 + @Override
51.324 + public void close() throws IOException {
51.325 + shutdown();
51.326 + }
51.327 +
51.328 + private class Res implements Bck2Brwsr.Resources {
51.329 + @Override
51.330 + public InputStream get(String resource) throws IOException {
51.331 + for (ClassLoader l : loaders) {
51.332 + URL u = null;
51.333 + Enumeration<URL> en = l.getResources(resource);
51.334 + while (en.hasMoreElements()) {
51.335 + u = en.nextElement();
51.336 + }
51.337 + if (u != null) {
51.338 + return u.openStream();
51.339 + }
51.340 + }
51.341 + throw new IOException("Can't find " + resource);
51.342 + }
51.343 + }
51.344 +
51.345 + private static class Page extends HttpHandler {
51.346 + private final String resource;
51.347 + private final String[] args;
51.348 + private final Res res;
51.349 +
51.350 + public Page(Res res, String resource, String... args) {
51.351 + this.res = res;
51.352 + this.resource = resource;
51.353 + this.args = args;
51.354 + }
51.355 +
51.356 + @Override
51.357 + public void service(Request request, Response response) throws Exception {
51.358 + String r = resource;
51.359 + if (r == null) {
51.360 + r = request.getHttpHandlerPath();
51.361 + if (r.startsWith("/")) {
51.362 + r = r.substring(1);
51.363 + }
51.364 + }
51.365 + if (r.endsWith(".html")) {
51.366 + response.setContentType("text/html");
51.367 + LOG.info("Content type text/html");
51.368 + }
51.369 + if (r.endsWith(".xhtml")) {
51.370 + response.setContentType("application/xhtml+xml");
51.371 + LOG.info("Content type application/xhtml+xml");
51.372 + }
51.373 + OutputStream os = response.getOutputStream();
51.374 + try (InputStream is = res.get(r)) {
51.375 + copyStream(is, os, request.getRequestURL().toString(), args);
51.376 + } catch (IOException ex) {
51.377 + response.setDetailMessage(ex.getLocalizedMessage());
51.378 + response.setError();
51.379 + response.setStatus(404);
51.380 + }
51.381 + }
51.382 + }
51.383 +
51.384 + private static class VM extends HttpHandler {
51.385 + private final Res loader;
51.386 +
51.387 + public VM(Res loader) {
51.388 + this.loader = loader;
51.389 + }
51.390 +
51.391 + @Override
51.392 + public void service(Request request, Response response) throws Exception {
51.393 + response.setCharacterEncoding("UTF-8");
51.394 + response.setContentType("text/javascript");
51.395 + Bck2Brwsr.generate(response.getWriter(), loader);
51.396 + }
51.397 + }
51.398 + private static class VMInit extends HttpHandler {
51.399 + public VMInit() {
51.400 + }
51.401 +
51.402 + @Override
51.403 + public void service(Request request, Response response) throws Exception {
51.404 + response.setCharacterEncoding("UTF-8");
51.405 + response.setContentType("text/javascript");
51.406 + response.getWriter().append(
51.407 + "function ldCls(res) {\n"
51.408 + + " var request = new XMLHttpRequest();\n"
51.409 + + " request.open('GET', '/classes/' + res, false);\n"
51.410 + + " request.send();\n"
51.411 + + " var arr = eval('(' + request.responseText + ')');\n"
51.412 + + " return arr;\n"
51.413 + + "}\n"
51.414 + + "var vm = new bck2brwsr(ldCls);\n");
51.415 + }
51.416 + }
51.417 +
51.418 + private static class Classes extends HttpHandler {
51.419 + private final Res loader;
51.420 +
51.421 + public Classes(Res loader) {
51.422 + this.loader = loader;
51.423 + }
51.424 +
51.425 + @Override
51.426 + public void service(Request request, Response response) throws Exception {
51.427 + String res = request.getHttpHandlerPath();
51.428 + if (res.startsWith("/")) {
51.429 + res = res.substring(1);
51.430 + }
51.431 + try (InputStream is = loader.get(res)) {
51.432 + response.setContentType("text/javascript");
51.433 + Writer w = response.getWriter();
51.434 + w.append("[");
51.435 + for (int i = 0;; i++) {
51.436 + int b = is.read();
51.437 + if (b == -1) {
51.438 + break;
51.439 + }
51.440 + if (i > 0) {
51.441 + w.append(", ");
51.442 + }
51.443 + if (i % 20 == 0) {
51.444 + w.write("\n");
51.445 + }
51.446 + if (b > 127) {
51.447 + b = b - 256;
51.448 + }
51.449 + w.append(Integer.toString(b));
51.450 + }
51.451 + w.append("\n]");
51.452 + } catch (IOException ex) {
51.453 + response.setError();
51.454 + response.setDetailMessage(ex.getMessage());
51.455 + }
51.456 + }
51.457 + }
51.458 +}
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java Fri Jan 18 14:27:22 2013 +0100
52.3 @@ -0,0 +1,208 @@
52.4 +/**
52.5 + * Back 2 Browser Bytecode Translator
52.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
52.7 + *
52.8 + * This program is free software: you can redistribute it and/or modify
52.9 + * it under the terms of the GNU General Public License as published by
52.10 + * the Free Software Foundation, version 2 of the License.
52.11 + *
52.12 + * This program is distributed in the hope that it will be useful,
52.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
52.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52.15 + * GNU General Public License for more details.
52.16 + *
52.17 + * You should have received a copy of the GNU General Public License
52.18 + * along with this program. Look for COPYING file in the top folder.
52.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
52.20 + */
52.21 +package org.apidesign.bck2brwsr.launcher;
52.22 +
52.23 +import java.io.IOException;
52.24 +import java.io.InputStream;
52.25 +import java.lang.reflect.InvocationTargetException;
52.26 +import java.lang.reflect.Method;
52.27 +import java.lang.reflect.Modifier;
52.28 +import java.net.URL;
52.29 +import java.util.Enumeration;
52.30 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
52.31 +
52.32 +/**
52.33 + *
52.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
52.35 + */
52.36 +public class Console {
52.37 + public static String welcome() {
52.38 + return "HellofromBck2Brwsr";
52.39 + }
52.40 + public static String multiply() {
52.41 + return String.valueOf(Integer.MAX_VALUE / 2 + Integer.MAX_VALUE);
52.42 + }
52.43 +
52.44 + @JavaScriptBody(args = {"id", "attr"}, body =
52.45 + "return window.document.getElementById(id)[attr].toString();")
52.46 + private static native Object getAttr(String id, String attr);
52.47 +
52.48 + @JavaScriptBody(args = {"id", "attr", "value"}, body =
52.49 + "window.document.getElementById(id)[attr] = value;")
52.50 + private static native void setAttr(String id, String attr, Object value);
52.51 +
52.52 + @JavaScriptBody(args = {}, body = "return; window.close();")
52.53 + private static native void closeWindow();
52.54 +
52.55 + private static void log(String newText) {
52.56 + String id = "result";
52.57 + String attr = "value";
52.58 + setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
52.59 + setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
52.60 + }
52.61 +
52.62 + public static void execute() throws Exception {
52.63 + String clazz = (String) getAttr("clazz", "value");
52.64 + String method = (String) getAttr("method", "value");
52.65 + Object res = invokeMethod(clazz, method);
52.66 + setAttr("result", "value", res);
52.67 + }
52.68 +
52.69 + public static void harness(String url) {
52.70 + log("Connecting to " + url);
52.71 + try {
52.72 + URL u = new URL(url);
52.73 + for (;;) {
52.74 + String data = (String) u.getContent(new Class[] { String.class });
52.75 + log("\nGot \"" + data + "\"");
52.76 + if (data.isEmpty()) {
52.77 + log("No data, exiting");
52.78 + closeWindow();
52.79 + break;
52.80 + }
52.81 +
52.82 + Case c = Case.parseData(data);
52.83 + log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
52.84 +
52.85 + Object result = invokeMethod(c.getClassName(), c.getMethodName());
52.86 +
52.87 + log("Result: " + result);
52.88 +
52.89 + result = encodeURL("" + result);
52.90 +
52.91 + log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
52.92 + u = new URL(url + "?request=" + c.getRequestId() + "&result=" + result);
52.93 + }
52.94 +
52.95 +
52.96 + } catch (Exception ex) {
52.97 + log(ex.getMessage());
52.98 + }
52.99 + }
52.100 +
52.101 + private static String encodeURL(String r) {
52.102 + StringBuilder sb = new StringBuilder();
52.103 + for (int i = 0; i < r.length(); i++) {
52.104 + int ch = r.charAt(i);
52.105 + if (ch < 32 || ch == '%' || ch == '+') {
52.106 + sb.append("%").append(("0" + Integer.toHexString(ch)).substring(0, 2));
52.107 + } else {
52.108 + if (ch == 32) {
52.109 + sb.append("+");
52.110 + } else {
52.111 + sb.append((char)ch);
52.112 + }
52.113 + }
52.114 + }
52.115 + return sb.toString();
52.116 + }
52.117 +
52.118 + static String invoke(String clazz, String method) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException {
52.119 + final Object r = invokeMethod(clazz, method);
52.120 + return r == null ? "null" : r.toString().toString();
52.121 + }
52.122 +
52.123 + /** Helper method that inspects the classpath and loads given resource
52.124 + * (usually a class file). Used while running tests in Rhino.
52.125 + *
52.126 + * @param name resource name to find
52.127 + * @return the array of bytes in the given resource
52.128 + * @throws IOException I/O in case something goes wrong
52.129 + */
52.130 + public static byte[] read(String name) throws IOException {
52.131 + URL u = null;
52.132 + Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
52.133 + while (en.hasMoreElements()) {
52.134 + u = en.nextElement();
52.135 + }
52.136 + if (u == null) {
52.137 + throw new IOException("Can't find " + name);
52.138 + }
52.139 + try (InputStream is = u.openStream()) {
52.140 + byte[] arr;
52.141 + arr = new byte[is.available()];
52.142 + int offset = 0;
52.143 + while (offset < arr.length) {
52.144 + int len = is.read(arr, offset, arr.length - offset);
52.145 + if (len == -1) {
52.146 + throw new IOException("Can't read " + name);
52.147 + }
52.148 + offset += len;
52.149 + }
52.150 + return arr;
52.151 + }
52.152 + }
52.153 +
52.154 + private static Object invokeMethod(String clazz, String method)
52.155 + throws ClassNotFoundException, InvocationTargetException,
52.156 + SecurityException, IllegalAccessException, IllegalArgumentException,
52.157 + InstantiationException {
52.158 + Method found = null;
52.159 + Class<?> c = Class.forName(clazz);
52.160 + for (Method m : c.getMethods()) {
52.161 + if (m.getName().equals(method)) {
52.162 + found = m;
52.163 + }
52.164 + }
52.165 + Object res;
52.166 + if (found != null) {
52.167 + try {
52.168 + if ((found.getModifiers() & Modifier.STATIC) != 0) {
52.169 + res = found.invoke(null);
52.170 + } else {
52.171 + res = found.invoke(c.newInstance());
52.172 + }
52.173 + } catch (Exception ex) {
52.174 + res = ex.getClass().getName() + ":" + ex.getMessage();
52.175 + }
52.176 + } else {
52.177 + res = "Can't find method " + method + " in " + clazz;
52.178 + }
52.179 + return res;
52.180 + }
52.181 +
52.182 + private static final class Case {
52.183 + private final Object data;
52.184 +
52.185 + private Case(Object data) {
52.186 + this.data = data;
52.187 + }
52.188 +
52.189 + public static Case parseData(String s) {
52.190 + return new Case(toJSON(s));
52.191 + }
52.192 +
52.193 + public String getMethodName() {
52.194 + return value("methodName", data);
52.195 + }
52.196 +
52.197 + public String getClassName() {
52.198 + return value("className", data);
52.199 + }
52.200 +
52.201 + public String getRequestId() {
52.202 + return value("request", data);
52.203 + }
52.204 +
52.205 + @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
52.206 + private static native Object toJSON(String s);
52.207 +
52.208 + @JavaScriptBody(args = {"p", "d"}, body = "return d[p].toString();")
52.209 + private static native String value(String p, Object d);
52.210 + }
52.211 +}
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java Fri Jan 18 14:27:22 2013 +0100
53.3 @@ -0,0 +1,127 @@
53.4 +/**
53.5 + * Back 2 Browser Bytecode Translator
53.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
53.7 + *
53.8 + * This program is free software: you can redistribute it and/or modify
53.9 + * it under the terms of the GNU General Public License as published by
53.10 + * the Free Software Foundation, version 2 of the License.
53.11 + *
53.12 + * This program is distributed in the hope that it will be useful,
53.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
53.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53.15 + * GNU General Public License for more details.
53.16 + *
53.17 + * You should have received a copy of the GNU General Public License
53.18 + * along with this program. Look for COPYING file in the top folder.
53.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
53.20 + */
53.21 +package org.apidesign.bck2brwsr.launcher;
53.22 +
53.23 +import java.io.IOException;
53.24 +import java.io.InputStream;
53.25 +import java.net.URL;
53.26 +import java.util.Enumeration;
53.27 +import java.util.LinkedHashSet;
53.28 +import java.util.Set;
53.29 +import java.util.logging.Logger;
53.30 +import javax.script.Invocable;
53.31 +import javax.script.ScriptEngine;
53.32 +import javax.script.ScriptEngineManager;
53.33 +import javax.script.ScriptException;
53.34 +import org.apidesign.vm4brwsr.Bck2Brwsr;
53.35 +
53.36 +/**
53.37 + * Tests execution in Java's internal scripting engine.
53.38 + */
53.39 +final class JSLauncher extends Launcher {
53.40 + private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
53.41 + private Set<ClassLoader> loaders = new LinkedHashSet<>();
53.42 + private final Res resources = new Res();
53.43 + private Invocable code;
53.44 + private StringBuilder codeSeq;
53.45 + private Object console;
53.46 +
53.47 +
53.48 + @Override
53.49 + public MethodInvocation addMethod(Class<?> clazz, String method) {
53.50 + loaders.add(clazz.getClassLoader());
53.51 + MethodInvocation mi = new MethodInvocation(clazz.getName(), method);
53.52 + try {
53.53 + mi.result(code.invokeMethod(
53.54 + console,
53.55 + "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
53.56 + mi.className, mi.methodName).toString(), null);
53.57 + } catch (ScriptException | NoSuchMethodException ex) {
53.58 + mi.result(null, ex);
53.59 + }
53.60 + return mi;
53.61 + }
53.62 +
53.63 + public void addClassLoader(ClassLoader url) {
53.64 + this.loaders.add(url);
53.65 + }
53.66 +
53.67 + @Override
53.68 + public void initialize() throws IOException {
53.69 + try {
53.70 + initRhino();
53.71 + } catch (Exception ex) {
53.72 + if (ex instanceof IOException) {
53.73 + throw (IOException)ex;
53.74 + }
53.75 + if (ex instanceof RuntimeException) {
53.76 + throw (RuntimeException)ex;
53.77 + }
53.78 + throw new IOException(ex);
53.79 + }
53.80 + }
53.81 +
53.82 + private void initRhino() throws IOException, ScriptException, NoSuchMethodException {
53.83 + StringBuilder sb = new StringBuilder();
53.84 + Bck2Brwsr.generate(sb, new Res());
53.85 +
53.86 + ScriptEngineManager sem = new ScriptEngineManager();
53.87 + ScriptEngine mach = sem.getEngineByExtension("js");
53.88 +
53.89 + sb.append(
53.90 + "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.Console.read);"
53.91 + + "\nfunction initVM() { return vm; };"
53.92 + + "\n");
53.93 +
53.94 + Object res = mach.eval(sb.toString());
53.95 + if (!(mach instanceof Invocable)) {
53.96 + throw new IOException("It is invocable object: " + res);
53.97 + }
53.98 + code = (Invocable) mach;
53.99 + codeSeq = sb;
53.100 +
53.101 + Object vm = code.invokeFunction("initVM");
53.102 + console = code.invokeMethod(vm, "loadClass", Console.class.getName());
53.103 + }
53.104 +
53.105 + @Override
53.106 + public void shutdown() throws IOException {
53.107 + }
53.108 +
53.109 + @Override
53.110 + public String toString() {
53.111 + return codeSeq.toString();
53.112 + }
53.113 +
53.114 + private class Res implements Bck2Brwsr.Resources {
53.115 + @Override
53.116 + public InputStream get(String resource) throws IOException {
53.117 + for (ClassLoader l : loaders) {
53.118 + URL u = null;
53.119 + Enumeration<URL> en = l.getResources(resource);
53.120 + while (en.hasMoreElements()) {
53.121 + u = en.nextElement();
53.122 + }
53.123 + if (u != null) {
53.124 + return u.openStream();
53.125 + }
53.126 + }
53.127 + throw new IOException("Can't find " + resource);
53.128 + }
53.129 + }
53.130 +}
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
54.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java Fri Jan 18 14:27:22 2013 +0100
54.3 @@ -0,0 +1,63 @@
54.4 +/**
54.5 + * Back 2 Browser Bytecode Translator
54.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
54.7 + *
54.8 + * This program is free software: you can redistribute it and/or modify
54.9 + * it under the terms of the GNU General Public License as published by
54.10 + * the Free Software Foundation, version 2 of the License.
54.11 + *
54.12 + * This program is distributed in the hope that it will be useful,
54.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
54.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54.15 + * GNU General Public License for more details.
54.16 + *
54.17 + * You should have received a copy of the GNU General Public License
54.18 + * along with this program. Look for COPYING file in the top folder.
54.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
54.20 + */
54.21 +package org.apidesign.bck2brwsr.launcher;
54.22 +
54.23 +import java.io.Closeable;
54.24 +import java.io.IOException;
54.25 +import java.net.URLClassLoader;
54.26 +import org.apidesign.vm4brwsr.Bck2Brwsr;
54.27 +
54.28 +/** An abstraction for executing tests in a Bck2Brwsr virtual machine.
54.29 + * Either in JavaScript engine, or in external browser.
54.30 + *
54.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
54.32 + */
54.33 +public abstract class Launcher {
54.34 +
54.35 + Launcher() {
54.36 + }
54.37 +
54.38 + abstract MethodInvocation addMethod(Class<?> clazz, String method) throws IOException;
54.39 +
54.40 + public abstract void initialize() throws IOException;
54.41 + public abstract void shutdown() throws IOException;
54.42 + public MethodInvocation invokeMethod(Class<?> clazz, String method) throws IOException {
54.43 + return addMethod(clazz, method);
54.44 + }
54.45 +
54.46 +
54.47 +
54.48 + public static Launcher createJavaScript() {
54.49 + final JSLauncher l = new JSLauncher();
54.50 + l.addClassLoader(Bck2Brwsr.class.getClassLoader());
54.51 + return l;
54.52 + }
54.53 +
54.54 + public static Launcher createBrowser(String cmd) {
54.55 + final Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(cmd);
54.56 + l.addClassLoader(Bck2Brwsr.class.getClassLoader());
54.57 + l.setTimeout(180000);
54.58 + return l;
54.59 + }
54.60 + public static Closeable showURL(URLClassLoader classes, String startpage) throws IOException {
54.61 + Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
54.62 + l.addClassLoader(classes);
54.63 + l.showURL(startpage);
54.64 + return l;
54.65 + }
54.66 +}
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/MethodInvocation.java Fri Jan 18 14:27:22 2013 +0100
55.3 @@ -0,0 +1,57 @@
55.4 +/**
55.5 + * Back 2 Browser Bytecode Translator
55.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
55.7 + *
55.8 + * This program is free software: you can redistribute it and/or modify
55.9 + * it under the terms of the GNU General Public License as published by
55.10 + * the Free Software Foundation, version 2 of the License.
55.11 + *
55.12 + * This program is distributed in the hope that it will be useful,
55.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
55.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55.15 + * GNU General Public License for more details.
55.16 + *
55.17 + * You should have received a copy of the GNU General Public License
55.18 + * along with this program. Look for COPYING file in the top folder.
55.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
55.20 + */
55.21 +package org.apidesign.bck2brwsr.launcher;
55.22 +
55.23 +import java.util.concurrent.CountDownLatch;
55.24 +import java.util.concurrent.TimeUnit;
55.25 +
55.26 +/**
55.27 + *
55.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
55.29 + */
55.30 +public final class MethodInvocation {
55.31 + final CountDownLatch wait = new CountDownLatch(1);
55.32 + final String className;
55.33 + final String methodName;
55.34 + private String result;
55.35 + private Throwable exception;
55.36 +
55.37 + MethodInvocation(String className, String methodName) {
55.38 + this.className = className;
55.39 + this.methodName = methodName;
55.40 + }
55.41 +
55.42 + void await(long timeOut) throws InterruptedException {
55.43 + wait.await(timeOut, TimeUnit.MILLISECONDS);
55.44 + }
55.45 +
55.46 + void result(String r, Throwable e) {
55.47 + this.result = r;
55.48 + this.exception = e;
55.49 + wait.countDown();
55.50 + }
55.51 +
55.52 + @Override
55.53 + public String toString() {
55.54 + if (exception != null) {
55.55 + return exception.toString();
55.56 + }
55.57 + return result;
55.58 + }
55.59 +
55.60 +}
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
56.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/console.xhtml Fri Jan 18 14:27:22 2013 +0100
56.3 @@ -0,0 +1,52 @@
56.4 +<?xml version="1.0" encoding="UTF-8"?>
56.5 +<!--
56.6 +
56.7 + Back 2 Browser Bytecode Translator
56.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
56.9 +
56.10 + This program is free software: you can redistribute it and/or modify
56.11 + it under the terms of the GNU General Public License as published by
56.12 + the Free Software Foundation, version 2 of the License.
56.13 +
56.14 + This program is distributed in the hope that it will be useful,
56.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
56.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56.17 + GNU General Public License for more details.
56.18 +
56.19 + You should have received a copy of the GNU General Public License
56.20 + along with this program. Look for COPYING file in the top folder.
56.21 + If not, see http://opensource.org/licenses/GPL-2.0.
56.22 +
56.23 +-->
56.24 +<!DOCTYPE html>
56.25 +<html xmlns="http://www.w3.org/1999/xhtml">
56.26 + <head>
56.27 + <title>Bck2Brwsr Launcher</title>
56.28 + </head>
56.29 + <body>
56.30 + <script src="/bck2brwsr.js"></script>
56.31 + <script src="/vm.js"></script>
56.32 +
56.33 + <h1>Bck2Browser Console Launcher</h1>
56.34 +
56.35 + Class Name:
56.36 + <input id="clazz" value="$0"/>
56.37 + <br/>
56.38 + Method Name:
56.39 +
56.40 + <input id="method" value="$1"/>
56.41 + <br/>
56.42 +
56.43 + <button onclick="vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').execute__V();">Execute!</button>
56.44 +
56.45 + <hr/>
56.46 + <textarea id="result" rows="10" cols="80" disabled="">
56.47 + </textarea>
56.48 +
56.49 + <script type="text/javascript">
56.50 + if ($2) {
56.51 + vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').execute__V();
56.52 + }
56.53 + </script>
56.54 + </body>
56.55 +</html>
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
57.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Fri Jan 18 14:27:22 2013 +0100
57.3 @@ -0,0 +1,39 @@
57.4 +<?xml version="1.0" encoding="UTF-8"?>
57.5 +<!--
57.6 +
57.7 + Back 2 Browser Bytecode Translator
57.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
57.9 +
57.10 + This program is free software: you can redistribute it and/or modify
57.11 + it under the terms of the GNU General Public License as published by
57.12 + the Free Software Foundation, version 2 of the License.
57.13 +
57.14 + This program is distributed in the hope that it will be useful,
57.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
57.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57.17 + GNU General Public License for more details.
57.18 +
57.19 + You should have received a copy of the GNU General Public License
57.20 + along with this program. Look for COPYING file in the top folder.
57.21 + If not, see http://opensource.org/licenses/GPL-2.0.
57.22 +
57.23 +-->
57.24 +<!DOCTYPE html>
57.25 +<html xmlns="http://www.w3.org/1999/xhtml">
57.26 + <head>
57.27 + <title>Bck2Brwsr Harness</title>
57.28 + </head>
57.29 + <body>
57.30 + <script src="/bck2brwsr.js"></script>
57.31 + <script src="/vm.js"></script>
57.32 +
57.33 + <h1>Bck2Browser Execution Harness</h1>
57.34 +
57.35 + <textarea id="result" rows="25" style="width: 100%;" disabled="">
57.36 + </textarea>
57.37 +
57.38 + <script type="text/javascript">
57.39 + vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').harness__VLjava_lang_String_2('$U/../data');
57.40 + </script>
57.41 + </body>
57.42 +</html>
58.1 --- a/mojo/pom.xml Fri Jan 18 14:23:18 2013 +0100
58.2 +++ b/mojo/pom.xml Fri Jan 18 14:27:22 2013 +0100
58.3 @@ -11,7 +11,7 @@
58.4 <artifactId>mojo</artifactId>
58.5 <version>0.3-SNAPSHOT</version>
58.6 <packaging>maven-plugin</packaging>
58.7 - <name>Maven Mojo to Compile to JavaScript</name>
58.8 + <name>Bck2Brwsr Maven Project</name>
58.9 <url>http://maven.apache.org</url>
58.10 <build>
58.11 <plugins>
58.12 @@ -77,5 +77,10 @@
58.13 <version>3.0.2</version>
58.14 <type>jar</type>
58.15 </dependency>
58.16 + <dependency>
58.17 + <groupId>${project.groupId}</groupId>
58.18 + <artifactId>launcher</artifactId>
58.19 + <version>${project.version}</version>
58.20 + </dependency>
58.21 </dependencies>
58.22 </project>
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
59.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java Fri Jan 18 14:27:22 2013 +0100
59.3 @@ -0,0 +1,89 @@
59.4 +/**
59.5 + * Back 2 Browser Bytecode Translator
59.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
59.7 + *
59.8 + * This program is free software: you can redistribute it and/or modify
59.9 + * it under the terms of the GNU General Public License as published by
59.10 + * the Free Software Foundation, version 2 of the License.
59.11 + *
59.12 + * This program is distributed in the hope that it will be useful,
59.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
59.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59.15 + * GNU General Public License for more details.
59.16 + *
59.17 + * You should have received a copy of the GNU General Public License
59.18 + * along with this program. Look for COPYING file in the top folder.
59.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
59.20 + */
59.21 +package org.apidesign.bck2brwsr.mojo;
59.22 +
59.23 +import java.io.Closeable;
59.24 +import org.apache.maven.plugin.AbstractMojo;
59.25 +
59.26 +import java.io.File;
59.27 +import java.io.IOException;
59.28 +import java.net.MalformedURLException;
59.29 +import java.net.URL;
59.30 +import java.net.URLClassLoader;
59.31 +import java.util.ArrayList;
59.32 +import java.util.Collection;
59.33 +import java.util.List;
59.34 +import org.apache.maven.artifact.Artifact;
59.35 +import org.apache.maven.plugin.MojoExecutionException;
59.36 +import org.apache.maven.plugins.annotations.LifecyclePhase;
59.37 +import org.apache.maven.plugins.annotations.Mojo;
59.38 +import org.apache.maven.plugins.annotations.Parameter;
59.39 +import org.apache.maven.project.MavenProject;
59.40 +import org.apidesign.bck2brwsr.launcher.Launcher;
59.41 +
59.42 +/** Executes given HTML page in a browser. */
59.43 +@Mojo(name="brwsr", defaultPhase=LifecyclePhase.DEPLOY)
59.44 +public class BrswrMojo extends AbstractMojo {
59.45 + public BrswrMojo() {
59.46 + }
59.47 + /** Resource to show as initial page */
59.48 + @Parameter
59.49 + private String startpage;
59.50 +
59.51 + @Parameter(defaultValue="${project}")
59.52 + private MavenProject prj;
59.53 +
59.54 + /** Root of the class files */
59.55 + @Parameter(defaultValue="${project.build.directory}/classes")
59.56 + private File classes;
59.57 +
59.58 + @Override
59.59 + public void execute() throws MojoExecutionException {
59.60 + if (startpage == null) {
59.61 + throw new MojoExecutionException("You have to provide a start page");
59.62 + }
59.63 +
59.64 + try {
59.65 + URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
59.66 +
59.67 + Closeable httpServer;
59.68 + try {
59.69 + httpServer = Launcher.showURL(url, startpage());
59.70 + } catch (Exception ex) {
59.71 + throw new MojoExecutionException("Can't open " + startpage(), ex);
59.72 + }
59.73 + System.in.read();
59.74 + httpServer.close();
59.75 + } catch (IOException ex) {
59.76 + throw new MojoExecutionException("Can't show the browser", ex);
59.77 + }
59.78 + }
59.79 +
59.80 + private String startpage() {
59.81 + return startpage;
59.82 + }
59.83 +
59.84 + private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
59.85 + List<URL> arr = new ArrayList<URL>();
59.86 + arr.add(root.toURI().toURL());
59.87 + for (Artifact a : deps) {
59.88 + arr.add(a.getFile().toURI().toURL());
59.89 + }
59.90 + return new URLClassLoader(arr.toArray(new URL[0]), BrswrMojo.class.getClassLoader());
59.91 + }
59.92 +}
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
60.2 +++ b/mojo/src/main/resources/META-INF/maven/archetype-metadata.xml Fri Jan 18 14:27:22 2013 +0100
60.3 @@ -0,0 +1,42 @@
60.4 +<?xml version="1.0" encoding="UTF-8"?>
60.5 +<!--
60.6 +
60.7 + Back 2 Browser Bytecode Translator
60.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
60.9 +
60.10 + This program is free software: you can redistribute it and/or modify
60.11 + it under the terms of the GNU General Public License as published by
60.12 + the Free Software Foundation, version 2 of the License.
60.13 +
60.14 + This program is distributed in the hope that it will be useful,
60.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
60.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60.17 + GNU General Public License for more details.
60.18 +
60.19 + You should have received a copy of the GNU General Public License
60.20 + along with this program. Look for COPYING file in the top folder.
60.21 + If not, see http://opensource.org/licenses/GPL-2.0.
60.22 +
60.23 +-->
60.24 +<archetype-descriptor name="bck2brwsr">
60.25 + <fileSets>
60.26 + <fileSet filtered="true" packaged="true">
60.27 + <directory>src/main/java</directory>
60.28 + <includes>
60.29 + <include>**/*.java</include>
60.30 + </includes>
60.31 + </fileSet>
60.32 + <fileSet filtered="true" packaged="true">
60.33 + <directory>src/main/resources</directory>
60.34 + <includes>
60.35 + <include>**/*.xhtml</include>
60.36 + </includes>
60.37 + </fileSet>
60.38 + <fileSet filtered="false" packaged="false">
60.39 + <directory></directory>
60.40 + <includes>
60.41 + <include>nbactions.xml</include>
60.42 + </includes>
60.43 + </fileSet>
60.44 + </fileSets>
60.45 +</archetype-descriptor>
60.46 \ No newline at end of file
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
61.2 +++ b/mojo/src/main/resources/archetype-resources/nbactions.xml Fri Jan 18 14:27:22 2013 +0100
61.3 @@ -0,0 +1,10 @@
61.4 +<?xml version="1.0" encoding="UTF-8"?>
61.5 +<actions>
61.6 + <action>
61.7 + <actionName>run</actionName>
61.8 + <goals>
61.9 + <goal>process-classes</goal>
61.10 + <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
61.11 + </goals>
61.12 + </action>
61.13 +</actions>
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/mojo/src/main/resources/archetype-resources/pom.xml Fri Jan 18 14:27:22 2013 +0100
62.3 @@ -0,0 +1,57 @@
62.4 +<?xml version="1.0"?>
62.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
62.6 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
62.7 + <modelVersion>4.0.0</modelVersion>
62.8 +
62.9 + <groupId>${groupId}</groupId>
62.10 + <artifactId>${artifactId}</artifactId>
62.11 + <version>${version}</version>
62.12 + <packaging>jar</packaging>
62.13 +
62.14 + <name>${artifactId}</name>
62.15 +
62.16 + <properties>
62.17 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
62.18 + </properties>
62.19 + <build>
62.20 + <plugins>
62.21 + <plugin>
62.22 + <groupId>org.apidesign.bck2brwsr</groupId>
62.23 + <artifactId>mojo</artifactId>
62.24 + <version>0.3-SNAPSHOT</version>
62.25 + <executions>
62.26 + <execution>
62.27 + <goals>
62.28 + <goal>brwsr</goal>
62.29 + </goals>
62.30 + </execution>
62.31 + </executions>
62.32 + <configuration>
62.33 + <startpage>${package.replace('.','/')}/index.xhtml</startpage>
62.34 + </configuration>
62.35 + </plugin>
62.36 + <plugin>
62.37 + <groupId>org.apache.maven.plugins</groupId>
62.38 + <artifactId>maven-compiler-plugin</artifactId>
62.39 + <version>2.3.2</version>
62.40 + <configuration>
62.41 + <source>1.7</source>
62.42 + <target>1.7</target>
62.43 + </configuration>
62.44 + </plugin>
62.45 + </plugins>
62.46 + </build>
62.47 +
62.48 + <dependencies>
62.49 + <dependency>
62.50 + <groupId>org.apidesign.bck2brwsr</groupId>
62.51 + <artifactId>emul</artifactId>
62.52 + <version>0.3-SNAPSHOT</version>
62.53 + </dependency>
62.54 + <dependency>
62.55 + <groupId>org.apidesign.bck2brwsr</groupId>
62.56 + <artifactId>javaquery.api</artifactId>
62.57 + <version>0.3-SNAPSHOT</version>
62.58 + </dependency>
62.59 + </dependencies>
62.60 +</project>
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
63.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/java/App.java Fri Jan 18 14:27:22 2013 +0100
63.3 @@ -0,0 +1,17 @@
63.4 +package ${package};
63.5 +
63.6 +import org.apidesign.bck2brwsr.htmlpage.api.*;
63.7 +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*;
63.8 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
63.9 +
63.10 +/** Edit the index.xhtml file. Use 'id' to name certain HTML elements.
63.11 + * Use this class to define behavior of the elements.
63.12 + */
63.13 +@Page(xhtml="index.xhtml", className="Index")
63.14 +public class App {
63.15 + @On(event = CLICK, id="hello")
63.16 + static void hello() {
63.17 + Index.HELLO.setDisabled(true);
63.18 + Element.alert("Hello World!");
63.19 + }
63.20 +}
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
64.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/resources/index.xhtml Fri Jan 18 14:27:22 2013 +0100
64.3 @@ -0,0 +1,16 @@
64.4 +<?xml version="1.0" encoding="UTF-8"?>
64.5 +<!DOCTYPE html>
64.6 +<html xmlns="http://www.w3.org/1999/xhtml">
64.7 + <head>
64.8 + <title>Bck2Brwsr's Hello World</title>
64.9 + </head>
64.10 + <body>
64.11 + <button id="hello">Hello World!</button>
64.12 +
64.13 + <script src="/bck2brwsr.js"></script>
64.14 + <script src="/vm.js"></script>
64.15 + <script type="text/javascript">
64.16 + vm.loadClass('${package}.Index');
64.17 + </script>
64.18 + </body>
64.19 +</html>
65.1 --- a/pom.xml Fri Jan 18 14:23:18 2013 +0100
65.2 +++ b/pom.xml Fri Jan 18 14:27:22 2013 +0100
65.3 @@ -14,6 +14,8 @@
65.4 <module>javaquery</module>
65.5 <module>javap</module>
65.6 <module>benchmarks</module>
65.7 + <module>launcher</module>
65.8 + <module>vmtest</module>
65.9 </modules>
65.10 <licenses>
65.11 <license>
65.12 @@ -71,6 +73,8 @@
65.13 <exclude>javap/**</exclude>
65.14 <exclude>*</exclude>
65.15 <exclude>.*/**</exclude>
65.16 + <exclude>mojo/src/main/resources/archetype-resources/**</exclude>
65.17 + <exclude>vmtest/src/test/resources/**</exclude>
65.18 </excludes>
65.19 </configuration>
65.20 </plugin>
65.21 @@ -108,4 +112,4 @@
65.22 <properties>
65.23 <license>COPYING</license>
65.24 </properties>
65.25 -</project>
65.26 +</project>
65.27 \ No newline at end of file
66.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Fri Jan 18 14:23:18 2013 +0100
66.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Fri Jan 18 14:27:22 2013 +0100
66.3 @@ -37,7 +37,7 @@
66.4 * return null; // byte[] for the resource
66.5 * });
66.6 * </pre>
66.7 - * In this scenario, when a request for a unknown class is made, the loader
66.8 + * In this scenario, when a request for an unknown class is made, the loader
66.9 * function is asked for its byte code and the system dynamically transforms
66.10 * it to JavaScript.
66.11 *
67.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Jan 18 14:23:18 2013 +0100
67.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Jan 18 14:27:22 2013 +0100
67.3 @@ -26,6 +26,8 @@
67.4 import org.apidesign.javap.MethodData;
67.5 import org.apidesign.javap.StackMapIterator;
67.6 import static org.apidesign.javap.RuntimeConstants.*;
67.7 +import org.apidesign.javap.TrapData;
67.8 +import org.apidesign.javap.TrapDataIterator;
67.9
67.10 /** Translator of the code inside class files to JavaScript.
67.11 *
67.12 @@ -64,6 +66,17 @@
67.13 /* protected */ String accessClass(String classOperation) {
67.14 return classOperation;
67.15 }
67.16 +
67.17 + /** Prints out a debug message.
67.18 + *
67.19 + * @param msg the message
67.20 + * @return true if the message has been printed
67.21 + * @throws IOException
67.22 + */
67.23 + boolean debug(String msg) throws IOException {
67.24 + out.append(msg);
67.25 + return true;
67.26 + }
67.27
67.28 /**
67.29 * Converts a given class file to a JavaScript version.
67.30 @@ -76,6 +89,11 @@
67.31
67.32 public String compile(InputStream classFile) throws IOException {
67.33 this.jc = new ClassData(classFile);
67.34 + if (jc.getMajor_version() < 50) {
67.35 + throw new IOException("Can't compile " + jc.getClassName() + ". Class file version " + jc.getMajor_version() + "."
67.36 + + jc.getMinor_version() + " - recompile with -target 1.6 (at least)."
67.37 + );
67.38 + }
67.39 byte[] arrData = jc.findAnnotationData(true);
67.40 String[] arr = findAnnotation(arrData, jc,
67.41 "org.apidesign.bck2brwsr.core.ExtraJavaScript",
67.42 @@ -129,18 +147,27 @@
67.43 }
67.44 continue;
67.45 }
67.46 + String prefix;
67.47 String mn;
67.48 if (m.isStatic()) {
67.49 - mn = generateStaticMethod("\n c.", m, toInitilize);
67.50 + prefix = "\n c.";
67.51 + mn = generateStaticMethod(prefix, m, toInitilize);
67.52 } else {
67.53 - mn = generateInstanceMethod("\n c.", m);
67.54 + if (m.isConstructor()) {
67.55 + prefix = "\n CLS.";
67.56 + mn = generateInstanceMethod(prefix, m);
67.57 + } else {
67.58 + prefix = "\n c.";
67.59 + mn = generateInstanceMethod(prefix, m);
67.60 + }
67.61 }
67.62 byte[] runAnno = m.findAnnotationData(false);
67.63 if (runAnno != null) {
67.64 - out.append("\n c.").append(mn).append(".anno = {");
67.65 + out.append(prefix).append(mn).append(".anno = {");
67.66 generateAnno(jc, out, runAnno);
67.67 out.append("\n };");
67.68 }
67.69 + out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";");
67.70 }
67.71 out.append("\n c.constructor = CLS;");
67.72 out.append("\n c.$instOf_").append(className).append(" = true;");
67.73 @@ -151,6 +178,7 @@
67.74 out.append(accessClass("java_lang_Class(true);"));
67.75 out.append("\n CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
67.76 out.append("\n CLS.$class.superclass = sprcls;");
67.77 + out.append("\n CLS.$class.access = ").append(jc.getAccessFlags()+";");
67.78 out.append("\n CLS.$class.cnstr = CLS;");
67.79 byte[] classAnno = jc.findAnnotationData(false);
67.80 if (classAnno != null) {
67.81 @@ -217,17 +245,19 @@
67.82 private void generateMethod(String prefix, String name, MethodData m)
67.83 throws IOException {
67.84 final StackMapIterator stackMapIterator = m.createStackMapIterator();
67.85 + TrapDataIterator trap = m.getTrapDataIterator();
67.86 final LocalsMapper lmapper =
67.87 new LocalsMapper(stackMapIterator.getArguments());
67.88
67.89 out.append(prefix).append(name).append(" = function(");
67.90 - lmapper.outputArguments(out);
67.91 + lmapper.outputArguments(out, m.isStatic());
67.92 out.append(") {").append("\n");
67.93
67.94 final byte[] byteCodes = m.getCode();
67.95 if (byteCodes == null) {
67.96 out.append(" throw 'no code found for ")
67.97 - .append(m.getInternalSig()).append("';\n");
67.98 + .append(jc.getClassName()).append('.')
67.99 + .append(m.getName()).append("';\n");
67.100 out.append("};");
67.101 return;
67.102 }
67.103 @@ -246,6 +276,9 @@
67.104 out.append(';');
67.105 }
67.106 }
67.107 + if (!m.isStatic()) {
67.108 + out.append(" var ").append(" lcA0 = this;\n");
67.109 + }
67.110
67.111 // maxStack includes two stack positions for every pushed long / double
67.112 // so this might generate more stack variables than we need
67.113 @@ -263,18 +296,31 @@
67.114 }
67.115
67.116 int lastStackFrame = -1;
67.117 -
67.118 + TrapData[] previousTrap = null;
67.119 +
67.120 out.append("\n var gt = 0;\n for(;;) switch(gt) {\n");
67.121 for (int i = 0; i < byteCodes.length; i++) {
67.122 int prev = i;
67.123 stackMapIterator.advanceTo(i);
67.124 + boolean changeInCatch = trap.advanceTo(i);
67.125 + if (changeInCatch || lastStackFrame != stackMapIterator.getFrameIndex()) {
67.126 + if (previousTrap != null) {
67.127 + generateCatch(previousTrap);
67.128 + previousTrap = null;
67.129 + }
67.130 + }
67.131 if (lastStackFrame != stackMapIterator.getFrameIndex()) {
67.132 lastStackFrame = stackMapIterator.getFrameIndex();
67.133 lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
67.134 smapper.syncWithFrameStack(stackMapIterator.getFrameStack());
67.135 - out.append(" case " + i).append(": ");
67.136 + out.append(" case " + i).append(": ");
67.137 + changeInCatch = true;
67.138 } else {
67.139 - out.append(" /* " + i).append(" */ ");
67.140 + debug(" /* " + i + " */ ");
67.141 + }
67.142 + if (changeInCatch && trap.useTry()) {
67.143 + out.append("try {");
67.144 + previousTrap = trap.current();
67.145 }
67.146 final int c = readByte(byteCodes, i);
67.147 switch (c) {
67.148 @@ -449,7 +495,7 @@
67.149 emit(out, "@1 = @2;", lmapper.setD(3), smapper.popD());
67.150 break;
67.151 case opc_iadd:
67.152 - emit(out, "@1 += @2;", smapper.getI(1), smapper.popI());
67.153 + emit(out, "@1 = @1.add32(@2);", smapper.getI(1), smapper.popI());
67.154 break;
67.155 case opc_ladd:
67.156 emit(out, "@1 += @2;", smapper.getL(1), smapper.popL());
67.157 @@ -461,7 +507,7 @@
67.158 emit(out, "@1 += @2;", smapper.getD(1), smapper.popD());
67.159 break;
67.160 case opc_isub:
67.161 - emit(out, "@1 -= @2;", smapper.getI(1), smapper.popI());
67.162 + emit(out, "@1 = @1.sub32(@2);", smapper.getI(1), smapper.popI());
67.163 break;
67.164 case opc_lsub:
67.165 emit(out, "@1 -= @2;", smapper.getL(1), smapper.popL());
67.166 @@ -473,7 +519,7 @@
67.167 emit(out, "@1 -= @2;", smapper.getD(1), smapper.popD());
67.168 break;
67.169 case opc_imul:
67.170 - emit(out, "@1 *= @2;", smapper.getI(1), smapper.popI());
67.171 + emit(out, "@1 = @1.mul32(@2);", smapper.getI(1), smapper.popI());
67.172 break;
67.173 case opc_lmul:
67.174 emit(out, "@1 *= @2;", smapper.getL(1), smapper.popL());
67.175 @@ -630,9 +676,13 @@
67.176 smapper.popD(), smapper.pushL());
67.177 break;
67.178 case opc_i2b:
67.179 + emit(out, "@1 = @1.toInt8();", smapper.getI(0));
67.180 + break;
67.181 case opc_i2c:
67.182 + out.append("{ /* number conversion */ }");
67.183 + break;
67.184 case opc_i2s:
67.185 - out.append("/* number conversion */");
67.186 + emit(out, "@1 = @1.toInt16();", smapper.getI(0));
67.187 break;
67.188 case opc_aconst_null:
67.189 emit(out, "@1 = null;", smapper.pushA());
67.190 @@ -863,28 +913,53 @@
67.191 break;
67.192 }
67.193 case opc_newarray:
67.194 - ++i; // skip type of array
67.195 - emit(out, "@2 = new Array(@1).fillNulls();",
67.196 - smapper.popI(), smapper.pushA());
67.197 + int atype = readByte(byteCodes, ++i);
67.198 + String jvmType;
67.199 + switch (atype) {
67.200 + case 4: jvmType = "[Z"; break;
67.201 + case 5: jvmType = "[C"; break;
67.202 + case 6: jvmType = "[F"; break;
67.203 + case 7: jvmType = "[D"; break;
67.204 + case 8: jvmType = "[B"; break;
67.205 + case 9: jvmType = "[S"; break;
67.206 + case 10: jvmType = "[I"; break;
67.207 + case 11: jvmType = "[J"; break;
67.208 + default: throw new IllegalStateException("Array type: " + atype);
67.209 + }
67.210 + emit(out, "@2 = new Array(@1).initWith('@3', 0);",
67.211 + smapper.popI(), smapper.pushA(), jvmType);
67.212 break;
67.213 - case opc_anewarray:
67.214 - i += 2; // skip type of array
67.215 - emit(out, "@2 = new Array(@1).fillNulls();",
67.216 - smapper.popI(), smapper.pushA());
67.217 + case opc_anewarray: {
67.218 + int type = readIntArg(byteCodes, i);
67.219 + i += 2;
67.220 + String typeName = jc.getClassName(type);
67.221 + if (typeName.startsWith("[")) {
67.222 + typeName = "[" + typeName;
67.223 + } else {
67.224 + typeName = "[L" + typeName + ";";
67.225 + }
67.226 + emit(out, "@2 = new Array(@1).initWith('@3', null);",
67.227 + smapper.popI(), smapper.pushA(), typeName);
67.228 break;
67.229 + }
67.230 case opc_multianewarray: {
67.231 + int type = readIntArg(byteCodes, i);
67.232 i += 2;
67.233 + String typeName = jc.getClassName(type);
67.234 int dim = readByte(byteCodes, ++i);
67.235 out.append("{ var a0 = new Array(").append(smapper.popI())
67.236 - .append(").fillNulls();");
67.237 + .append(").initWith('").append(typeName).append("', null);");
67.238 for (int d = 1; d < dim; d++) {
67.239 + typeName = typeName.substring(1);
67.240 out.append("\n var l" + d).append(" = ")
67.241 .append(smapper.popI()).append(';');
67.242 out.append("\n for (var i" + d).append (" = 0; i" + d).
67.243 append(" < a" + (d - 1)).
67.244 append(".length; i" + d).append("++) {");
67.245 out.append("\n var a" + d).
67.246 - append (" = new Array(l" + d).append(").fillNulls();");
67.247 + append (" = new Array(l" + d).append(").initWith('")
67.248 + .append(typeName).append("', ")
67.249 + .append(typeName.length() == 2 ? "0" : "null").append(");");
67.250 out.append("\n a" + (d - 1)).append("[i" + d).append("] = a" + d).
67.251 append(";");
67.252 }
67.253 @@ -898,55 +973,55 @@
67.254 emit(out, "@2 = @1.length;", smapper.popA(), smapper.pushI());
67.255 break;
67.256 case opc_lastore:
67.257 - emit(out, "@3[@2] = @1;",
67.258 + emit(out, "@3.at(@2, @1);",
67.259 smapper.popL(), smapper.popI(), smapper.popA());
67.260 break;
67.261 case opc_fastore:
67.262 - emit(out, "@3[@2] = @1;",
67.263 + emit(out, "@3.at(@2, @1);",
67.264 smapper.popF(), smapper.popI(), smapper.popA());
67.265 break;
67.266 case opc_dastore:
67.267 - emit(out, "@3[@2] = @1;",
67.268 + emit(out, "@3.at(@2, @1);",
67.269 smapper.popD(), smapper.popI(), smapper.popA());
67.270 break;
67.271 case opc_aastore:
67.272 - emit(out, "@3[@2] = @1;",
67.273 + emit(out, "@3.at(@2, @1);",
67.274 smapper.popA(), smapper.popI(), smapper.popA());
67.275 break;
67.276 case opc_iastore:
67.277 case opc_bastore:
67.278 case opc_castore:
67.279 case opc_sastore:
67.280 - emit(out, "@3[@2] = @1;",
67.281 + emit(out, "@3.at(@2, @1);",
67.282 smapper.popI(), smapper.popI(), smapper.popA());
67.283 break;
67.284 case opc_laload:
67.285 - emit(out, "@3 = @2[@1];",
67.286 + emit(out, "@3 = @2.at(@1);",
67.287 smapper.popI(), smapper.popA(), smapper.pushL());
67.288 break;
67.289 case opc_faload:
67.290 - emit(out, "@3 = @2[@1];",
67.291 + emit(out, "@3 = @2.at(@1);",
67.292 smapper.popI(), smapper.popA(), smapper.pushF());
67.293 break;
67.294 case opc_daload:
67.295 - emit(out, "@3 = @2[@1];",
67.296 + emit(out, "@3 = @2.at(@1);",
67.297 smapper.popI(), smapper.popA(), smapper.pushD());
67.298 break;
67.299 case opc_aaload:
67.300 - emit(out, "@3 = @2[@1];",
67.301 + emit(out, "@3 = @2.at(@1);",
67.302 smapper.popI(), smapper.popA(), smapper.pushA());
67.303 break;
67.304 case opc_iaload:
67.305 case opc_baload:
67.306 case opc_caload:
67.307 case opc_saload:
67.308 - emit(out, "@3 = @2[@1];",
67.309 + emit(out, "@3 = @2.at(@1);",
67.310 smapper.popI(), smapper.popA(), smapper.pushI());
67.311 break;
67.312 case opc_pop:
67.313 case opc_pop2:
67.314 smapper.pop(1);
67.315 - out.append("/* pop */");
67.316 + debug("/* pop */");
67.317 break;
67.318 case opc_dup: {
67.319 final Variable v = smapper.get(0);
67.320 @@ -1024,7 +1099,7 @@
67.321 int indx = readIntArg(byteCodes, i);
67.322 String[] fi = jc.getFieldInfoName(indx);
67.323 final int type = VarType.fromFieldType(fi[2].charAt(0));
67.324 - emit(out, "@1 = @2.@3;",
67.325 + emit(out, "@1 = @2(false).constructor.@3;",
67.326 smapper.pushT(type),
67.327 accessClass(fi[0].replace('/', '_')), fi[1]);
67.328 i += 2;
67.329 @@ -1044,7 +1119,7 @@
67.330 int indx = readIntArg(byteCodes, i);
67.331 String[] fi = jc.getFieldInfoName(indx);
67.332 final int type = VarType.fromFieldType(fi[2].charAt(0));
67.333 - emit(out, "@1.@2 = @3;",
67.334 + emit(out, "@1(false).constructor.@2 = @3;",
67.335 accessClass(fi[0].replace('/', '_')), fi[1],
67.336 smapper.popT(type));
67.337 i += 2;
67.338 @@ -1099,13 +1174,17 @@
67.339 Integer.toString(c));
67.340 }
67.341 }
67.342 - out.append(" //");
67.343 - for (int j = prev; j <= i; j++) {
67.344 - out.append(" ");
67.345 - final int cc = readByte(byteCodes, j);
67.346 - out.append(Integer.toString(cc));
67.347 + if (debug(" //")) {
67.348 + for (int j = prev; j <= i; j++) {
67.349 + out.append(" ");
67.350 + final int cc = readByte(byteCodes, j);
67.351 + out.append(Integer.toString(cc));
67.352 + }
67.353 }
67.354 - out.append("\n");
67.355 + out.append("\n");
67.356 + }
67.357 + if (previousTrap != null) {
67.358 + generateCatch(previousTrap);
67.359 }
67.360 out.append(" }\n");
67.361 out.append("};");
67.362 @@ -1204,6 +1283,7 @@
67.363 returnType[0] = 'L';
67.364 }
67.365 i = next + 1;
67.366 + array = false;
67.367 continue;
67.368 case '[':
67.369 array = true;
67.370 @@ -1279,8 +1359,15 @@
67.371 final String in = mi[0];
67.372 out.append(accessClass(in.replace('/', '_')));
67.373 out.append("(false).");
67.374 + if (mn.startsWith("cons_")) {
67.375 + out.append("constructor.");
67.376 + }
67.377 out.append(mn);
67.378 - out.append('(');
67.379 + if (isStatic) {
67.380 + out.append('(');
67.381 + } else {
67.382 + out.append(".call(");
67.383 + }
67.384 if (numArguments > 0) {
67.385 out.append(vars[0]);
67.386 for (int j = 1; j < numArguments; ++j) {
67.387 @@ -1316,10 +1403,11 @@
67.388 out.append(vars[0]).append('.');
67.389 out.append(mn);
67.390 out.append('(');
67.391 - out.append(vars[0]);
67.392 + String sep = "";
67.393 for (int j = 1; j < numArguments; ++j) {
67.394 - out.append(", ");
67.395 + out.append(sep);
67.396 out.append(vars[j]);
67.397 + sep = ", ";
67.398 }
67.399 out.append(");");
67.400 i += 2;
67.401 @@ -1328,7 +1416,7 @@
67.402
67.403 private void addReference(String cn) throws IOException {
67.404 if (requireReference(cn)) {
67.405 - out.append(" /* needs ").append(cn).append(" */");
67.406 + debug(" /* needs " + cn + " */");
67.407 }
67.408 }
67.409
67.410 @@ -1393,15 +1481,8 @@
67.411 final String mn = findMethodName(m, cnt);
67.412 out.append(prefix).append(mn);
67.413 out.append(" = function(");
67.414 - String space;
67.415 - int index;
67.416 - if (!isStatic) {
67.417 - space = outputArg(out, p.args, 0);
67.418 - index = 1;
67.419 - } else {
67.420 - space = "";
67.421 - index = 0;
67.422 - }
67.423 + String space = "";
67.424 + int index = 0;
67.425 for (int i = 0; i < cnt.length(); i++) {
67.426 out.append(space);
67.427 space = outputArg(out, p.args, index);
67.428 @@ -1534,4 +1615,39 @@
67.429
67.430 out.append(format, processed, length);
67.431 }
67.432 +
67.433 + private void generateCatch(TrapData[] traps) throws IOException {
67.434 + out.append("} catch (e) {\n");
67.435 + int finallyPC = -1;
67.436 + for (TrapData e : traps) {
67.437 + if (e == null) {
67.438 + break;
67.439 + }
67.440 + if (e.catch_cpx != 0) { //not finally
67.441 + final String classInternalName = jc.getClassName(e.catch_cpx);
67.442 + addReference(classInternalName);
67.443 + if ("java/lang/Throwable".equals(classInternalName)) {
67.444 + out.append("if (e.$instOf_java_lang_Throwable) {");
67.445 + out.append(" stA0 = e;");
67.446 + out.append("} else {");
67.447 + out.append(" stA0 = vm.java_lang_Throwable(true);");
67.448 + out.append(" vm.java_lang_Throwable.cons__VLjava_lang_String_2.call(stA0, e.toString());");
67.449 + out.append("}");
67.450 + out.append("gt=" + e.handler_pc + "; continue;");
67.451 + } else {
67.452 + out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
67.453 + out.append("gt=" + e.handler_pc + "; stA0 = e; continue;");
67.454 + out.append("}\n");
67.455 + }
67.456 + } else {
67.457 + finallyPC = e.handler_pc;
67.458 + }
67.459 + }
67.460 + if (finallyPC == -1) {
67.461 + out.append("throw e;");
67.462 + } else {
67.463 + out.append("gt=" + finallyPC + "; stA0 = e; continue;");
67.464 + }
67.465 + out.append("\n}");
67.466 + }
67.467 }
68.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java Fri Jan 18 14:23:18 2013 +0100
68.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/LocalsMapper.java Fri Jan 18 14:27:22 2013 +0100
68.3 @@ -33,13 +33,14 @@
68.4 localTypeRecords = new TypeArray(initTypeRecords);
68.5 }
68.6
68.7 - public void outputArguments(final Appendable out) throws IOException {
68.8 + public void outputArguments(final Appendable out, boolean isStatic) throws IOException {
68.9 final int argRecordCount = argTypeRecords.getSize();
68.10 - if (argRecordCount > 0) {
68.11 - Variable variable = getVariable(argTypeRecords, 0);
68.12 + int first = isStatic ? 0 : 1;
68.13 + if (argRecordCount > first) {
68.14 + Variable variable = getVariable(argTypeRecords, first);
68.15 out.append(variable);
68.16
68.17 - int i = variable.isCategory2() ? 2 : 1;
68.18 + int i = first + (variable.isCategory2() ? 2 : 1);
68.19 while (i < argRecordCount) {
68.20 variable = getVariable(argTypeRecords, i);
68.21 out.append(", ");
69.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Fri Jan 18 14:23:18 2013 +0100
69.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Fri Jan 18 14:27:22 2013 +0100
69.3 @@ -33,6 +33,11 @@
69.4 // uses VMLazy to load dynamic classes
69.5 VMLazy.init();
69.6 }
69.7 +
69.8 + @Override
69.9 + boolean debug(String msg) throws IOException {
69.10 + return false;
69.11 + }
69.12
69.13 static void compile(Bck2Brwsr.Resources l, Appendable out, StringArray names) throws IOException {
69.14 new VM(out).doCompile(l, names);
69.15 @@ -112,12 +117,19 @@
69.16 + " var loader = {};\n"
69.17 + " loader.vm = vm;\n"
69.18 + " loader.loadClass = function(name) {\n"
69.19 - + " var attr = name.replace__Ljava_lang_String_2CC(name, '.','_');\n"
69.20 + + " var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
69.21 + " var fn = vm[attr];\n"
69.22 + " if (fn) return fn(false);\n"
69.23 + " if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
69.24 + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
69.25 - + " load___3Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
69.26 + + " load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
69.27 + + " }\n"
69.28 + + " if (args[0]) {\n"
69.29 + + " vm.loadClass = loader.loadClass;\n"
69.30 + + " vm.loadBytes = function(name) {\n"
69.31 + + " if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
69.32 + + " return args[0](name);\n"
69.33 + + " }\n"
69.34 + " }\n"
69.35 + " return loader;\n"
69.36 + " };\n");
70.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Fri Jan 18 14:23:18 2013 +0100
70.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Fri Jan 18 14:27:22 2013 +0100
70.3 @@ -47,10 +47,10 @@
70.4
70.5 static Object load(Object loader, String name, Object[] arguments)
70.6 throws IOException, ClassNotFoundException {
70.7 - return new VMLazy(loader, arguments).load(name);
70.8 + return new VMLazy(loader, arguments).load(name, false);
70.9 }
70.10
70.11 - private Object load(String name)
70.12 + private Object load(String name, boolean instance)
70.13 throws IOException, ClassNotFoundException {
70.14 String res = name.replace('.', '/') + ".class";
70.15 byte[] arr = read(loader, res, args);
70.16 @@ -61,10 +61,27 @@
70.17 StringBuilder out = new StringBuilder();
70.18 out.append("var loader = arguments[0];\n");
70.19 out.append("var vm = loader.vm;\n");
70.20 - new Gen(this, out).compile(new ByteArrayInputStream(arr));
70.21 + int prelude = out.length();
70.22 + String initCode = new Gen(this, out).compile(new ByteArrayInputStream(arr));
70.23 String code = out.toString().toString();
70.24 +// dump("Loading " + name);
70.25 + dump(code);
70.26 String under = name.replace('.', '_');
70.27 - return applyCode(loader, under, code);
70.28 + Object fn = applyCode(loader, under, code, instance);
70.29 +
70.30 + if (!initCode.isEmpty()) {
70.31 + out.setLength(prelude);
70.32 + out.append(initCode);
70.33 + code = out.toString().toString();
70.34 + dump(code);
70.35 + applyCode(loader, null, code, false);
70.36 + }
70.37 +
70.38 + return fn;
70.39 + }
70.40 +
70.41 +// @JavaScriptBody(args = "s", body = "java.lang.System.out.println(s.toString());")
70.42 + static void dump(String s) {
70.43 }
70.44
70.45 /* possibly not needed:
70.46 @@ -76,15 +93,15 @@
70.47 */
70.48
70.49
70.50 - @JavaScriptBody(args = {"loader", "name", "script" }, body =
70.51 + @JavaScriptBody(args = {"loader", "name", "script", "instance" }, body =
70.52 "try {\n" +
70.53 " new Function(script)(loader, name);\n" +
70.54 "} catch (ex) {\n" +
70.55 " throw 'Cannot compile ' + ex + ' line: ' + ex.lineNumber + ' script:\\n' + script;\n" +
70.56 "}\n" +
70.57 - "return vm[name](false);\n"
70.58 + "return name != null ? vm[name](instance) : null;\n"
70.59 )
70.60 - private static native Object applyCode(Object loader, String name, String script);
70.61 + private static native Object applyCode(Object loader, String name, String script, boolean instance);
70.62
70.63
70.64 private static final class Gen extends ByteCodeToJavaScript {
70.65 @@ -95,16 +112,17 @@
70.66 this.lazy = vm;
70.67 }
70.68
70.69 - @JavaScriptBody(args = {"self", "n"},
70.70 + @JavaScriptBody(args = {"n"},
70.71 body =
70.72 - "var cls = n.replace__Ljava_lang_String_2CC(n, '/','_').toString();"
70.73 - + "\nvar dot = n.replace__Ljava_lang_String_2CC(n,'/','.').toString();"
70.74 - + "\nvar lazy = self.fld_lazy;"
70.75 + "var cls = n.replace__Ljava_lang_String_2CC('/','_').toString();"
70.76 + + "\nvar dot = n.replace__Ljava_lang_String_2CC('/','.').toString();"
70.77 + + "\nvar lazy = this.fld_lazy;"
70.78 + "\nvar loader = lazy.fld_loader;"
70.79 + "\nvar vm = loader.vm;"
70.80 + "\nif (vm[cls]) return false;"
70.81 + "\nvm[cls] = function() {"
70.82 - + "\n return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2(lazy, dot);"
70.83 + + "\n var instance = arguments.length == 0 || arguments[0] === true;"
70.84 + + "\n return lazy.load__Ljava_lang_Object_2Ljava_lang_String_2Z(dot, instance);"
70.85 + "\n};"
70.86 + "\nreturn true;")
70.87 @Override
71.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Array.java Fri Jan 18 14:23:18 2013 +0100
71.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Array.java Fri Jan 18 14:27:22 2013 +0100
71.3 @@ -51,6 +51,16 @@
71.4 return doubles[4][0];
71.5 }
71.6
71.7 + static double[][] dbls = new double[1][2];
71.8 + public static double twoDoubles() {
71.9 + return dbls[0][0] + dbls[0][0];
71.10 + }
71.11 +
71.12 + static int[][] tints = new int[1][2];
71.13 + public static int twoInts() {
71.14 + return tints[0][0] + tints[0][0];
71.15 + }
71.16 +
71.17 private static final Array[] ARR = { new Array(), new Array(), new Array() };
71.18
71.19 private static Array[][] arr() {
71.20 @@ -82,16 +92,27 @@
71.21 }
71.22 return sum;
71.23 }
71.24 - public static int simple() {
71.25 - int[] arr = { 0, 1, 2, 3, 4, 5 };
71.26 + private static final int[] arr = { 0, 1, 2, 3, 4, 5 };
71.27 + public static int simple(boolean clone) {
71.28 + int[] ar;
71.29 + if (clone) {
71.30 + ar = arr.clone();
71.31 + } else {
71.32 + ar = arr;
71.33 + }
71.34
71.35 int sum = 0;
71.36 - for (int a : arr) {
71.37 + for (int a : ar) {
71.38 sum += a;
71.39 }
71.40 return sum;
71.41 }
71.42
71.43 + public static int sum(int size) {
71.44 + int[] arr = new int[size];
71.45 + return arr[0] + arr[1];
71.46 + }
71.47 +
71.48 static void arraycopy(char[] value, int srcBegin, char[] dst, int dstBegin, int count) {
71.49 while (count-- > 0) {
71.50 dst[dstBegin++] = value[srcBegin++];
72.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Fri Jan 18 14:23:18 2013 +0100
72.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Fri Jan 18 14:27:22 2013 +0100
72.3 @@ -18,7 +18,6 @@
72.4 package org.apidesign.vm4brwsr;
72.5
72.6 import javax.script.Invocable;
72.7 -import javax.script.ScriptException;
72.8 import static org.testng.Assert.*;
72.9 import org.testng.annotations.BeforeClass;
72.10 import org.testng.annotations.Test;
72.11 @@ -28,9 +27,20 @@
72.12 * @author Jaroslav Tulach <jtulach@netbeans.org>
72.13 */
72.14 public class ArrayTest {
72.15 + @Test public void intArrayShouldBeFilledWithZeroes() throws Exception {
72.16 + assertExec("0 + 0", Array.class, "sum__II",
72.17 + Double.valueOf(0), 2
72.18 + );
72.19 + }
72.20 @Test public void verifySimpleIntOperation() throws Exception {
72.21 - assertExec("CheckTheSum", Array.class, "simple__I",
72.22 - Double.valueOf(15)
72.23 + assertExec("CheckTheSum", Array.class, "simple__IZ",
72.24 + Double.valueOf(15), false
72.25 + );
72.26 + }
72.27 +
72.28 + @Test public void cloneOnArray() throws Exception {
72.29 + assertExec("CheckTheSum on clone", Array.class, "simple__IZ",
72.30 + Double.valueOf(15), true
72.31 );
72.32 }
72.33
72.34 @@ -43,6 +53,17 @@
72.35 Double.valueOf(105)
72.36 );
72.37 }
72.38 +
72.39 + @Test public void twoDoubles() throws Exception {
72.40 + assertExec("Elements are initialized", Array.class, "twoDoubles__D",
72.41 + Double.valueOf(0)
72.42 + );
72.43 + }
72.44 + @Test public void twoInts() throws Exception {
72.45 + assertExec("Elements are initialized", Array.class, "twoInts__I",
72.46 + Double.valueOf(0)
72.47 + );
72.48 + }
72.49
72.50 @Test public void doesCopyArrayWork() throws Exception {
72.51 assertExec("Returns 'a'", Array.class, "copyArray__C", Double.valueOf('a'));
73.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/BytesLoader.java Fri Jan 18 14:23:18 2013 +0100
73.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/BytesLoader.java Fri Jan 18 14:27:22 2013 +0100
73.3 @@ -19,6 +19,8 @@
73.4
73.5 import java.io.IOException;
73.6 import java.io.InputStream;
73.7 +import java.net.URL;
73.8 +import java.util.Enumeration;
73.9 import java.util.Set;
73.10 import java.util.TreeSet;
73.11
73.12 @@ -33,15 +35,7 @@
73.13 if (!requested.add(name)) {
73.14 throw new IllegalStateException("Requested for second time: " + name);
73.15 }
73.16 - InputStream is = BytesLoader.class.getClassLoader().getResourceAsStream(name);
73.17 - if (is == null) {
73.18 - throw new IOException("Can't find " + name);
73.19 - }
73.20 - byte[] arr = new byte[is.available()];
73.21 - int len = is.read(arr);
73.22 - if (len != arr.length) {
73.23 - throw new IOException("Read only " + len + " wanting " + arr.length);
73.24 - }
73.25 + byte[] arr = readClass(name);
73.26 /*
73.27 System.err.print("loader['" + name + "'] = [");
73.28 for (int i = 0; i < arr.length; i++) {
73.29 @@ -54,5 +48,29 @@
73.30 */
73.31 return arr;
73.32 }
73.33 +
73.34 + static byte[] readClass(String name) throws IOException {
73.35 + URL u = null;
73.36 + Enumeration<URL> en = BytesLoader.class.getClassLoader().getResources(name);
73.37 + while (en.hasMoreElements()) {
73.38 + u = en.nextElement();
73.39 + }
73.40 + if (u == null) {
73.41 + throw new IOException("Can't find " + name);
73.42 + }
73.43 + try (InputStream is = u.openStream()) {
73.44 + byte[] arr;
73.45 + arr = new byte[is.available()];
73.46 + int offset = 0;
73.47 + while (offset < arr.length) {
73.48 + int len = is.read(arr, offset, arr.length - offset);
73.49 + if (len == -1) {
73.50 + throw new IOException("Can't read " + name);
73.51 + }
73.52 + offset += len;
73.53 + }
73.54 + return arr;
73.55 + }
73.56 + }
73.57
73.58 }
74.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Fri Jan 18 14:23:18 2013 +0100
74.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Fri Jan 18 14:27:22 2013 +0100
74.3 @@ -74,6 +74,16 @@
74.4 @Test public void jsNewInstance() throws Exception {
74.5 assertExec("Check new instance", Classes.class, "newInstance__Z", Double.valueOf(1));
74.6 }
74.7 + @Test public void javaNoNewInstance() throws Exception {
74.8 + assertEquals("java.lang.InstantiationException:java.lang.Float",
74.9 + Classes.newInstanceNoPubConstructor()
74.10 + );
74.11 + }
74.12 + @Test public void jsNoNewInstance() throws Exception {
74.13 + assertExec("Check problems with new instance", Classes.class, "newInstanceNoPubConstructor__Ljava_lang_String_2",
74.14 + "java.lang.InstantiationException:java.lang.Float"
74.15 + );
74.16 + }
74.17 @Test public void jsAnnotation() throws Exception {
74.18 assertExec("Check class annotation", Classes.class, "getMarker__I", Double.valueOf(10));
74.19 }
74.20 @@ -92,6 +102,11 @@
74.21 "java.io.IOException", true, "name"
74.22 );
74.23 }
74.24 + @Test public void jsInvokeParamMethod() throws Exception {
74.25 + assertExec("sums two numbers via reflection", Classes.class,
74.26 + "reflectiveSum__III", Double.valueOf(5), 2, 3
74.27 + );
74.28 + }
74.29 @Test public void javaFindMethod() throws Exception {
74.30 assertEquals(Classes.reflectiveMethodCall(false, "name"), "java.io.IOException", "Calls the name() method via reflection");
74.31 }
74.32 @@ -101,6 +116,18 @@
74.33 "java.io.IOException", false, "name"
74.34 );
74.35 }
74.36 + @Test public void primitiveReturnType() throws Exception {
74.37 + assertExec("Tries to get an integer via reflection", Classes.class,
74.38 + "primitiveType__Ljava_lang_String_2Ljava_lang_String_2",
74.39 + Classes.primitiveType("primitive"), "primitive"
74.40 + );
74.41 + }
74.42 + @Test public void primitiveBoolReturnType() throws Exception {
74.43 + assertExec("Tries to get an integer via reflection", Classes.class,
74.44 + "primitiveType__Ljava_lang_String_2Ljava_lang_String_2",
74.45 + Classes.primitiveType("primitiveB"), "primitiveB"
74.46 + );
74.47 + }
74.48 @Test public void javaAnnotatedMethod() throws Exception {
74.49 assertEquals(Classes.reflectiveMethodCall(false, null), "java.io.IOException", "Calls the name() method via reflection");
74.50 }
74.51 @@ -116,6 +143,26 @@
74.52 "java.io.IOException"
74.53 );
74.54 }
74.55 + @Test public void noInterface() throws Exception {
74.56 + assertExec("Calls Class.isInterface", Classes.class,
74.57 + "isInterface__ZLjava_lang_String_2",
74.58 + 0.0, "java.lang.String"
74.59 + );
74.60 + }
74.61 + /*
74.62 + @Test public void isInterface() throws Exception {
74.63 + assertExec("Calls Class.isInterface", Classes.class,
74.64 + "isInterface__ZLjava_lang_String_2",
74.65 + 1.0, "java.lang.Runnable"
74.66 + );
74.67 + }
74.68 + */
74.69 + @Test public void integerType() throws Exception {
74.70 + assertExec("Computes the type", Classes.class,
74.71 + "intType__Ljava_lang_String_2",
74.72 + Classes.intType()
74.73 + );
74.74 + }
74.75
74.76 private static CharSequence codeSeq;
74.77 private static Invocable code;
75.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Fri Jan 18 14:23:18 2013 +0100
75.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Fri Jan 18 14:27:22 2013 +0100
75.3 @@ -38,6 +38,10 @@
75.4 return c.getName();
75.5 }
75.6
75.7 + public static boolean isInterface(String s) throws ClassNotFoundException {
75.8 + return Class.forName(s).isInterface();
75.9 + }
75.10 +
75.11 public static boolean equalsClassesOfExceptions() {
75.12 return MalformedURLException.class.getSuperclass() == IOException.class;
75.13 }
75.14 @@ -68,6 +72,14 @@
75.15 }
75.16 throw new IllegalStateException("Not a subtype: " + ioe);
75.17 }
75.18 + public static String newInstanceNoPubConstructor() throws Exception {
75.19 + try {
75.20 + Float f = Float.class.newInstance();
75.21 + return "wrong, can't instantiate: " + f;
75.22 + } catch (Exception ex) {
75.23 + return (ex.getClass().getName() + ":" + ex.getMessage()).toString().toString();
75.24 + }
75.25 + }
75.26 public static int getMarker() {
75.27 if (!Classes.class.isAnnotationPresent(ClassesMarker.class)) {
75.28 return -2;
75.29 @@ -88,6 +100,21 @@
75.30 return null;
75.31 }
75.32
75.33 + public static String intType() {
75.34 + return Integer.TYPE.getName();
75.35 + }
75.36 +
75.37 + public static int primitive() {
75.38 + return 1;
75.39 + }
75.40 + public static boolean primitiveB() {
75.41 + return true;
75.42 + }
75.43 +
75.44 + public static String primitiveType(String method) throws Exception {
75.45 + return reflectiveMethodCall(false, method).getClass().getName();
75.46 + }
75.47 +
75.48 @JavaScriptBody(args = "msg", body = "throw msg;")
75.49 private static native void thrw(String msg);
75.50
75.51 @@ -119,4 +146,9 @@
75.52 }
75.53 return find.invoke(null);
75.54 }
75.55 +
75.56 + public static int reflectiveSum(int a, int b) throws Exception {
75.57 + Method m = StaticMethod.class.getMethod("sum", int.class, int.class);
75.58 + return (int) m.invoke(null, a, b);
75.59 + }
75.60 }
76.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Compare.java Fri Jan 18 14:23:18 2013 +0100
76.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
76.3 @@ -1,36 +0,0 @@
76.4 -/**
76.5 - * Back 2 Browser Bytecode Translator
76.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
76.7 - *
76.8 - * This program is free software: you can redistribute it and/or modify
76.9 - * it under the terms of the GNU General Public License as published by
76.10 - * the Free Software Foundation, version 2 of the License.
76.11 - *
76.12 - * This program is distributed in the hope that it will be useful,
76.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
76.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76.15 - * GNU General Public License for more details.
76.16 - *
76.17 - * You should have received a copy of the GNU General Public License
76.18 - * along with this program. Look for COPYING file in the top folder.
76.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
76.20 - */
76.21 -package org.apidesign.vm4brwsr;
76.22 -
76.23 -import java.lang.annotation.ElementType;
76.24 -import java.lang.annotation.Retention;
76.25 -import java.lang.annotation.RetentionPolicy;
76.26 -import java.lang.annotation.Target;
76.27 -
76.28 -/** Can be applied on a method that yields a return value.
76.29 - * Together with {@link VMCompare#create} it can be used to write
76.30 - * methods which are executed in real as well as JavaScript VMs and
76.31 - * their results are compared.
76.32 - *
76.33 - * @author Jaroslav Tulach <jtulach@netbeans.org>
76.34 - */
76.35 -@Retention(RetentionPolicy.RUNTIME)
76.36 -@Target(ElementType.METHOD)
76.37 -public @interface Compare {
76.38 -
76.39 -}
77.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/CompareVMs.java Fri Jan 18 14:23:18 2013 +0100
77.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
77.3 @@ -1,197 +0,0 @@
77.4 -/**
77.5 - * Back 2 Browser Bytecode Translator
77.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
77.7 - *
77.8 - * This program is free software: you can redistribute it and/or modify
77.9 - * it under the terms of the GNU General Public License as published by
77.10 - * the Free Software Foundation, version 2 of the License.
77.11 - *
77.12 - * This program is distributed in the hope that it will be useful,
77.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
77.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77.15 - * GNU General Public License for more details.
77.16 - *
77.17 - * You should have received a copy of the GNU General Public License
77.18 - * along with this program. Look for COPYING file in the top folder.
77.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
77.20 - */
77.21 -package org.apidesign.vm4brwsr;
77.22 -
77.23 -import java.lang.reflect.Method;
77.24 -import java.util.Map;
77.25 -import java.util.WeakHashMap;
77.26 -import javax.script.Invocable;
77.27 -import javax.script.ScriptContext;
77.28 -import javax.script.ScriptEngine;
77.29 -import javax.script.ScriptEngineManager;
77.30 -import org.testng.Assert;
77.31 -import org.testng.ITest;
77.32 -import org.testng.annotations.Factory;
77.33 -import org.testng.annotations.Test;
77.34 -
77.35 -/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
77.36 - * in provided class and builds set of tests that compare the computations
77.37 - * in real as well as JavaScript virtual machines. Use as:<pre>
77.38 - * {@code @}{@link Factory} public static create() {
77.39 - * return @{link CompareVMs}.{@link #create(YourClass.class);
77.40 - * }</pre>
77.41 - *
77.42 - * @author Jaroslav Tulach <jtulach@netbeans.org>
77.43 - */
77.44 -public final class CompareVMs implements ITest {
77.45 - private final Run first, second;
77.46 - private final Method m;
77.47 -
77.48 - private CompareVMs(Method m, Run first, Run second) {
77.49 - this.first = first;
77.50 - this.second = second;
77.51 - this.m = m;
77.52 - }
77.53 -
77.54 - public static Object[] create(Class<?> clazz) {
77.55 - Method[] arr = clazz.getMethods();
77.56 - Object[] ret = new Object[3 * arr.length];
77.57 - int cnt = 0;
77.58 - for (Method m : arr) {
77.59 - Compare c = m.getAnnotation(Compare.class);
77.60 - if (c == null) {
77.61 - continue;
77.62 - }
77.63 - final Run real = new Run(m, false);
77.64 - final Run js = new Run(m, true);
77.65 - ret[cnt++] = real;
77.66 - ret[cnt++] = js;
77.67 - ret[cnt++] = new CompareVMs(m, real, js);
77.68 - }
77.69 - Object[] r = new Object[cnt];
77.70 - for (int i = 0; i < cnt; i++) {
77.71 - r[i] = ret[i];
77.72 - }
77.73 - return r;
77.74 - }
77.75 -
77.76 - @Test(dependsOnGroups = "run") public void compareResults() throws Throwable {
77.77 - Object v1 = first.value;
77.78 - Object v2 = second.value;
77.79 - if (v1 instanceof Number) {
77.80 - v1 = ((Number)v1).doubleValue();
77.81 - }
77.82 - Assert.assertEquals(v2, v1, "Comparing results");
77.83 - }
77.84 -
77.85 - @Override
77.86 - public String getTestName() {
77.87 - return m.getName() + "[Compare]";
77.88 - }
77.89 -
77.90 - public static final class Run implements ITest {
77.91 - private final Method m;
77.92 - private final boolean js;
77.93 - Object value;
77.94 - private Invocable code;
77.95 - private CharSequence codeSeq;
77.96 - private static final Map<Class,Object[]> compiled = new WeakHashMap<Class,Object[]>();
77.97 -
77.98 - private Run(Method m, boolean js) {
77.99 - this.m = m;
77.100 - this.js = js;
77.101 - }
77.102 -
77.103 - private void compileTheCode(Class<?> clazz) throws Exception {
77.104 - final Object[] data = compiled.get(clazz);
77.105 - if (data != null) {
77.106 - code = (Invocable) data[0];
77.107 - codeSeq = (CharSequence) data[1];
77.108 - return;
77.109 - }
77.110 - StringBuilder sb = new StringBuilder();
77.111 - Bck2Brwsr.generate(sb, CompareVMs.class.getClassLoader());
77.112 -
77.113 - ScriptEngineManager sem = new ScriptEngineManager();
77.114 - ScriptEngine js = sem.getEngineByExtension("js");
77.115 - js.getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
77.116 -
77.117 - sb.append("\nfunction initVM() {"
77.118 - + "\n return bck2brwsr("
77.119 - + "\n function(name) { return loader.get(name);}"
77.120 - + "\n );"
77.121 - + "\n};");
77.122 -
77.123 - Object res = js.eval(sb.toString());
77.124 - Assert.assertTrue(js instanceof Invocable, "It is invocable object: " + res);
77.125 - code = (Invocable) js;
77.126 - codeSeq = sb;
77.127 - compiled.put(clazz, new Object[] { code, codeSeq });
77.128 - }
77.129 -
77.130 - @Test(groups = "run") public void executeCode() throws Throwable {
77.131 - if (js) {
77.132 - try {
77.133 - compileTheCode(m.getDeclaringClass());
77.134 - Object vm = code.invokeFunction("initVM");
77.135 - Object inst = code.invokeMethod(vm, "loadClass", m.getDeclaringClass().getName());
77.136 - value = code.invokeMethod(inst, m.getName() + "__" + computeSignature(m));
77.137 - } catch (Exception ex) {
77.138 - throw new AssertionError(StaticMethodTest.dumpJS(codeSeq)).initCause(ex);
77.139 - }
77.140 - } else {
77.141 - value = m.invoke(m.getDeclaringClass().newInstance());
77.142 - }
77.143 - }
77.144 - @Override
77.145 - public String getTestName() {
77.146 - return m.getName() + (js ? "[JavaScript]" : "[Java]");
77.147 - }
77.148 -
77.149 - private static String computeSignature(Method m) {
77.150 - StringBuilder sb = new StringBuilder();
77.151 - appendType(sb, m.getReturnType());
77.152 - for (Class<?> c : m.getParameterTypes()) {
77.153 - appendType(sb, c);
77.154 - }
77.155 - return sb.toString();
77.156 - }
77.157 -
77.158 - private static void appendType(StringBuilder sb, Class<?> t) {
77.159 - if (t == null) {
77.160 - sb.append('V');
77.161 - return;
77.162 - }
77.163 - if (t.isPrimitive()) {
77.164 - int ch = -1;
77.165 - if (t == int.class) {
77.166 - ch = 'I';
77.167 - }
77.168 - if (t == short.class) {
77.169 - ch = 'S';
77.170 - }
77.171 - if (t == byte.class) {
77.172 - ch = 'B';
77.173 - }
77.174 - if (t == boolean.class) {
77.175 - ch = 'Z';
77.176 - }
77.177 - if (t == long.class) {
77.178 - ch = 'J';
77.179 - }
77.180 - if (t == float.class) {
77.181 - ch = 'F';
77.182 - }
77.183 - if (t == double.class) {
77.184 - ch = 'D';
77.185 - }
77.186 - assert ch != -1 : "Unknown primitive type " + t;
77.187 - sb.append((char)ch);
77.188 - return;
77.189 - }
77.190 - if (t.isArray()) {
77.191 - sb.append("_3");
77.192 - appendType(sb, t.getComponentType());
77.193 - return;
77.194 - }
77.195 - sb.append('L');
77.196 - sb.append(t.getName().replace('.', '_'));
77.197 - sb.append("_2");
77.198 - }
77.199 - }
77.200 -}
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java Fri Jan 18 14:27:22 2013 +0100
78.3 @@ -0,0 +1,88 @@
78.4 +/**
78.5 + * Back 2 Browser Bytecode Translator
78.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
78.7 + *
78.8 + * This program is free software: you can redistribute it and/or modify
78.9 + * it under the terms of the GNU General Public License as published by
78.10 + * the Free Software Foundation, version 2 of the License.
78.11 + *
78.12 + * This program is distributed in the hope that it will be useful,
78.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
78.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
78.15 + * GNU General Public License for more details.
78.16 + *
78.17 + * You should have received a copy of the GNU General Public License
78.18 + * along with this program. Look for COPYING file in the top folder.
78.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
78.20 + */
78.21 +package org.apidesign.vm4brwsr;
78.22 +
78.23 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
78.24 +
78.25 +/**
78.26 + *
78.27 + * @author tom
78.28 + */
78.29 +public class Exceptions {
78.30 + private Exceptions() {
78.31 + }
78.32 +
78.33 + public static int methodWithTryCatchNoThrow() {
78.34 + int res = 0;
78.35 + try {
78.36 + res = 1;
78.37 + } catch (IllegalArgumentException e) {
78.38 + res = 2;
78.39 + }
78.40 + //join point
78.41 + return res;
78.42 + }
78.43 +
78.44 + public static int methodWithTryCatchThrow() {
78.45 + int res = 0;
78.46 + try {
78.47 + res = 1;
78.48 + throw new IllegalArgumentException();
78.49 + } catch (IllegalArgumentException e) {
78.50 + res = 2;
78.51 + }
78.52 + //join point
78.53 + return res;
78.54 + }
78.55 +
78.56 + @JavaScriptBody(args = "msg", body = "throw msg;")
78.57 + public static void thrw(String msg) {}
78.58 +
78.59 + public static String catchThrowableCatchesAll() {
78.60 + try {
78.61 + thrw("Hello!");
78.62 + return "Not here!";
78.63 + } catch (Throwable ex) {
78.64 + return ex.getMessage();
78.65 + }
78.66 + }
78.67 +
78.68 + public static String newInstance(String n) {
78.69 + try {
78.70 + Class c;
78.71 + try {
78.72 + c = Class.forName(n);
78.73 + } catch (ClassNotFoundException ex) {
78.74 + return ("CNFE:" + ex.getMessage()).toString();
78.75 + }
78.76 + return c.newInstance().getClass().getName();
78.77 + } catch (InstantiationException | IllegalAccessException ex) {
78.78 + return ex.getMessage();
78.79 + }
78.80 + }
78.81 +
78.82 + private static int counter;
78.83 + public static int readCounter(String n) throws ClassNotFoundException {
78.84 + try {
78.85 + Class.forName(n);
78.86 + } finally {
78.87 + counter++;
78.88 + }
78.89 + return counter;
78.90 + }
78.91 +}
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
79.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java Fri Jan 18 14:27:22 2013 +0100
79.3 @@ -0,0 +1,121 @@
79.4 +/**
79.5 + * Back 2 Browser Bytecode Translator
79.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
79.7 + *
79.8 + * This program is free software: you can redistribute it and/or modify
79.9 + * it under the terms of the GNU General Public License as published by
79.10 + * the Free Software Foundation, version 2 of the License.
79.11 + *
79.12 + * This program is distributed in the hope that it will be useful,
79.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
79.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79.15 + * GNU General Public License for more details.
79.16 + *
79.17 + * You should have received a copy of the GNU General Public License
79.18 + * along with this program. Look for COPYING file in the top folder.
79.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
79.20 + */
79.21 +package org.apidesign.vm4brwsr;
79.22 +
79.23 +import javax.script.Invocable;
79.24 +import javax.script.ScriptException;
79.25 +import static org.testng.Assert.*;
79.26 +import org.testng.annotations.BeforeClass;
79.27 +import org.testng.annotations.Test;
79.28 +
79.29 +/**
79.30 + *
79.31 + * @author Tomas Zezula <tzezula@netbeans.org>
79.32 + */
79.33 +public class ExceptionsTest {
79.34 + @Test
79.35 + public void verifyMethodWithTryCatchNoThrow() throws Exception {
79.36 + assertExec(
79.37 + "No throw",
79.38 + Exceptions.class,
79.39 + "methodWithTryCatchNoThrow__I",
79.40 + new Double(1.0));
79.41 + }
79.42 +
79.43 + @Test
79.44 + public void catchJavaScriptStringAsThrowable() throws Exception {
79.45 + assertExec(
79.46 + "Throw hello!",
79.47 + Exceptions.class,
79.48 + "catchThrowableCatchesAll__Ljava_lang_String_2",
79.49 + "Hello!"
79.50 + );
79.51 + }
79.52 +
79.53 + @Test
79.54 + public void verifyMethodWithTryCatchThrow() throws Exception {
79.55 + assertExec(
79.56 + "Throw",
79.57 + Exceptions.class,
79.58 + "methodWithTryCatchThrow__I",
79.59 + new Double(2.0));
79.60 + }
79.61 +
79.62 + @Test public void createObject() throws Exception {
79.63 + assertExec("Object created", Exceptions.class,
79.64 + "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
79.65 + "java.lang.Object",
79.66 + "java.lang.Object"
79.67 + );
79.68 + }
79.69 +
79.70 + @Test public void createFloatFails() throws Exception {
79.71 + assertExec("Float not created", Exceptions.class,
79.72 + "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
79.73 + "java.lang.Float",
79.74 + "java.lang.Float"
79.75 + );
79.76 + }
79.77 +
79.78 + @Test public void createUnknownFails() throws Exception {
79.79 + assertExec("Object created", Exceptions.class,
79.80 + "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
79.81 + "CNFE:org.apidesign.Unknown",
79.82 + "org.apidesign.Unknown"
79.83 + );
79.84 + }
79.85 +
79.86 + @Test public void testThreeCalls() throws Exception {
79.87 + Object vm = code.invokeFunction("bck2brwsr");
79.88 + Object clazz = code.invokeMethod(vm, "loadClass", Exceptions.class.getName());
79.89 +
79.90 + String method = "readCounter__ILjava_lang_String_2";
79.91 +
79.92 + try {
79.93 + Object ret = code.invokeMethod(clazz, method, "org.apidesign.Unknown");
79.94 + fail("We expect an CNFE!");
79.95 + } catch (ScriptException scriptException) {
79.96 + // script exception should be OK
79.97 + }
79.98 + {
79.99 + // 2nd invocation
79.100 + Object ret = code.invokeMethod(clazz, method, "java.lang.String");
79.101 + assertEquals(ret, Double.valueOf(2));
79.102 + }
79.103 + {
79.104 + // 3rd invocation
79.105 + Object ret = code.invokeMethod(clazz, method, "java.lang.Integer");
79.106 + assertEquals(ret, Double.valueOf(3));
79.107 + }
79.108 + }
79.109 +
79.110 + private static CharSequence codeSeq;
79.111 + private static Invocable code;
79.112 +
79.113 + @BeforeClass
79.114 + public void compileTheCode() throws Exception {
79.115 + StringBuilder sb = new StringBuilder();
79.116 + code = StaticMethodTest.compileClass(sb,
79.117 + "org/apidesign/vm4brwsr/Exceptions"
79.118 + );
79.119 + codeSeq = sb;
79.120 + }
79.121 + private static void assertExec(String msg, Class clazz, String method, Object expRes, Object... args) throws Exception {
79.122 + StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
79.123 + }
79.124 +}
80.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Fri Jan 18 14:23:18 2013 +0100
80.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java Fri Jan 18 14:27:22 2013 +0100
80.3 @@ -125,4 +125,11 @@
80.4 public static boolean iofObject() {
80.5 return jsObj() instanceof Object;
80.6 }
80.7 +
80.8 + public static int jscall() {
80.9 + return jsgetbytes(new Instance());
80.10 + }
80.11 +
80.12 + @JavaScriptBody(args = { "instance" }, body = "return instance.getByte__B();")
80.13 + private static native int jsgetbytes(Instance instance);
80.14 }
81.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Fri Jan 18 14:23:18 2013 +0100
81.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Fri Jan 18 14:27:22 2013 +0100
81.3 @@ -131,6 +131,14 @@
81.4 Double.valueOf(1)
81.5 );
81.6 }
81.7 +
81.8 + @Test public void jsCallingConvention() throws Exception {
81.9 + assertExec(
81.10 + "Pointer to 'this' is passed automatically (and not as a first argument)",
81.11 + Instance.class, "jscall__I",
81.12 + Double.valueOf(31)
81.13 + );
81.14 + }
81.15
81.16 protected String startCompilationWith() {
81.17 return "org/apidesign/vm4brwsr/Instance";
82.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java Fri Jan 18 14:23:18 2013 +0100
82.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java Fri Jan 18 14:27:22 2013 +0100
82.3 @@ -20,7 +20,6 @@
82.4 import java.io.File;
82.5 import java.io.FileWriter;
82.6 import java.io.IOException;
82.7 -import java.io.InputStream;
82.8 import static org.testng.Assert.*;
82.9 import javax.script.Invocable;
82.10 import org.testng.annotations.BeforeClass;
82.11 @@ -36,13 +35,13 @@
82.12 private static Invocable code;
82.13
82.14 @Test public void compareGeneratedCodeForArrayClass() throws Exception {
82.15 - compareCode("/org/apidesign/vm4brwsr/Array.class");
82.16 + compareCode("org/apidesign/vm4brwsr/Array.class");
82.17 }
82.18
82.19 @Test public void compareGeneratedCodeForClassesClass() throws Exception {
82.20 - compareCode("/org/apidesign/vm4brwsr/Classes.class");
82.21 + compareCode("org/apidesign/vm4brwsr/Classes.class");
82.22 }
82.23 -
82.24 +
82.25 @BeforeClass
82.26 public void compileTheCode() throws Exception {
82.27 StringBuilder sb = new StringBuilder();
82.28 @@ -52,20 +51,8 @@
82.29 codeSeq = sb;
82.30 }
82.31
82.32 - private static byte[] readClass(String res) throws IOException {
82.33 - InputStream is1 = VMinVMTest.class.getResourceAsStream(res);
82.34 - assertNotNull(is1, "Stream found");
82.35 - byte[] arr = new byte[is1.available()];
82.36 - int len = is1.read(arr);
82.37 - is1.close();
82.38 - if (len != arr.length) {
82.39 - throw new IOException("Wrong len " + len + " for arr: " + arr.length);
82.40 - }
82.41 - return arr;
82.42 - }
82.43 -
82.44 private void compareCode(final String nm) throws Exception, IOException {
82.45 - byte[] arr = readClass(nm);
82.46 + byte[] arr = BytesLoader.readClass(nm);
82.47 String ret1 = VMinVM.toJavaScript(arr);
82.48
82.49 Object ret;
83.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareHashTest.java Fri Jan 18 14:23:18 2013 +0100
83.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
83.3 @@ -1,37 +0,0 @@
83.4 -/**
83.5 - * Back 2 Browser Bytecode Translator
83.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
83.7 - *
83.8 - * This program is free software: you can redistribute it and/or modify
83.9 - * it under the terms of the GNU General Public License as published by
83.10 - * the Free Software Foundation, version 2 of the License.
83.11 - *
83.12 - * This program is distributed in the hope that it will be useful,
83.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
83.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83.15 - * GNU General Public License for more details.
83.16 - *
83.17 - * You should have received a copy of the GNU General Public License
83.18 - * along with this program. Look for COPYING file in the top folder.
83.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
83.20 - */
83.21 -package org.apidesign.vm4brwsr.tck;
83.22 -
83.23 -import org.apidesign.vm4brwsr.Compare;
83.24 -import org.apidesign.vm4brwsr.CompareVMs;
83.25 -import org.testng.annotations.Factory;
83.26 -
83.27 -/**
83.28 - *
83.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
83.30 - */
83.31 -public class CompareHashTest {
83.32 - @Compare public int hashOfString() {
83.33 - return "Ahoj".hashCode();
83.34 - }
83.35 -
83.36 - @Factory
83.37 - public static Object[] create() {
83.38 - return CompareVMs.create(CompareHashTest.class);
83.39 - }
83.40 -}
84.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareStringsTest.java Fri Jan 18 14:23:18 2013 +0100
84.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
84.3 @@ -1,43 +0,0 @@
84.4 -/**
84.5 - * Back 2 Browser Bytecode Translator
84.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
84.7 - *
84.8 - * This program is free software: you can redistribute it and/or modify
84.9 - * it under the terms of the GNU General Public License as published by
84.10 - * the Free Software Foundation, version 2 of the License.
84.11 - *
84.12 - * This program is distributed in the hope that it will be useful,
84.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
84.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84.15 - * GNU General Public License for more details.
84.16 - *
84.17 - * You should have received a copy of the GNU General Public License
84.18 - * along with this program. Look for COPYING file in the top folder.
84.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
84.20 - */
84.21 -package org.apidesign.vm4brwsr.tck;
84.22 -
84.23 -import org.apidesign.vm4brwsr.Compare;
84.24 -import org.apidesign.vm4brwsr.CompareVMs;
84.25 -import org.testng.annotations.Factory;
84.26 -
84.27 -/**
84.28 - *
84.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
84.30 - */
84.31 -public class CompareStringsTest {
84.32 - @Compare public String deleteLastTwoCharacters() {
84.33 - StringBuilder sb = new StringBuilder();
84.34 - sb.append("453.0");
84.35 - if (sb.toString().endsWith(".0")) {
84.36 - final int l = sb.length();
84.37 - sb.delete(l - 2, l);
84.38 - }
84.39 - return sb.toString().toString();
84.40 - }
84.41 -
84.42 - @Factory
84.43 - public static Object[] create() {
84.44 - return CompareVMs.create(CompareStringsTest.class);
84.45 - }
84.46 -}
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
85.2 +++ b/vmtest/pom.xml Fri Jan 18 14:27:22 2013 +0100
85.3 @@ -0,0 +1,61 @@
85.4 +<?xml version="1.0"?>
85.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
85.6 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
85.7 + <modelVersion>4.0.0</modelVersion>
85.8 + <parent>
85.9 + <groupId>org.apidesign</groupId>
85.10 + <artifactId>bck2brwsr</artifactId>
85.11 + <version>0.3-SNAPSHOT</version>
85.12 + </parent>
85.13 + <groupId>org.apidesign.bck2brwsr</groupId>
85.14 + <artifactId>vmtest</artifactId>
85.15 + <version>0.3-SNAPSHOT</version>
85.16 +
85.17 + <name>VM Testing APIs</name>
85.18 + <url>http://bck2brwsr.apidesign.org</url>
85.19 + <build>
85.20 + <plugins>
85.21 + <plugin>
85.22 + <groupId>org.apache.maven.plugins</groupId>
85.23 + <artifactId>maven-compiler-plugin</artifactId>
85.24 + <version>2.3.2</version>
85.25 + <configuration>
85.26 + <source>1.7</source>
85.27 + <target>1.7</target>
85.28 + </configuration>
85.29 + </plugin>
85.30 + </plugins>
85.31 + </build>
85.32 + <properties>
85.33 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
85.34 + </properties>
85.35 + <dependencies>
85.36 + <dependency>
85.37 + <groupId>org.testng</groupId>
85.38 + <artifactId>testng</artifactId>
85.39 + <scope>compile</scope>
85.40 + <exclusions>
85.41 + <exclusion>
85.42 + <artifactId>junit</artifactId>
85.43 + <groupId>junit</groupId>
85.44 + </exclusion>
85.45 + </exclusions>
85.46 + </dependency>
85.47 + <dependency>
85.48 + <groupId>${project.groupId}</groupId>
85.49 + <artifactId>vm4brwsr</artifactId>
85.50 + <version>0.3-SNAPSHOT</version>
85.51 + <type>jar</type>
85.52 + </dependency>
85.53 + <dependency>
85.54 + <groupId>${project.groupId}</groupId>
85.55 + <artifactId>emul</artifactId>
85.56 + <version>0.3-SNAPSHOT</version>
85.57 + </dependency>
85.58 + <dependency>
85.59 + <groupId>${project.groupId}</groupId>
85.60 + <artifactId>launcher</artifactId>
85.61 + <version>${project.version}</version>
85.62 + </dependency>
85.63 + </dependencies>
85.64 +</project>
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
86.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/Compare.java Fri Jan 18 14:27:22 2013 +0100
86.3 @@ -0,0 +1,36 @@
86.4 +/**
86.5 + * Back 2 Browser Bytecode Translator
86.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
86.7 + *
86.8 + * This program is free software: you can redistribute it and/or modify
86.9 + * it under the terms of the GNU General Public License as published by
86.10 + * the Free Software Foundation, version 2 of the License.
86.11 + *
86.12 + * This program is distributed in the hope that it will be useful,
86.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
86.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
86.15 + * GNU General Public License for more details.
86.16 + *
86.17 + * You should have received a copy of the GNU General Public License
86.18 + * along with this program. Look for COPYING file in the top folder.
86.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
86.20 + */
86.21 +package org.apidesign.bck2brwsr.vmtest;
86.22 +
86.23 +import java.lang.annotation.ElementType;
86.24 +import java.lang.annotation.Retention;
86.25 +import java.lang.annotation.RetentionPolicy;
86.26 +import java.lang.annotation.Target;
86.27 +
86.28 +/** Can be applied on a method that yields a return value.
86.29 + * Together with {@link VMTest#create} it can be used to write
86.30 + * methods which are executed in real as well as JavaScript VMs and
86.31 + * their results are compared.
86.32 + *
86.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
86.34 + */
86.35 +@Retention(RetentionPolicy.RUNTIME)
86.36 +@Target(ElementType.METHOD)
86.37 +public @interface Compare {
86.38 +
86.39 +}
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
87.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/VMTest.java Fri Jan 18 14:27:22 2013 +0100
87.3 @@ -0,0 +1,43 @@
87.4 +/**
87.5 + * Back 2 Browser Bytecode Translator
87.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
87.7 + *
87.8 + * This program is free software: you can redistribute it and/or modify
87.9 + * it under the terms of the GNU General Public License as published by
87.10 + * the Free Software Foundation, version 2 of the License.
87.11 + *
87.12 + * This program is distributed in the hope that it will be useful,
87.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
87.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
87.15 + * GNU General Public License for more details.
87.16 + *
87.17 + * You should have received a copy of the GNU General Public License
87.18 + * along with this program. Look for COPYING file in the top folder.
87.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
87.20 + */
87.21 +package org.apidesign.bck2brwsr.vmtest;
87.22 +
87.23 +import org.apidesign.bck2brwsr.vmtest.impl.CompareCase;
87.24 +import org.testng.annotations.Factory;
87.25 +
87.26 +/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
87.27 + * in provided class and builds set of tests that compare the computations
87.28 + * in real as well as JavaScript virtual machines. Use as:<pre>
87.29 + * {@code @}{@link Factory} public static create() {
87.30 + * return @{link VMTest}.{@link #create(YourClass.class);
87.31 + * }</pre>
87.32 + *
87.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
87.34 + */
87.35 +public final class VMTest {
87.36 + /** Inspects <code>clazz</code> and for each {@lik Compare} method creates
87.37 + * instances of tests. Each instance runs the test in different virtual
87.38 + * machine and at the end they compare the results.
87.39 + *
87.40 + * @param clazz the class to inspect
87.41 + * @return the set of created tests
87.42 + */
87.43 + public static Object[] create(Class<?> clazz) {
87.44 + return CompareCase.create(clazz);
87.45 + }
87.46 +}
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
88.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Fri Jan 18 14:27:22 2013 +0100
88.3 @@ -0,0 +1,80 @@
88.4 +/**
88.5 + * Back 2 Browser Bytecode Translator
88.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
88.7 + *
88.8 + * This program is free software: you can redistribute it and/or modify
88.9 + * it under the terms of the GNU General Public License as published by
88.10 + * the Free Software Foundation, version 2 of the License.
88.11 + *
88.12 + * This program is distributed in the hope that it will be useful,
88.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
88.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
88.15 + * GNU General Public License for more details.
88.16 + *
88.17 + * You should have received a copy of the GNU General Public License
88.18 + * along with this program. Look for COPYING file in the top folder.
88.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
88.20 + */
88.21 +package org.apidesign.bck2brwsr.vmtest.impl;
88.22 +
88.23 +import java.io.File;
88.24 +import java.io.FileWriter;
88.25 +import java.io.IOException;
88.26 +import java.lang.reflect.InvocationTargetException;
88.27 +import java.lang.reflect.Method;
88.28 +import java.util.Map;
88.29 +import java.util.WeakHashMap;
88.30 +import org.apidesign.bck2brwsr.launcher.Launcher;
88.31 +import org.apidesign.bck2brwsr.launcher.MethodInvocation;
88.32 +import org.testng.ITest;
88.33 +import org.testng.annotations.Test;
88.34 +
88.35 +/**
88.36 + *
88.37 + * @author Jaroslav Tulach <jtulach@netbeans.org>
88.38 + */
88.39 +public final class Bck2BrwsrCase implements ITest {
88.40 + private final Method m;
88.41 + private final Launcher l;
88.42 + private final String type;
88.43 + Object value;
88.44 + private static final Map<Class, Object[]> compiled = new WeakHashMap<>();
88.45 + private Object inst;
88.46 +
88.47 + Bck2BrwsrCase(Method m, String type, Launcher l) {
88.48 + this.l = l;
88.49 + this.m = m;
88.50 + this.type = type;
88.51 + }
88.52 +
88.53 + @Test(groups = "run")
88.54 + public void executeCode() throws Throwable {
88.55 + if (l != null) {
88.56 + MethodInvocation c = l.invokeMethod(m.getDeclaringClass(), m.getName());
88.57 + value = c.toString();
88.58 + } else {
88.59 + try {
88.60 + value = m.invoke(m.getDeclaringClass().newInstance());
88.61 + } catch (InvocationTargetException ex) {
88.62 + Throwable t = ex.getTargetException();
88.63 + value = t.getClass().getName() + ":" + t.getMessage();
88.64 + }
88.65 + }
88.66 + }
88.67 +
88.68 + @Override
88.69 + public String getTestName() {
88.70 + return m.getName() + "[" + typeName() + "]";
88.71 + }
88.72 +
88.73 + final String typeName() {
88.74 + return type;
88.75 + }
88.76 + static void dumpJS(StringBuilder sb, Bck2BrwsrCase c) throws IOException {
88.77 + File f = File.createTempFile(c.m.getName(), ".js");
88.78 + try (final FileWriter w = new FileWriter(f)) {
88.79 + w.append(c.l.toString());
88.80 + }
88.81 + sb.append("Path: ").append(f.getPath());
88.82 + }
88.83 +}
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
89.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Fri Jan 18 14:27:22 2013 +0100
89.3 @@ -0,0 +1,126 @@
89.4 +/**
89.5 + * Back 2 Browser Bytecode Translator
89.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
89.7 + *
89.8 + * This program is free software: you can redistribute it and/or modify
89.9 + * it under the terms of the GNU General Public License as published by
89.10 + * the Free Software Foundation, version 2 of the License.
89.11 + *
89.12 + * This program is distributed in the hope that it will be useful,
89.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
89.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
89.15 + * GNU General Public License for more details.
89.16 + *
89.17 + * You should have received a copy of the GNU General Public License
89.18 + * along with this program. Look for COPYING file in the top folder.
89.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
89.20 + */
89.21 +package org.apidesign.bck2brwsr.vmtest.impl;
89.22 +
89.23 +import org.apidesign.bck2brwsr.vmtest.*;
89.24 +import java.io.File;
89.25 +import java.io.FileWriter;
89.26 +import java.io.IOException;
89.27 +import java.lang.reflect.Method;
89.28 +import java.util.ArrayList;
89.29 +import java.util.List;
89.30 +import org.apidesign.bck2brwsr.launcher.Launcher;
89.31 +import org.testng.Assert;
89.32 +import org.testng.ITest;
89.33 +import org.testng.annotations.Factory;
89.34 +import org.testng.annotations.Test;
89.35 +
89.36 +/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
89.37 + * in provided class and builds set of tests that compare the computations
89.38 + * in real as well as JavaScript virtual machines. Use as:<pre>
89.39 + * {@code @}{@link Factory} public static create() {
89.40 + * return @{link VMTest}.{@link #create(YourClass.class);
89.41 + * }</pre>
89.42 + *
89.43 + * @author Jaroslav Tulach <jtulach@netbeans.org>
89.44 + */
89.45 +public final class CompareCase implements ITest {
89.46 + private final Bck2BrwsrCase first, second;
89.47 + private final Method m;
89.48 +
89.49 + private CompareCase(Method m, Bck2BrwsrCase first, Bck2BrwsrCase second) {
89.50 + this.first = first;
89.51 + this.second = second;
89.52 + this.m = m;
89.53 + }
89.54 +
89.55 + /** Inspects <code>clazz</code> and for each {@lik Compare} method creates
89.56 + * instances of tests. Each instance runs the test in different virtual
89.57 + * machine and at the end they compare the results.
89.58 + *
89.59 + * @param clazz the class to inspect
89.60 + * @return the set of created tests
89.61 + */
89.62 + public static Object[] create(Class<?> clazz) {
89.63 + Method[] arr = clazz.getMethods();
89.64 + List<Object> ret = new ArrayList<>();
89.65 +
89.66 + final LaunchSetup l = LaunchSetup.INSTANCE;
89.67 + ret.add(l);
89.68 +
89.69 + String[] brwsr;
89.70 + {
89.71 + String p = System.getProperty("vmtest.brwsrs");
89.72 + if (p != null) {
89.73 + brwsr = p.split(",");
89.74 + } else {
89.75 + brwsr = new String[0];
89.76 + }
89.77 + }
89.78 +
89.79 + for (Method m : arr) {
89.80 + Compare c = m.getAnnotation(Compare.class);
89.81 + if (c == null) {
89.82 + continue;
89.83 + }
89.84 + final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null);
89.85 + final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript());
89.86 + ret.add(real);
89.87 + ret.add(js);
89.88 + ret.add(new CompareCase(m, real, js));
89.89 +
89.90 + for (String b : brwsr) {
89.91 + final Launcher s = l.brwsr(b);
89.92 + ret.add(s);
89.93 + final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s);
89.94 + ret.add(cse);
89.95 + ret.add(new CompareCase(m, real, cse));
89.96 + }
89.97 + }
89.98 + return ret.toArray();
89.99 + }
89.100 +
89.101 + /** Test that compares the previous results.
89.102 + * @throws Throwable
89.103 + */
89.104 + @Test(dependsOnGroups = "run") public void compareResults() throws Throwable {
89.105 + Object v1 = first.value;
89.106 + Object v2 = second.value;
89.107 + if (v1 != null) {
89.108 + v1 = v1.toString();
89.109 + } else {
89.110 + v1 = "null";
89.111 + }
89.112 + try {
89.113 + Assert.assertEquals(v2, v1, "Comparing results");
89.114 + } catch (AssertionError e) {
89.115 + StringBuilder sb = new StringBuilder();
89.116 + sb.append(e.getMessage());
89.117 + Bck2BrwsrCase.dumpJS(sb, second);
89.118 + throw new AssertionError(sb.toString());
89.119 + }
89.120 + }
89.121 +
89.122 + /** Test name.
89.123 + * @return name of the tested method followed by a suffix
89.124 + */
89.125 + @Override
89.126 + public String getTestName() {
89.127 + return m.getName() + "[Compare " + second.typeName() + "]";
89.128 + }
89.129 +}
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
90.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/LaunchSetup.java Fri Jan 18 14:27:22 2013 +0100
90.3 @@ -0,0 +1,68 @@
90.4 +/**
90.5 + * Back 2 Browser Bytecode Translator
90.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
90.7 + *
90.8 + * This program is free software: you can redistribute it and/or modify
90.9 + * it under the terms of the GNU General Public License as published by
90.10 + * the Free Software Foundation, version 2 of the License.
90.11 + *
90.12 + * This program is distributed in the hope that it will be useful,
90.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
90.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90.15 + * GNU General Public License for more details.
90.16 + *
90.17 + * You should have received a copy of the GNU General Public License
90.18 + * along with this program. Look for COPYING file in the top folder.
90.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
90.20 + */
90.21 +package org.apidesign.bck2brwsr.vmtest.impl;
90.22 +
90.23 +import java.io.IOException;
90.24 +import java.util.LinkedHashMap;
90.25 +import java.util.Map;
90.26 +import org.apidesign.bck2brwsr.launcher.Launcher;
90.27 +import org.testng.annotations.AfterGroups;
90.28 +import org.testng.annotations.BeforeGroups;
90.29 +
90.30 +/**
90.31 + *
90.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
90.33 + */
90.34 +public final class LaunchSetup {
90.35 + static LaunchSetup INSTANCE = new LaunchSetup();
90.36 +
90.37 + private final Launcher js = Launcher.createJavaScript();
90.38 + private final Map<String,Launcher> brwsrs = new LinkedHashMap<>();
90.39 +
90.40 + private LaunchSetup() {
90.41 + }
90.42 +
90.43 + public Launcher javaScript() {
90.44 + return js;
90.45 + }
90.46 +
90.47 + public synchronized Launcher brwsr(String cmd) {
90.48 + Launcher s = brwsrs.get(cmd);
90.49 + if (s == null) {
90.50 + s = Launcher.createBrowser(cmd);
90.51 + brwsrs.put(cmd, s);
90.52 + }
90.53 + return s;
90.54 + }
90.55 +
90.56 + @BeforeGroups("run")
90.57 + public void initializeLauncher() throws IOException {
90.58 + js.initialize();
90.59 + for (Launcher launcher : brwsrs.values()) {
90.60 + launcher.initialize();
90.61 + }
90.62 + }
90.63 +
90.64 + @AfterGroups("run")
90.65 + public void shutDownLauncher() throws IOException, InterruptedException {
90.66 + js.shutdown();
90.67 + for (Launcher launcher : brwsrs.values()) {
90.68 + launcher.shutdown();
90.69 + }
90.70 + }
90.71 +}
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
91.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java Fri Jan 18 14:27:22 2013 +0100
91.3 @@ -0,0 +1,102 @@
91.4 +/**
91.5 + * Back 2 Browser Bytecode Translator
91.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
91.7 + *
91.8 + * This program is free software: you can redistribute it and/or modify
91.9 + * it under the terms of the GNU General Public License as published by
91.10 + * the Free Software Foundation, version 2 of the License.
91.11 + *
91.12 + * This program is distributed in the hope that it will be useful,
91.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
91.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
91.15 + * GNU General Public License for more details.
91.16 + *
91.17 + * You should have received a copy of the GNU General Public License
91.18 + * along with this program. Look for COPYING file in the top folder.
91.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
91.20 + */
91.21 +package org.apidesign.bck2brwsr.tck;
91.22 +
91.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
91.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
91.25 +import org.testng.annotations.Factory;
91.26 +
91.27 +/**
91.28 + *
91.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
91.30 + */
91.31 +public class ByteArithmeticTest {
91.32 +
91.33 + private static byte add(byte x, byte y) {
91.34 + return (byte)(x + y);
91.35 + }
91.36 +
91.37 + private static byte sub(byte x, byte y) {
91.38 + return (byte)(x - y);
91.39 + }
91.40 +
91.41 + private static byte mul(byte x, byte y) {
91.42 + return (byte)(x * y);
91.43 + }
91.44 +
91.45 + private static byte div(byte x, byte y) {
91.46 + return (byte)(x / y);
91.47 + }
91.48 +
91.49 + private static byte mod(byte x, byte y) {
91.50 + return (byte)(x % y);
91.51 + }
91.52 +
91.53 + @Compare public byte conversion() {
91.54 + return (byte)123456;
91.55 + }
91.56 +
91.57 + @Compare public byte addOverflow() {
91.58 + return add(Byte.MAX_VALUE, (byte)1);
91.59 + }
91.60 +
91.61 + @Compare public byte subUnderflow() {
91.62 + return sub(Byte.MIN_VALUE, (byte)1);
91.63 + }
91.64 +
91.65 + @Compare public byte addMaxByteAndMaxByte() {
91.66 + return add(Byte.MAX_VALUE, Byte.MAX_VALUE);
91.67 + }
91.68 +
91.69 + @Compare public byte subMinByteAndMinByte() {
91.70 + return sub(Byte.MIN_VALUE, Byte.MIN_VALUE);
91.71 + }
91.72 +
91.73 + @Compare public byte multiplyMaxByte() {
91.74 + return mul(Byte.MAX_VALUE, (byte)2);
91.75 + }
91.76 +
91.77 + @Compare public byte multiplyMaxByteAndMaxByte() {
91.78 + return mul(Byte.MAX_VALUE, Byte.MAX_VALUE);
91.79 + }
91.80 +
91.81 + @Compare public byte multiplyMinByte() {
91.82 + return mul(Byte.MIN_VALUE, (byte)2);
91.83 + }
91.84 +
91.85 + @Compare public byte multiplyMinByteAndMinByte() {
91.86 + return mul(Byte.MIN_VALUE, Byte.MIN_VALUE);
91.87 + }
91.88 +
91.89 + @Compare public byte multiplyPrecision() {
91.90 + return mul((byte)17638, (byte)1103);
91.91 + }
91.92 +
91.93 + @Compare public byte division() {
91.94 + return div((byte)1, (byte)2);
91.95 + }
91.96 +
91.97 + @Compare public byte divisionReminder() {
91.98 + return mod((byte)1, (byte)2);
91.99 + }
91.100 +
91.101 + @Factory
91.102 + public static Object[] create() {
91.103 + return VMTest.create(ByteArithmeticTest.class);
91.104 + }
91.105 +}
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CloneTest.java Fri Jan 18 14:27:22 2013 +0100
92.3 @@ -0,0 +1,73 @@
92.4 +/**
92.5 + * Back 2 Browser Bytecode Translator
92.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
92.7 + *
92.8 + * This program is free software: you can redistribute it and/or modify
92.9 + * it under the terms of the GNU General Public License as published by
92.10 + * the Free Software Foundation, version 2 of the License.
92.11 + *
92.12 + * This program is distributed in the hope that it will be useful,
92.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
92.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
92.15 + * GNU General Public License for more details.
92.16 + *
92.17 + * You should have received a copy of the GNU General Public License
92.18 + * along with this program. Look for COPYING file in the top folder.
92.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
92.20 + */
92.21 +package org.apidesign.bck2brwsr.tck;
92.22 +
92.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
92.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
92.25 +import org.testng.annotations.Factory;
92.26 +
92.27 +/**
92.28 + *
92.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
92.30 + */
92.31 +public class CloneTest {
92.32 + private int value;
92.33 +
92.34 + @Compare
92.35 + public Object notSupported() throws CloneNotSupportedException {
92.36 + return this.clone();
92.37 + }
92.38 +
92.39 + @Compare public String sameClass() throws CloneNotSupportedException {
92.40 + return new Clnbl().clone().getClass().getName();
92.41 + }
92.42 +
92.43 + @Compare public boolean differentInstance() throws CloneNotSupportedException {
92.44 + Clnbl orig = new Clnbl();
92.45 + return orig == orig.clone();
92.46 + }
92.47 +
92.48 + @Compare public int sameReference() throws CloneNotSupportedException {
92.49 + CloneTest self = this;
92.50 + Clnbl orig = new Clnbl();
92.51 + self.value = 33;
92.52 + orig.ref = self;
92.53 + return ((Clnbl)orig.clone()).ref.value;
92.54 + }
92.55 +
92.56 + @Compare public int sameValue() throws CloneNotSupportedException {
92.57 + Clnbl orig = new Clnbl();
92.58 + orig.value = 10;
92.59 + return ((Clnbl)orig.clone()).value;
92.60 + }
92.61 +
92.62 + @Factory
92.63 + public static Object[] create() {
92.64 + return VMTest.create(CloneTest.class);
92.65 + }
92.66 +
92.67 + public static final class Clnbl implements Cloneable {
92.68 + public CloneTest ref;
92.69 + private int value;
92.70 +
92.71 + @Override
92.72 + public Object clone() throws CloneNotSupportedException {
92.73 + return super.clone();
92.74 + }
92.75 + }
92.76 +}
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
93.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java Fri Jan 18 14:27:22 2013 +0100
93.3 @@ -0,0 +1,93 @@
93.4 +/**
93.5 + * Back 2 Browser Bytecode Translator
93.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
93.7 + *
93.8 + * This program is free software: you can redistribute it and/or modify
93.9 + * it under the terms of the GNU General Public License as published by
93.10 + * the Free Software Foundation, version 2 of the License.
93.11 + *
93.12 + * This program is distributed in the hope that it will be useful,
93.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
93.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
93.15 + * GNU General Public License for more details.
93.16 + *
93.17 + * You should have received a copy of the GNU General Public License
93.18 + * along with this program. Look for COPYING file in the top folder.
93.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
93.20 + */
93.21 +package org.apidesign.bck2brwsr.tck;
93.22 +
93.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
93.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
93.25 +import org.testng.annotations.Factory;
93.26 +
93.27 +/**
93.28 + *
93.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
93.30 + */
93.31 +public class CompareByteArrayTest {
93.32 + @Compare public int byteArraySum() {
93.33 + byte[] arr = createArray();
93.34 + return sumByteArr(arr);
93.35 + }
93.36 +
93.37 + @Compare public int countZeros() {
93.38 + int zeros = 0;
93.39 + for (Byte b : createArray()) {
93.40 + if (b == 0) {
93.41 + zeros++;
93.42 + }
93.43 + }
93.44 + return zeros;
93.45 + }
93.46 +
93.47 + private static int sumByteArr(byte[] arr) {
93.48 + int sum = 0;
93.49 + for (int i = 0; i < arr.length; i++) {
93.50 + sum += arr[i];
93.51 + }
93.52 + return sum;
93.53 + }
93.54 +
93.55 + @Compare public String noOutOfBounds() {
93.56 + return atIndex(1);
93.57 + }
93.58 +
93.59 + @Compare public String outOfBounds() {
93.60 + return atIndex(5);
93.61 + }
93.62 +
93.63 + @Compare public String outOfBoundsMinus() {
93.64 + return atIndex(-1);
93.65 + }
93.66 +
93.67 + @Compare public String toOfBounds() {
93.68 + return toIndex(5);
93.69 + }
93.70 +
93.71 + @Compare public String toOfBoundsMinus() {
93.72 + return toIndex(-1);
93.73 + }
93.74 +
93.75 + private static final int[] arr = { 0, 1, 2 };
93.76 + public static String atIndex(int at) {
93.77 + return "at@" + arr[at];
93.78 + }
93.79 + public static String toIndex(int at) {
93.80 + arr[at] = 10;
93.81 + return "ok";
93.82 + }
93.83 +
93.84 +
93.85 + @Factory
93.86 + public static Object[] create() {
93.87 + return VMTest.create(CompareByteArrayTest.class);
93.88 + }
93.89 +
93.90 + private byte[] createArray() {
93.91 + byte[] arr = new byte[10];
93.92 + arr[5] = 3;
93.93 + arr[7] = 8;
93.94 + return arr;
93.95 + }
93.96 +}
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java Fri Jan 18 14:27:22 2013 +0100
94.3 @@ -0,0 +1,50 @@
94.4 +/**
94.5 + * Back 2 Browser Bytecode Translator
94.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
94.7 + *
94.8 + * This program is free software: you can redistribute it and/or modify
94.9 + * it under the terms of the GNU General Public License as published by
94.10 + * the Free Software Foundation, version 2 of the License.
94.11 + *
94.12 + * This program is distributed in the hope that it will be useful,
94.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
94.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
94.15 + * GNU General Public License for more details.
94.16 + *
94.17 + * You should have received a copy of the GNU General Public License
94.18 + * along with this program. Look for COPYING file in the top folder.
94.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
94.20 + */
94.21 +package org.apidesign.bck2brwsr.tck;
94.22 +
94.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
94.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
94.25 +import org.testng.annotations.Factory;
94.26 +
94.27 +/**
94.28 + *
94.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
94.30 + */
94.31 +public class CompareHashTest {
94.32 + @Compare public int hashOfString() {
94.33 + return "Ahoj".hashCode();
94.34 + }
94.35 +
94.36 + @Compare public int hashRemainsYieldsZero() {
94.37 + Object o = new Object();
94.38 + return o.hashCode() - o.hashCode();
94.39 + }
94.40 +
94.41 + @Compare public int initializeInStatic() {
94.42 + return StaticUse.NON_NULL.hashCode() - StaticUse.NON_NULL.hashCode();
94.43 + }
94.44 +
94.45 + @Compare public int hashOfInt() {
94.46 + return Integer.valueOf(Integer.MAX_VALUE).hashCode();
94.47 + }
94.48 +
94.49 + @Factory
94.50 + public static Object[] create() {
94.51 + return VMTest.create(CompareHashTest.class);
94.52 + }
94.53 +}
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
95.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareIntArrayTest.java Fri Jan 18 14:27:22 2013 +0100
95.3 @@ -0,0 +1,63 @@
95.4 +/**
95.5 + * Back 2 Browser Bytecode Translator
95.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
95.7 + *
95.8 + * This program is free software: you can redistribute it and/or modify
95.9 + * it under the terms of the GNU General Public License as published by
95.10 + * the Free Software Foundation, version 2 of the License.
95.11 + *
95.12 + * This program is distributed in the hope that it will be useful,
95.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
95.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
95.15 + * GNU General Public License for more details.
95.16 + *
95.17 + * You should have received a copy of the GNU General Public License
95.18 + * along with this program. Look for COPYING file in the top folder.
95.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
95.20 + */
95.21 +package org.apidesign.bck2brwsr.tck;
95.22 +
95.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
95.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
95.25 +import org.testng.annotations.Factory;
95.26 +
95.27 +/**
95.28 + *
95.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
95.30 + */
95.31 +public class CompareIntArrayTest {
95.32 + @Compare public int integerArraySum() {
95.33 + int[] arr = createArray();
95.34 + return sumIntArr(arr);
95.35 + }
95.36 +
95.37 + @Compare public int countZeros() {
95.38 + int zeros = 0;
95.39 + for (Integer i : createArray()) {
95.40 + if (i == 0) {
95.41 + zeros++;
95.42 + }
95.43 + }
95.44 + return zeros;
95.45 + }
95.46 +
95.47 + private static int sumIntArr(int[] arr) {
95.48 + int sum = 0;
95.49 + for (int i = 0; i < arr.length; i++) {
95.50 + sum += arr[i];
95.51 + }
95.52 + return sum;
95.53 + }
95.54 +
95.55 + @Factory
95.56 + public static Object[] create() {
95.57 + return VMTest.create(CompareIntArrayTest.class);
95.58 + }
95.59 +
95.60 + private int[] createArray() {
95.61 + int[] arr = new int[10];
95.62 + arr[5] = 3;
95.63 + arr[7] = 8;
95.64 + return arr;
95.65 + }
95.66 +}
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
96.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Fri Jan 18 14:27:22 2013 +0100
96.3 @@ -0,0 +1,129 @@
96.4 +/**
96.5 + * Back 2 Browser Bytecode Translator
96.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
96.7 + *
96.8 + * This program is free software: you can redistribute it and/or modify
96.9 + * it under the terms of the GNU General Public License as published by
96.10 + * the Free Software Foundation, version 2 of the License.
96.11 + *
96.12 + * This program is distributed in the hope that it will be useful,
96.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
96.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96.15 + * GNU General Public License for more details.
96.16 + *
96.17 + * You should have received a copy of the GNU General Public License
96.18 + * along with this program. Look for COPYING file in the top folder.
96.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
96.20 + */
96.21 +package org.apidesign.bck2brwsr.tck;
96.22 +
96.23 +import java.net.MalformedURLException;
96.24 +import java.net.URL;
96.25 +import org.apidesign.bck2brwsr.vmtest.Compare;
96.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
96.27 +import org.testng.annotations.Factory;
96.28 +
96.29 +/**
96.30 + *
96.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
96.32 + */
96.33 +public class CompareStringsTest {
96.34 + @Compare public String firstChar() {
96.35 + return "" + ("Hello".toCharArray()[0]);
96.36 + }
96.37 +
96.38 + @Compare public String classCast() {
96.39 + Object o = firstChar();
96.40 + return String.class.cast(o);
96.41 + }
96.42 +
96.43 + @Compare public String classCastThrown() {
96.44 + Object o = null;
96.45 + return String.class.cast(o);
96.46 + }
96.47 +
96.48 + @Compare public static Object compareURLs() throws MalformedURLException {
96.49 + return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
96.50 + }
96.51 +
96.52 + @Compare public String deleteLastTwoCharacters() {
96.53 + StringBuilder sb = new StringBuilder();
96.54 + sb.append("453.0");
96.55 + if (sb.toString().endsWith(".0")) {
96.56 + final int l = sb.length();
96.57 + sb.delete(l - 2, l);
96.58 + }
96.59 + return sb.toString().toString();
96.60 + }
96.61 +
96.62 + @Compare public String nameOfStringClass() throws Exception {
96.63 + return Class.forName("java.lang.String").getName();
96.64 + }
96.65 + @Compare public String nameOfArrayClass() throws Exception {
96.66 + return Class.forName("org.apidesign.bck2brwsr.tck.CompareHashTest").getName();
96.67 + }
96.68 +
96.69 + @Compare public String lowerHello() {
96.70 + return "HeLlO".toLowerCase();
96.71 + }
96.72 +
96.73 + @Compare public String lowerA() {
96.74 + return String.valueOf(Character.toLowerCase('A')).toString();
96.75 + }
96.76 + @Compare public String upperHello() {
96.77 + return "hello".toUpperCase();
96.78 + }
96.79 +
96.80 + @Compare public String upperA() {
96.81 + return String.valueOf(Character.toUpperCase('a')).toString();
96.82 + }
96.83 +
96.84 + @Compare public boolean matchRegExp() throws Exception {
96.85 + return "58038503".matches("\\d*");
96.86 + }
96.87 +
96.88 + @Compare public boolean doesNotMatchRegExp() throws Exception {
96.89 + return "58038503GH".matches("\\d*");
96.90 + }
96.91 +
96.92 + @Compare public boolean doesNotMatchRegExpFully() throws Exception {
96.93 + return "Hello".matches("Hell");
96.94 + }
96.95 +
96.96 + @Compare public String emptyCharArray() {
96.97 + char[] arr = new char[10];
96.98 + return new String(arr);
96.99 + }
96.100 +
96.101 + @Compare public String variousCharacterTests() throws Exception {
96.102 + StringBuilder sb = new StringBuilder();
96.103 +
96.104 + sb.append(Character.isUpperCase('a'));
96.105 + sb.append(Character.isUpperCase('A'));
96.106 + sb.append(Character.isLowerCase('a'));
96.107 + sb.append(Character.isLowerCase('A'));
96.108 +
96.109 + sb.append(Character.isLetter('A'));
96.110 + sb.append(Character.isLetterOrDigit('9'));
96.111 + sb.append(Character.isLetterOrDigit('A'));
96.112 + sb.append(Character.isLetter('0'));
96.113 +
96.114 + return sb.toString().toString();
96.115 + }
96.116 +
96.117 + @Compare
96.118 + public String nullFieldInitialized() {
96.119 + NullField nf = new NullField();
96.120 + return ("" + nf.name).toString();
96.121 + }
96.122 +
96.123 + @Factory
96.124 + public static Object[] create() {
96.125 + return VMTest.create(CompareStringsTest.class);
96.126 + }
96.127 +
96.128 + private static final class NullField {
96.129 +
96.130 + String name;
96.131 + }
96.132 +}
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Fri Jan 18 14:27:22 2013 +0100
97.3 @@ -0,0 +1,108 @@
97.4 +/**
97.5 + * Back 2 Browser Bytecode Translator
97.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
97.7 + *
97.8 + * This program is free software: you can redistribute it and/or modify
97.9 + * it under the terms of the GNU General Public License as published by
97.10 + * the Free Software Foundation, version 2 of the License.
97.11 + *
97.12 + * This program is distributed in the hope that it will be useful,
97.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
97.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
97.15 + * GNU General Public License for more details.
97.16 + *
97.17 + * You should have received a copy of the GNU General Public License
97.18 + * along with this program. Look for COPYING file in the top folder.
97.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
97.20 + */
97.21 +package org.apidesign.bck2brwsr.tck;
97.22 +
97.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
97.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
97.25 +import org.testng.annotations.Factory;
97.26 +
97.27 +/**
97.28 + *
97.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
97.30 + */
97.31 +public class IntegerArithmeticTest {
97.32 +
97.33 + private static int add(int x, int y) {
97.34 + return x + y;
97.35 + }
97.36 +
97.37 + private static int sub(int x, int y) {
97.38 + return x - y;
97.39 + }
97.40 +
97.41 + private static int mul(int x, int y) {
97.42 + return x * y;
97.43 + }
97.44 +
97.45 + private static int div(int x, int y) {
97.46 + return x / y;
97.47 + }
97.48 +
97.49 + private static int mod(int x, int y) {
97.50 + return x % y;
97.51 + }
97.52 +
97.53 + @Compare public int addOverflow() {
97.54 + return add(Integer.MAX_VALUE, 1);
97.55 + }
97.56 +
97.57 + @Compare public int subUnderflow() {
97.58 + return sub(Integer.MIN_VALUE, 1);
97.59 + }
97.60 +
97.61 + @Compare public int addMaxIntAndMaxInt() {
97.62 + return add(Integer.MAX_VALUE, Integer.MAX_VALUE);
97.63 + }
97.64 +
97.65 + @Compare public int subMinIntAndMinInt() {
97.66 + return sub(Integer.MIN_VALUE, Integer.MIN_VALUE);
97.67 + }
97.68 +
97.69 + @Compare public int multiplyMaxInt() {
97.70 + return mul(Integer.MAX_VALUE, 2);
97.71 + }
97.72 +
97.73 + @Compare public int multiplyMaxIntAndMaxInt() {
97.74 + return mul(Integer.MAX_VALUE, Integer.MAX_VALUE);
97.75 + }
97.76 +
97.77 + @Compare public int multiplyMinInt() {
97.78 + return mul(Integer.MIN_VALUE, 2);
97.79 + }
97.80 +
97.81 + @Compare public int multiplyMinIntAndMinInt() {
97.82 + return mul(Integer.MIN_VALUE, Integer.MIN_VALUE);
97.83 + }
97.84 +
97.85 + @Compare public int multiplyPrecision() {
97.86 + return mul(119106029, 1103515245);
97.87 + }
97.88 +
97.89 + @Compare public int division() {
97.90 + return div(1, 2);
97.91 + }
97.92 +
97.93 + @Compare public int divisionReminder() {
97.94 + return mod(1, 2);
97.95 + }
97.96 +
97.97 + @Compare public int sumTwoDimensions() {
97.98 + int[][] matrix = createMatrix(4, 3);
97.99 + matrix[0][0] += 10;
97.100 + return matrix[0][0];
97.101 + }
97.102 +
97.103 + static int[][] createMatrix(int x, int y) {
97.104 + return new int[x][y];
97.105 + }
97.106 +
97.107 + @Factory
97.108 + public static Object[] create() {
97.109 + return VMTest.create(IntegerArithmeticTest.class);
97.110 + }
97.111 +}
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Fri Jan 18 14:27:22 2013 +0100
98.3 @@ -0,0 +1,192 @@
98.4 +/**
98.5 + * Back 2 Browser Bytecode Translator
98.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
98.7 + *
98.8 + * This program is free software: you can redistribute it and/or modify
98.9 + * it under the terms of the GNU General Public License as published by
98.10 + * the Free Software Foundation, version 2 of the License.
98.11 + *
98.12 + * This program is distributed in the hope that it will be useful,
98.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
98.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
98.15 + * GNU General Public License for more details.
98.16 + *
98.17 + * You should have received a copy of the GNU General Public License
98.18 + * along with this program. Look for COPYING file in the top folder.
98.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
98.20 + */
98.21 +package org.apidesign.bck2brwsr.tck;
98.22 +
98.23 +import java.lang.reflect.Method;
98.24 +import java.util.Arrays;
98.25 +import java.util.Collections;
98.26 +import java.util.List;
98.27 +import java.util.logging.Level;
98.28 +import java.util.logging.Logger;
98.29 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
98.30 +import org.apidesign.bck2brwsr.vmtest.Compare;
98.31 +import org.apidesign.bck2brwsr.vmtest.VMTest;
98.32 +import org.testng.annotations.Factory;
98.33 +
98.34 +/**
98.35 + *
98.36 + * @author Jaroslav Tulach <jtulach@netbeans.org>
98.37 + */
98.38 +public class ReflectionTest {
98.39 + @Compare public boolean nonNullThis() {
98.40 + return this == null;
98.41 + }
98.42 +
98.43 + @Compare public String intType() {
98.44 + return Integer.TYPE.toString();
98.45 + }
98.46 +
98.47 + @Compare public String voidType() throws Exception {
98.48 + return void.class.toString();
98.49 + }
98.50 +
98.51 + @Compare public String longClass() {
98.52 + return long.class.toString();
98.53 + }
98.54 +
98.55 + @Compare public String namesOfMethods() {
98.56 + StringBuilder sb = new StringBuilder();
98.57 + String[] arr = new String[20];
98.58 + int i = 0;
98.59 + for (Method m : StaticUse.class.getMethods()) {
98.60 + arr[i++] = m.getName();
98.61 + }
98.62 + for (String s : sort(arr, i)) {
98.63 + sb.append(s).append("\n");
98.64 + }
98.65 + return sb.toString();
98.66 + }
98.67 +
98.68 + @Compare public String cannotCallNonStaticMethodWithNull() throws Exception {
98.69 + StaticUse.class.getMethod("instanceMethod").invoke(null);
98.70 + return "should not happen";
98.71 + }
98.72 +
98.73 + @Compare public Object voidReturnType() throws Exception {
98.74 + return StaticUse.class.getMethod("instanceMethod").getReturnType();
98.75 + }
98.76 +
98.77 + @Compare public String newInstanceFails() throws InstantiationException {
98.78 + try {
98.79 + return "success: " + StaticUse.class.newInstance();
98.80 + } catch (IllegalAccessException ex) {
98.81 + return ex.getClass().getName();
98.82 + }
98.83 + }
98.84 +
98.85 + @Compare public String paramTypes() throws Exception {
98.86 + Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
98.87 + final Class[] pt = plus.getParameterTypes();
98.88 + return pt[0].getName();
98.89 + }
98.90 + @Compare public String paramTypesNotFound() throws Exception {
98.91 + return StaticUse.class.getMethod("plus", int.class, double.class).toString();
98.92 + }
98.93 + @Compare public int methodWithArgs() throws Exception {
98.94 + Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
98.95 + return (Integer)plus.invoke(null, 2, 3);
98.96 + }
98.97 +
98.98 + @Compare public String classGetNameForByte() {
98.99 + return byte.class.getName();
98.100 + }
98.101 + @Compare public String classGetNameForBaseObject() {
98.102 + return newObject().getClass().getName();
98.103 + }
98.104 + @Compare public String classGetNameForJavaObject() {
98.105 + return new Object().getClass().getName();
98.106 + }
98.107 + @Compare public String classGetNameForObjectArray() {
98.108 + return (new Object[3]).getClass().getName();
98.109 + }
98.110 + @Compare public String classGetNameForSimpleIntArray() {
98.111 + return (new int[3]).getClass().getName();
98.112 + }
98.113 + @Compare public boolean sameClassGetNameForSimpleCharArray() {
98.114 + return (new char[3]).getClass() == (new char[34]).getClass();
98.115 + }
98.116 + @Compare public String classGetNameForMultiIntArray() {
98.117 + return (new int[3][4][5][6][7][8][9]).getClass().getName();
98.118 + }
98.119 + @Compare public String classGetNameForMultiIntArrayInner() {
98.120 + final int[][][][][][][] arr = new int[3][4][5][6][7][8][9];
98.121 + int[][][][][][] subarr = arr[0];
98.122 + int[][][][][] subsubarr = subarr[0];
98.123 + return subsubarr.getClass().getName();
98.124 + }
98.125 + @Compare public String classGetNameForMultiStringArray() {
98.126 + return (new String[3][4][5][6][7][8][9]).getClass().getName();
98.127 + }
98.128 +
98.129 + @Compare public String classForByte() throws Exception {
98.130 + return Class.forName("[Z").getName();
98.131 + }
98.132 +
98.133 + @Compare public String classForUnknownArray() {
98.134 + try {
98.135 + return Class.forName("[W").getName();
98.136 + } catch (Exception ex) {
98.137 + return ex.getClass().getName();
98.138 + }
98.139 + }
98.140 +
98.141 + @Compare public String classForUnknownDeepArray() {
98.142 + try {
98.143 + return Class.forName("[[[[[W").getName();
98.144 + } catch (Exception ex) {
98.145 + return ex.getClass().getName();
98.146 + }
98.147 + }
98.148 +
98.149 + @Compare public String componentGetNameForObjectArray() {
98.150 + return (new Object[3]).getClass().getComponentType().getName();
98.151 + }
98.152 + @Compare public boolean sameComponentGetNameForObjectArray() {
98.153 + return (new Object[3]).getClass().getComponentType() == Object.class;
98.154 + }
98.155 + @Compare public String componentGetNameForSimpleIntArray() {
98.156 + return (new int[3]).getClass().getComponentType().getName();
98.157 + }
98.158 + @Compare public String componentGetNameForMultiIntArray() {
98.159 + return (new int[3][4][5][6][7][8][9]).getClass().getComponentType().getName();
98.160 + }
98.161 + @Compare public String componentGetNameForMultiStringArray() {
98.162 + Class<?> c = (new String[3][4][5][6][7][8][9]).getClass();
98.163 + StringBuilder sb = new StringBuilder();
98.164 + for (;;) {
98.165 + sb.append(c.getName()).append("\n");
98.166 + c = c.getComponentType();
98.167 + if (c == null) {
98.168 + break;
98.169 + }
98.170 + }
98.171 + return sb.toString();
98.172 + }
98.173 +
98.174 + @Compare public boolean isArray() {
98.175 + return new Object[0].getClass().isArray();
98.176 + }
98.177 +
98.178 + @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
98.179 + private static String[] sort(String[] arr, int len) {
98.180 + List<String> list = Arrays.asList(arr).subList(0, len);
98.181 + Collections.sort(list);
98.182 + return list.toArray(new String[0]);
98.183 + }
98.184 +
98.185 + @JavaScriptBody(args = {}, body = "return new Object();")
98.186 + private static Object newObject() {
98.187 + return new Object();
98.188 + }
98.189 +
98.190 + @Factory
98.191 + public static Object[] create() {
98.192 + return VMTest.create(ReflectionTest.class);
98.193 + }
98.194 +
98.195 +}
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java Fri Jan 18 14:27:22 2013 +0100
99.3 @@ -0,0 +1,45 @@
99.4 +/**
99.5 + * Back 2 Browser Bytecode Translator
99.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
99.7 + *
99.8 + * This program is free software: you can redistribute it and/or modify
99.9 + * it under the terms of the GNU General Public License as published by
99.10 + * the Free Software Foundation, version 2 of the License.
99.11 + *
99.12 + * This program is distributed in the hope that it will be useful,
99.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
99.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99.15 + * GNU General Public License for more details.
99.16 + *
99.17 + * You should have received a copy of the GNU General Public License
99.18 + * along with this program. Look for COPYING file in the top folder.
99.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
99.20 + */
99.21 +package org.apidesign.bck2brwsr.tck;
99.22 +
99.23 +import java.io.InputStream;
99.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
99.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
99.26 +import org.testng.annotations.Factory;
99.27 +
99.28 +/**
99.29 + *
99.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
99.31 + */
99.32 +public class ResourcesTest {
99.33 +
99.34 + @Compare public String readResourceAsStream() throws Exception {
99.35 + InputStream is = getClass().getResourceAsStream("Resources.txt");
99.36 + byte[] b = new byte[30];
99.37 + int len = is.read(b);
99.38 + StringBuilder sb = new StringBuilder();
99.39 + for (int i = 0; i < len; i++) {
99.40 + sb.append((char)b[i]);
99.41 + }
99.42 + return sb.toString();
99.43 + }
99.44 +
99.45 + @Factory public static Object[] create() {
99.46 + return VMTest.create(ResourcesTest.class);
99.47 + }
99.48 +}
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ShortArithmeticTest.java Fri Jan 18 14:27:22 2013 +0100
100.3 @@ -0,0 +1,102 @@
100.4 +/**
100.5 + * Back 2 Browser Bytecode Translator
100.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
100.7 + *
100.8 + * This program is free software: you can redistribute it and/or modify
100.9 + * it under the terms of the GNU General Public License as published by
100.10 + * the Free Software Foundation, version 2 of the License.
100.11 + *
100.12 + * This program is distributed in the hope that it will be useful,
100.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
100.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
100.15 + * GNU General Public License for more details.
100.16 + *
100.17 + * You should have received a copy of the GNU General Public License
100.18 + * along with this program. Look for COPYING file in the top folder.
100.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
100.20 + */
100.21 +package org.apidesign.bck2brwsr.tck;
100.22 +
100.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
100.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
100.25 +import org.testng.annotations.Factory;
100.26 +
100.27 +/**
100.28 + *
100.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
100.30 + */
100.31 +public class ShortArithmeticTest {
100.32 +
100.33 + private static short add(short x, short y) {
100.34 + return (short)(x + y);
100.35 + }
100.36 +
100.37 + private static short sub(short x, short y) {
100.38 + return (short)(x - y);
100.39 + }
100.40 +
100.41 + private static short mul(short x, short y) {
100.42 + return (short)(x * y);
100.43 + }
100.44 +
100.45 + private static short div(short x, short y) {
100.46 + return (short)(x / y);
100.47 + }
100.48 +
100.49 + private static short mod(short x, short y) {
100.50 + return (short)(x % y);
100.51 + }
100.52 +
100.53 + @Compare public short conversion() {
100.54 + return (short)123456;
100.55 + }
100.56 +
100.57 + @Compare public short addOverflow() {
100.58 + return add(Short.MAX_VALUE, (short)1);
100.59 + }
100.60 +
100.61 + @Compare public short subUnderflow() {
100.62 + return sub(Short.MIN_VALUE, (short)1);
100.63 + }
100.64 +
100.65 + @Compare public short addMaxShortAndMaxShort() {
100.66 + return add(Short.MAX_VALUE, Short.MAX_VALUE);
100.67 + }
100.68 +
100.69 + @Compare public short subMinShortAndMinShort() {
100.70 + return sub(Short.MIN_VALUE, Short.MIN_VALUE);
100.71 + }
100.72 +
100.73 + @Compare public short multiplyMaxShort() {
100.74 + return mul(Short.MAX_VALUE, (short)2);
100.75 + }
100.76 +
100.77 + @Compare public short multiplyMaxShortAndMaxShort() {
100.78 + return mul(Short.MAX_VALUE, Short.MAX_VALUE);
100.79 + }
100.80 +
100.81 + @Compare public short multiplyMinShort() {
100.82 + return mul(Short.MIN_VALUE, (short)2);
100.83 + }
100.84 +
100.85 + @Compare public short multiplyMinShortAndMinShort() {
100.86 + return mul(Short.MIN_VALUE, Short.MIN_VALUE);
100.87 + }
100.88 +
100.89 + @Compare public short multiplyPrecision() {
100.90 + return mul((short)17638, (short)1103);
100.91 + }
100.92 +
100.93 + @Compare public short division() {
100.94 + return div((short)1, (short)2);
100.95 + }
100.96 +
100.97 + @Compare public short divisionReminder() {
100.98 + return mod((short)1, (short)2);
100.99 + }
100.100 +
100.101 + @Factory
100.102 + public static Object[] create() {
100.103 + return VMTest.create(ShortArithmeticTest.class);
100.104 + }
100.105 +}
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java Fri Jan 18 14:27:22 2013 +0100
101.3 @@ -0,0 +1,31 @@
101.4 +/**
101.5 + * Back 2 Browser Bytecode Translator
101.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
101.7 + *
101.8 + * This program is free software: you can redistribute it and/or modify
101.9 + * it under the terms of the GNU General Public License as published by
101.10 + * the Free Software Foundation, version 2 of the License.
101.11 + *
101.12 + * This program is distributed in the hope that it will be useful,
101.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
101.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
101.15 + * GNU General Public License for more details.
101.16 + *
101.17 + * You should have received a copy of the GNU General Public License
101.18 + * along with this program. Look for COPYING file in the top folder.
101.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
101.20 + */
101.21 +package org.apidesign.bck2brwsr.tck;
101.22 +
101.23 +class StaticUse {
101.24 + public static final Object NON_NULL = new Object();
101.25 + private StaticUse() {
101.26 + }
101.27 +
101.28 + public void instanceMethod() {
101.29 + }
101.30 +
101.31 + public static int plus(int a, int b) {
101.32 + return a + b;
101.33 + }
101.34 +}
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102.2 +++ b/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/Resources.txt Fri Jan 18 14:27:22 2013 +0100
102.3 @@ -0,0 +1,1 @@
102.4 +Ahoj