| /* |
| * Copyright 2013 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.dev.jjs.test; |
| |
| import com.google.gwt.junit.client.GWTTestCase; |
| |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * Tests Java 7 features. |
| */ |
| public class Java7Test extends GWTTestCase { |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.gwt.dev.jjs.CompilerSuite"; |
| } |
| |
| // new style class literals |
| int million = 1_000_000; |
| |
| int five = 0b101; |
| |
| public void testNewStyleLiterals() { |
| assertEquals(1000000, million); |
| assertEquals(5, five); |
| } |
| |
| public void testSwitchOnString() { |
| |
| String s = "AA"; |
| int result = -1; |
| switch (s) { |
| case "BB": |
| result = 0; |
| break; |
| case "CC": |
| case "AA": |
| result = 1; |
| break; |
| } |
| assertEquals(1, result); |
| } |
| |
| final List<String> log = new ArrayList<String>(); |
| |
| enum ThrowsWhen { |
| NEVER, ONCONSTRUCTOR, ONCLOSE; |
| } |
| |
| class Resource implements AutoCloseable { |
| |
| final String name; |
| final ThrowsWhen throwsWhen; |
| |
| public Resource(String name) throws E1 { |
| this(name, ThrowsWhen.NEVER); |
| } |
| |
| public Resource(String name, ThrowsWhen throwsWhen) throws E1 { |
| this.name = name; |
| this.throwsWhen = throwsWhen; |
| log.add("Open " + name); |
| if (throwsWhen == ThrowsWhen.ONCONSTRUCTOR) { |
| throwException("ExceptionOnConstructor"); |
| } |
| } |
| |
| public void doSomething() { |
| log.add("doSomething " + name); |
| } |
| |
| public void throwException(String text) throws E1 { |
| throw new E1(text + " in " + name); |
| } |
| |
| public void close() throws Exception { |
| log.add("Close " + name); |
| if (throwsWhen == ThrowsWhen.ONCLOSE) { |
| throwException("ExceptionOnClose"); |
| } |
| } |
| } |
| |
| private void logException(Exception e) { |
| log.add(e.getMessage()); |
| for (Throwable t : e.getSuppressed()) { |
| log.add("Suppressed: " + t.getMessage()); |
| } |
| } |
| |
| public void testTryWithResources_noExceptions() throws Exception { |
| log.clear(); |
| try ( |
| Resource rA = new Resource("A"); |
| Resource rB = new Resource("B"); |
| Resource rC = new Resource("C")) { |
| |
| rA.doSomething(); |
| rB.doSomething(); |
| rC.doSomething(); |
| } |
| |
| assertContentsInOrder(log, |
| "Open A", |
| "Open B", |
| "Open C", |
| "doSomething A", |
| "doSomething B", |
| "doSomething C", |
| "Close C", |
| "Close B", |
| "Close A" |
| ); |
| } |
| |
| public void testTryWithResources_exceptions() throws Exception { |
| log.clear(); |
| try ( |
| Resource rA = new Resource("A"); |
| Resource rB = new Resource("B", ThrowsWhen.ONCLOSE); |
| Resource rC = new Resource("C")) { |
| |
| rA.doSomething(); |
| rB.doSomething(); |
| rC.doSomething(); |
| } catch (Exception e) { |
| log.add(e.getMessage()); |
| } finally { |
| log.add("finally"); |
| } |
| |
| assertContentsInOrder(log, |
| "Open A", |
| "Open B", |
| "Open C", |
| "doSomething A", |
| "doSomething B", |
| "doSomething C", |
| "Close C", |
| "Close B", |
| "Close A", |
| "ExceptionOnClose in B", |
| "finally" |
| ); |
| } |
| |
| public void testTryWithResources_suppressedExceptions() throws Exception { |
| log.clear(); |
| try ( |
| Resource rA = new Resource("A", ThrowsWhen.ONCLOSE); |
| Resource rB = new Resource("B"); |
| Resource rC = new Resource("C", ThrowsWhen.ONCLOSE)) { |
| |
| rA.doSomething(); |
| rB.doSomething(); |
| rC.doSomething(); |
| } catch (Exception e) { |
| logException(e); |
| } |
| |
| assertContentsInOrder(log, |
| "Open A", |
| "Open B", |
| "Open C", |
| "doSomething A", |
| "doSomething B", |
| "doSomething C", |
| "Close C", |
| "Close B", |
| "Close A", |
| "ExceptionOnClose in C", |
| "Suppressed: ExceptionOnClose in A" |
| ); |
| |
| log.clear(); |
| try ( |
| Resource rA = new Resource("A"); |
| Resource rB = new Resource("B", ThrowsWhen.ONCLOSE); |
| Resource rC = new Resource("C")) { |
| |
| rA.doSomething(); |
| rB.throwException("E1 here"); |
| rC.doSomething(); |
| } catch (Exception e) { |
| logException(e); |
| } finally { |
| log.add("finally"); |
| } |
| |
| assertContentsInOrder(log, |
| "Open A", |
| "Open B", |
| "Open C", |
| "doSomething A", |
| "Close C", |
| "Close B", |
| "Close A", |
| "E1 here in B", |
| "Suppressed: ExceptionOnClose in B", |
| "finally" |
| ); |
| } |
| |
| public void testTryWithResources_exceptionInAcquisition() { |
| log.clear(); |
| try ( |
| Resource rA = new Resource("A", ThrowsWhen.ONCLOSE); |
| Resource rB = new Resource("B", ThrowsWhen.ONCONSTRUCTOR); |
| Resource rC = new Resource("C", ThrowsWhen.ONCLOSE)) { |
| |
| rA.doSomething(); |
| rB.doSomething(); |
| rC.doSomething(); |
| } catch (Exception e) { |
| logException(e); |
| } |
| |
| assertContentsInOrder(log, |
| "Open A", |
| "Open B", |
| "Close A", |
| "ExceptionOnConstructor in B", |
| "Suppressed: ExceptionOnClose in A" |
| ); |
| } |
| |
| public void testAddSuppressedExceptions() { |
| Throwable throwable = new Throwable("primary"); |
| assertNotNull(throwable.getSuppressed()); |
| assertEquals(0, throwable.getSuppressed().length); |
| Throwable suppressed1 = new Throwable("suppressed1"); |
| throwable.addSuppressed(suppressed1); |
| assertEquals(1, throwable.getSuppressed().length); |
| assertEquals(suppressed1, throwable.getSuppressed()[0]); |
| Throwable suppressed2 = new Throwable("suppressed2"); |
| throwable.addSuppressed(suppressed2); |
| assertEquals(2, throwable.getSuppressed().length); |
| assertEquals(suppressed1, throwable.getSuppressed()[0]); |
| assertEquals(suppressed2, throwable.getSuppressed()[1]); |
| } |
| |
| static class E1 extends Exception { |
| String name; |
| public E1(String name) { |
| this.name = name; |
| } |
| |
| public int methodE1() { |
| return 0; |
| } |
| |
| @Override |
| public String getMessage() { |
| return name; |
| } |
| } |
| |
| static class E2 extends E1 { |
| public E2(String name) { |
| super(name); |
| } |
| |
| public int methodE2() { |
| return 1; |
| } |
| } |
| |
| static class E3 extends E1 { |
| public E3(String name) { |
| super(name); |
| } |
| |
| public int methodE3() { |
| return 2; |
| } |
| } |
| |
| public void testMultiExceptions() { |
| |
| int choose = 0; |
| |
| try { |
| if (choose == 0) { |
| throw new E1("e1"); |
| } else if (choose == 1) { |
| throw new E2("e2"); |
| } |
| |
| fail("Exception was not trown"); |
| } catch (E2 | E3 x) { |
| // The compiler will assign x a common supertype/superinterface of E2 and E3. |
| // Here we make sure that this clause is not entered when the supertype is thrown. |
| fail("Caught E1 instead of E2|E3"); |
| } catch (E1 x) { |
| } |
| } |
| |
| private Object unoptimizableId(Object o) { |
| if (Math.random() > -10) { |
| return o; |
| } |
| return null; |
| } |
| |
| public void testPrimitiveCastsFromObject() { |
| Object o = unoptimizableId((byte) 2); |
| assertEquals((byte) 2, (byte) o); |
| o = unoptimizableId((short) 3); |
| assertEquals((short) 3, (short) o); |
| o = unoptimizableId(1); |
| assertEquals(1, (int) o); |
| o = unoptimizableId(1L); |
| assertEquals(1L, (long) o); |
| o = unoptimizableId(0.1f); |
| assertEquals(0.1f, (float) o); |
| o = unoptimizableId(0.1); |
| assertEquals(0.1, (double) o); |
| o = unoptimizableId(true); |
| assertEquals(true, (boolean) o); |
| o = unoptimizableId('a'); |
| assertEquals('a', (char) o); |
| // Test cast from supers. |
| Number n = (Number) unoptimizableId(5); |
| assertEquals(5, (int) n); |
| Serializable s = (Serializable) unoptimizableId(6); |
| assertEquals(6, (int) s); |
| Comparable<Integer> c = (Comparable<Integer>) unoptimizableId(7); |
| assertEquals(7, (int) c); |
| |
| // Failing casts. |
| try { |
| Object boxedChar = unoptimizableId('a'); |
| boolean b = (boolean) boxedChar; |
| fail("Should have thrown a ClassCastException"); |
| } catch (ClassCastException e) { |
| // Expected. |
| } |
| |
| try { |
| Object string = unoptimizableId("string"); |
| int num = (int) string; |
| fail("Should have thrown a ClassCastException"); |
| } catch (ClassCastException e) { |
| // Expected. |
| } |
| } |
| |
| private void assertContentsInOrder(Iterable<String> contents, String... elements) { |
| assertEquals(Arrays.asList(elements).toString(), contents.toString()); |
| } |
| } |