diff --git a/.hgtags b/.hgtags index 07ac4027b55..7584fc7f74d 100644 --- a/.hgtags +++ b/.hgtags @@ -133,3 +133,5 @@ bc5710332b294676661103bb20d47d2ea3ba8def jdk8-b07 fbf3cabc9e3bb1fcf710941d777cb0400505fbe6 jdk8-b09 f651ce87127980c58e3599daba964eba2f3b4026 jdk8-b10 cc1f5ce8e504d350e0b0c28c5f84333f8d540132 jdk8-b11 +86db042b3385c338e17f7664447fdc7d406dd19e jdk8-b12 +4cc0ef72c812943743ef4765f1100e2fbe2b1a08 jdk8-b13 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index bb8cba99e8b..adfe73a17a9 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -133,3 +133,5 @@ fb1bc13260d76447e269e843859eb593fe2a8ab2 jdk8-b08 8adb70647b5af5273dfe6a540f07be667cd50216 jdk8-b09 a6c4c248e8fa350c35014fa94bab5ac1a1ac3299 jdk8-b10 1defbc57940a56f0aa41e9dee87b71e8c8b71103 jdk8-b11 +8e2104d565baee473895d5eba20e39f85ab4bf9f jdk8-b12 +26fb81a1e9ceb9baffba216acd9ded62e9e9d5ab jdk8-b13 diff --git a/corba/.hgtags b/corba/.hgtags index bd2e17921d4..1ab8b2c2344 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -133,3 +133,5 @@ cc1b599b986a37cb57de4584c5e58169766ca535 jdk8-b05 a891732c1a83082177ff7a4cf1506068d9cc0a47 jdk8-b09 cda87f7fefcee3b89742a57ce5ad9b03a54c210d jdk8-b10 0199e4fef5cc2bd234c65b93220459ef7a3bb3b1 jdk8-b11 +31d70911b712c6b4e580a3110363d5f044cfed7a jdk8-b12 +5b9d9b839d3d7fe02347827221c97c6d242a6f96 jdk8-b13 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java b/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java index 1992c25a3c1..9f7008a16f8 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2243,6 +2243,10 @@ public class IIOPInputStream } try { + Class fieldCl = fields[i].getClazz(); + if (objectValue != null && !fieldCl.isInstance(objectValue)) { + throw new IllegalArgumentException(); + } bridge.putObject( o, fields[i].getFieldID(), objectValue ) ; // reflective code: fields[i].getField().set( o, objectValue ) ; } catch (IllegalArgumentException e) { @@ -2553,6 +2557,10 @@ public class IIOPInputStream { try { Field fld = c.getDeclaredField( fieldName ) ; + Class fieldCl = fld.getType(); + if(v != null && !fieldCl.isInstance(v)) { + throw new Exception(); + } long key = bridge.objectFieldOffset( fld ) ; bridge.putObject( o, key, v ) ; } catch (Exception e) { diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 46612cd8947..662b51ccb8a 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -195,3 +195,6 @@ d815de2e85e511b7deab2a83cf80c0224d011da9 jdk8-b10 4d3850d9d326ac3a9bee2d867727e954322d014e hs23-b03 4538caeef7b6cbd4302bebced805d65e68ccf301 jdk8-b11 6534482ff68ad79066dfe15dfb6d8905f09681bd hs23-b04 +1d3900713a67a0a39faf4e12c9c158d55aebef87 jdk8-b12 +3e609627e780736f372eb14d29bb9b5e53b21fbf hs23-b05 +b92ca8e229d29004f840c67e620833d23a346761 jdk8-b13 diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make index 094332012e1..f412310f9aa 100644 --- a/hotspot/make/bsd/makefiles/buildtree.make +++ b/hotspot/make/bsd/makefiles/buildtree.make @@ -234,6 +234,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "$(call gamma-path,commonsrc,share/vm/prims) \\"; \ echo "$(call gamma-path,altsrc,share/vm) \\"; \ echo "$(call gamma-path,commonsrc,share/vm) \\"; \ + echo "$(call gamma-path,altsrc,share/vm/precompiled) \\"; \ + echo "$(call gamma-path,commonsrc,share/vm/precompiled) \\"; \ echo "$(call gamma-path,altsrc,cpu/$(SRCARCH)/vm) \\"; \ echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \ echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \ diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index be09894628f..62148457083 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -88,7 +88,7 @@ ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \ ifneq ($(USE_PRECOMPILED_HEADER),0) USE_PRECOMPILED_HEADER=1 PRECOMPILED_HEADER_DIR=. -PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled.hpp +PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch endif endif diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index 09ea6779834..dbe6ad9b9bb 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011 HS_MAJOR_VER=23 HS_MINOR_VER=0 -HS_BUILD_NUMBER=04 +HS_BUILD_NUMBER=05 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make index f8a1e885c5f..b1eb00bb98c 100644 --- a/hotspot/make/linux/makefiles/buildtree.make +++ b/hotspot/make/linux/makefiles/buildtree.make @@ -223,6 +223,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "$(call gamma-path,commonsrc,share/vm/prims) \\"; \ echo "$(call gamma-path,altsrc,share/vm) \\"; \ echo "$(call gamma-path,commonsrc,share/vm) \\"; \ + echo "$(call gamma-path,altsrc,share/vm/precompiled) \\"; \ + echo "$(call gamma-path,commonsrc,share/vm/precompiled) \\"; \ echo "$(call gamma-path,altsrc,cpu/$(SRCARCH)/vm) \\"; \ echo "$(call gamma-path,commonsrc,cpu/$(SRCARCH)/vm) \\"; \ echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(SRCARCH)/vm) \\"; \ diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make index e36cec66f76..2da52739b6a 100644 --- a/hotspot/make/linux/makefiles/gcc.make +++ b/hotspot/make/linux/makefiles/gcc.make @@ -52,7 +52,7 @@ ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \ ifneq ($(USE_PRECOMPILED_HEADER),0) USE_PRECOMPILED_HEADER=1 PRECOMPILED_HEADER_DIR=. -PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled.hpp +PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch endif endif diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make index 30e03bedb8b..a46d6b3378f 100644 --- a/hotspot/make/solaris/makefiles/buildtree.make +++ b/hotspot/make/solaris/makefiles/buildtree.make @@ -216,6 +216,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "$(call gamma-path,commonsrc,share/vm/prims) \\"; \ echo "$(call gamma-path,altsrc,share/vm) \\"; \ echo "$(call gamma-path,commonsrc,share/vm) \\"; \ + echo "$(call gamma-path,altsrc,share/vm/precompiled) \\"; \ + echo "$(call gamma-path,commonsrc,share/vm/precompiled) \\"; \ echo "$(call gamma-path,altsrc,cpu/$(ARCH)/vm) \\"; \ echo "$(call gamma-path,commonsrc,cpu/$(ARCH)/vm) \\"; \ echo "$(call gamma-path,altsrc,os_cpu/$(OS_FAMILY)_$(ARCH)/vm) \\"; \ diff --git a/hotspot/make/solaris/makefiles/gcc.make b/hotspot/make/solaris/makefiles/gcc.make index b0cdfc9a231..15e43ea8d66 100644 --- a/hotspot/make/solaris/makefiles/gcc.make +++ b/hotspot/make/solaris/makefiles/gcc.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \ ifneq ($(USE_PRECOMPILED_HEADER),0) USE_PRECOMPILED_HEADER=1 PRECOMPILED_HEADER_DIR=. -PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled.hpp +PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch endif endif diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make index 1ee86646137..f0b1b933630 100644 --- a/hotspot/make/windows/makefiles/vm.make +++ b/hotspot/make/windows/makefiles/vm.make @@ -134,6 +134,7 @@ CPP_INCLUDE_DIRS=$(CPP_INCLUDE_DIRS) /I "$(ALTSRC)\cpu\$(Platform_arch)\vm" CPP_INCLUDE_DIRS=$(CPP_INCLUDE_DIRS) \ /I "$(COMMONSRC)\share\vm" \ + /I "$(COMMONSRC)\share\vm\precompiled" \ /I "$(COMMONSRC)\share\vm\prims" \ /I "$(COMMONSRC)\os\windows\vm" \ /I "$(COMMONSRC)\os_cpu\windows_$(Platform_arch)\vm" \ diff --git a/hotspot/src/share/vm/precompiled.hpp b/hotspot/src/share/vm/precompiled/precompiled.hpp similarity index 100% rename from hotspot/src/share/vm/precompiled.hpp rename to hotspot/src/share/vm/precompiled/precompiled.hpp diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 78334da4ff4..f770102ab48 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2580,7 +2580,7 @@ class CommandLineFlags { diagnostic(bool, DebugInlinedCalls, true, \ "If false, restricts profiled locations to the root method only") \ \ - product(bool, PrintVMOptions, trueInDebug, \ + product(bool, PrintVMOptions, NOT_EMBEDDED(trueInDebug) EMBEDDED_ONLY(false),\ "Print flags that appeared on the command line") \ \ product(bool, IgnoreUnrecognizedVMOptions, false, \ diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e0ff678bbaa..e037f606480 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -133,3 +133,5 @@ de4794dd69c48b08029d158a972993ff9d5627df jdk8-b08 93554324c014282571aeeb48552ad00d3fedb089 jdk8-b09 d21a4d5141c04bc9e88f2c0253121d449b66d667 jdk8-b10 d1b7a4f6dd2065fdeafbcdfd9dcc0072da8c6881 jdk8-b11 +ca977d167697a561c04894187fc1c4d927582ffa jdk8-b12 +bcc739229f6384786c7ac0b52c1822c85674dcf1 jdk8-b13 diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 3eec004d4a8..67d2711e9d2 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -133,3 +133,5 @@ acffff22a9465005e8eb206224fae9f2ea4fd469 jdk8-b06 70172e57cf29efe271b068987eefb601c2a77780 jdk8-b09 8e7fdc8e3c758644ca6d0fd70bb255e9d2e64cda jdk8-b10 a12ab897a249feb7859a6e6cd84b49411f4c06ac jdk8-b11 +e6eed2ff5d5f62bdc815beb5276d23347600c760 jdk8-b12 +adf2a6b5fde14090beb9ebc40c4114132ddee731 jdk8-b13 diff --git a/jaxws/jaxws.properties b/jaxws/jaxws.properties index bd6e153899b..f3952bbddc5 100644 --- a/jaxws/jaxws.properties +++ b/jaxws/jaxws.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,15 @@ drops.master.copy.base=${drops.dir} -jaxws_src.bundle.name=jdk7-jaxws2_2_4-b03-2011_05_27.zip -jaxws_src.bundle.md5.checksum=2f5b829ade70f67fe272d0b322e3e702 +jaxws_src.bundle.name=jdk8-jaxws2_2_4-b01-2011_07_22.zip +jaxws_src.bundle.md5.checksum=f64bedd3c512e6b1ca265fda2feb0905 jaxws_src.master.bundle.dir=${drops.master.copy.base} -jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk7 +jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk8 -jaf_src.bundle.name=jdk7-jaf-2010_08_19.zip +jaf_src.bundle.name=jdk8-jaf-2011_07_22.zip jaf_src.bundle.md5.checksum=18d15dfd71117daadb332af003d08212 jaf_src.master.bundle.dir=${drops.master.copy.base} -jaf_src.master.bundle.url.base=https://java.net/downloads/jax-ws/JDK7 +jaf_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk8 #jaxws_tests.bundle.name=jdk7-jaxws-tests-2009_08_28.zip #jaxws_tests.master.bundle.dir=${drops.master.copy.base} diff --git a/jdk/.hgtags b/jdk/.hgtags index e1e7ba132b7..472ceb82660 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -134,3 +134,5 @@ f1ec21b8142168ff40f3278d2f6b5fe4bd5f3b26 jdk8-b09 4788745572ef2bde34924ef34e7e4d55ba07e979 jdk8-b10 7ab0d613cd1a271a9763ffb894dc1f0a5b95a7e4 jdk8-b11 09fd2067f715e4505c44b01c301258a4e8f8964e jdk8-b12 +4cb2e8679b27432854690cb688ea06d3b2d8e008 jdk8-b13 +99632935785e2038b2fc836da9f2ede69dea294b jdk8-b14 diff --git a/jdk/make/common/Demo.gmk b/jdk/make/common/Demo.gmk index a3788aea7d5..429c4e546c9 100644 --- a/jdk/make/common/Demo.gmk +++ b/jdk/make/common/Demo.gmk @@ -158,6 +158,8 @@ ifneq ($(strip $(DEMO_ALL_NATIVE_SOURCES)),) # bit between them. LINK.demo = $(LINK.c) LDLIBS.demo = $(EXTRA_LIBS) $(LFLAGS_$(COMPILER_VERSION)) + DEMO_VERSION_INFO = $(OBJDIR)/$(LIBRARY).res + LDLIBS.demo += $(DEMO_VERSION_INFO) else ifneq ($(DEMO_NEEDS_CPP),) LINK.demo = $(LINK.cpp) @@ -288,6 +290,13 @@ ifndef DEMO_SKIP_SRCZIP $(install-file) endif +ifeq ($(PLATFORM),windows) +# JDK name required here +RC_FLAGS += /D "JDK_FNAME=$(LIBRARY).dll" \ + /D "JDK_INTERNAL_NAME=$(LIBRARY)" \ + /D "JDK_FTYPE=0x2L" +endif + # Native library building ifdef DEMO_LIBRARY @@ -308,6 +317,9 @@ $(OBJDIR)/%.$(OBJECT_SUFFIX): $(DEMO_BUILD_SRCDIR)/%.cpp # Actual creation of the native shared library (C++ and C are different) $(DEMO_LIBRARY): $(DEMO_FULL_OBJECTS) @$(prep-target) + ifeq ($(PLATFORM),windows) + $(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(DEMO_VERSION_INFO) $(VERSIONINFO_RESOURCE) + endif $(LINK.demo) $(SHARED_LIBRARY_FLAG) $(CC_PROGRAM_OUTPUT_FLAG)$@ \ $(DEMO_FULL_OBJECTS) $(LDLIBS.demo) @$(call binary_file_verification,$@) diff --git a/jdk/make/java/nio/FILES_java.gmk b/jdk/make/java/nio/FILES_java.gmk index 41397cacdc0..b394b89e483 100644 --- a/jdk/make/java/nio/FILES_java.gmk +++ b/jdk/make/java/nio/FILES_java.gmk @@ -232,6 +232,7 @@ FILES_src = \ sun/nio/cs/UTF_16BE.java \ sun/nio/cs/UTF_16LE.java \ sun/nio/cs/UTF_8.java \ + sun/nio/cs/CESU_8.java \ sun/nio/cs/Unicode.java \ sun/nio/cs/UnicodeDecoder.java \ sun/nio/cs/UnicodeEncoder.java \ diff --git a/jdk/make/sun/net/Makefile b/jdk/make/sun/net/Makefile index 3e56798e2ee..b36fa664f8e 100644 --- a/jdk/make/sun/net/Makefile +++ b/jdk/make/sun/net/Makefile @@ -28,6 +28,7 @@ PACKAGE = sun.net PRODUCT = sun SUBDIRS_MAKEFLAGS += JAVAC_MAX_WARNINGS=true SUBDIRS_MAKEFLAGS += JAVAC_WARNINGS_FATAL=true +SUBDIRS_MAKEFLAGS += JAVAC_LINT_OPTIONS=-Xlint:all,-deprecation,-path include $(BUILDDIR)/common/Defs.gmk SUBDIRS = others spi diff --git a/jdk/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java b/jdk/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java index c17fcf72136..c60435331ec 100644 --- a/jdk/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java +++ b/jdk/src/share/classes/com/sun/net/ssl/HttpsURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,6 +179,12 @@ class HttpsURLConnection extends HttpURLConnection throw new IllegalArgumentException( "no SSLSocketFactory specified"); } + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkSetFactory(); + } + sslSocketFactory = sf; } diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java index 61baa1595ad..2fba8455968 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java @@ -250,6 +250,8 @@ public class IdResolver { int index=s==null ? elementIndex : names.indexOf(n.getNamespaceURI()); index=(index<0) ? namesLength : index; String name=n.getLocalName(); + if (name == null) + name = n.getName(); if (name.length()>2) continue; String value=n.getNodeValue(); diff --git a/jdk/src/share/classes/java/awt/AWTKeyStroke.java b/jdk/src/share/classes/java/awt/AWTKeyStroke.java index fc311535d65..13f6edd81f0 100644 --- a/jdk/src/share/classes/java/awt/AWTKeyStroke.java +++ b/jdk/src/share/classes/java/awt/AWTKeyStroke.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package java.awt; import java.awt.event.KeyEvent; +import sun.awt.AppContext; import java.awt.event.InputEvent; import java.util.Collections; import java.util.HashMap; @@ -66,9 +67,6 @@ import java.lang.reflect.Field; public class AWTKeyStroke implements Serializable { static final long serialVersionUID = -6430539691155161871L; - private static Map cache; - private static AWTKeyStroke cacheKey; - private static Constructor ctor = getCtor(AWTKeyStroke.class); private static Map modifierKeywords; /** * Associates VK_XXX (as a String) with code (as Integer). This is @@ -77,6 +75,25 @@ public class AWTKeyStroke implements Serializable { */ private static VKCollection vks; + //A key for the collection of AWTKeyStrokes within AppContext. + private static Object APP_CONTEXT_CACHE_KEY = new Object(); + //A key withing the cache + private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke(); + + /* + * Reads keystroke class from AppContext and if null, puts there the + * AWTKeyStroke class. + * Must be called under locked AWTKeyStro + */ + private static Class getAWTKeyStrokeClass() { + Class clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); + if (clazz == null) { + clazz = AWTKeyStroke.class; + AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class); + } + return clazz; + } + private char keyChar = KeyEvent.CHAR_UNDEFINED; private int keyCode = KeyEvent.VK_UNDEFINED; private int modifiers; @@ -164,9 +181,12 @@ public class AWTKeyStroke implements Serializable { if (subclass == null) { throw new IllegalArgumentException("subclass cannot be null"); } - if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) { - // Already registered - return; + synchronized (AWTKeyStroke.class) { + Class keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class); + if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){ + // Already registered + return; + } } if (!AWTKeyStroke.class.isAssignableFrom(subclass)) { throw new ClassCastException("subclass is not derived from AWTKeyStroke"); @@ -197,9 +217,9 @@ public class AWTKeyStroke implements Serializable { } synchronized (AWTKeyStroke.class) { - AWTKeyStroke.ctor = ctor; - cache = null; - cacheKey = null; + AppContext.getAppContext().put(AWTKeyStroke.class, subclass); + AppContext.getAppContext().remove(APP_CONTEXT_CACHE_KEY); + AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY); } } @@ -229,13 +249,19 @@ public class AWTKeyStroke implements Serializable { private static synchronized AWTKeyStroke getCachedStroke (char keyChar, int keyCode, int modifiers, boolean onKeyRelease) { + Map cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY); + AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY); + if (cache == null) { cache = new HashMap(); + AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache); } if (cacheKey == null) { try { - cacheKey = (AWTKeyStroke)ctor.newInstance((Object[]) null); + Class clazz = getAWTKeyStrokeClass(); + cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null); + AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey); } catch (InstantiationException e) { assert(false); } catch (IllegalAccessException e) { @@ -253,9 +279,8 @@ public class AWTKeyStroke implements Serializable { if (stroke == null) { stroke = cacheKey; cache.put(stroke, stroke); - cacheKey = null; + AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY); } - return stroke; } diff --git a/jdk/src/share/classes/java/io/InputStream.java b/jdk/src/share/classes/java/io/InputStream.java index 23c166ed673..63d31d51f99 100644 --- a/jdk/src/share/classes/java/io/InputStream.java +++ b/jdk/src/share/classes/java/io/InputStream.java @@ -44,10 +44,9 @@ package java.io; */ public abstract class InputStream implements Closeable { - // SKIP_BUFFER_SIZE is used to determine the size of skipBuffer - private static final int SKIP_BUFFER_SIZE = 2048; - // skipBuffer is initialized in skip(long), if needed. - private static byte[] skipBuffer; + // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to + // use when skipping. + private static final int MAX_SKIP_BUFFER_SIZE = 2048; /** * Reads the next byte of data from the input stream. The value byte is @@ -212,18 +211,15 @@ public abstract class InputStream implements Closeable { long remaining = n; int nr; - if (skipBuffer == null) - skipBuffer = new byte[SKIP_BUFFER_SIZE]; - - byte[] localSkipBuffer = skipBuffer; if (n <= 0) { return 0; } + int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); + byte[] skipBuffer = new byte[size]; while (remaining > 0) { - nr = read(localSkipBuffer, 0, - (int) Math.min(SKIP_BUFFER_SIZE, remaining)); + nr = read(skipBuffer, 0, (int)Math.min(size, remaining)); if (nr < 0) { break; } diff --git a/jdk/src/share/classes/java/lang/ref/Reference.java b/jdk/src/share/classes/java/lang/ref/Reference.java index f483edf58d2..6d3d9c3bd1a 100644 --- a/jdk/src/share/classes/java/lang/ref/Reference.java +++ b/jdk/src/share/classes/java/lang/ref/Reference.java @@ -27,7 +27,6 @@ package java.lang.ref; import sun.misc.Cleaner; - /** * Abstract base class for reference objects. This class defines the * operations common to all reference objects. Because reference objects are @@ -69,7 +68,7 @@ public abstract class Reference { * null. * * Pending: queue = ReferenceQueue with which instance is registered; - * next = Following instance in queue, or this if at end of list. + * next = this * * Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance * in queue, or this if at end of list. @@ -81,17 +80,28 @@ public abstract class Reference { * the next field is null then the instance is active; if it is non-null, * then the collector should treat the instance normally. * - * To ensure that concurrent collector can discover active Reference + * To ensure that a concurrent collector can discover active Reference * objects without interfering with application threads that may apply * the enqueue() method to those objects, collectors should link - * discovered objects through the discovered field. + * discovered objects through the discovered field. The discovered + * field is also used for linking Reference objects in the pending list. */ private T referent; /* Treated specially by GC */ ReferenceQueue queue; + /* When active: NULL + * pending: this + * Enqueued: next reference in queue (or this if last) + * Inactive: this + */ Reference next; + + /* When active: next element in a discovered reference list maintained by GC (or this if last) + * pending: next element in the pending list (or null if last) + * otherwise: NULL + */ transient private Reference discovered; /* used by VM */ @@ -106,7 +116,8 @@ public abstract class Reference { /* List of References waiting to be enqueued. The collector adds * References to this list, while the Reference-handler thread removes - * them. This list is protected by the above lock object. + * them. This list is protected by the above lock object. The + * list uses the discovered field to link its elements. */ private static Reference pending = null; @@ -120,14 +131,12 @@ public abstract class Reference { public void run() { for (;;) { - Reference r; synchronized (lock) { if (pending != null) { r = pending; - Reference rn = r.next; - pending = (rn == r) ? null : rn; - r.next = r; + pending = r.discovered; + r.discovered = null; } else { try { lock.wait(); @@ -201,10 +210,8 @@ public abstract class Reference { * been enqueued */ public boolean isEnqueued() { - /* In terms of the internal states, this predicate actually tests - whether the instance is either Pending or Enqueued */ synchronized (this) { - return (this.queue != ReferenceQueue.NULL) && (this.next != null); + return (this.next != null && this.queue == ReferenceQueue.ENQUEUED); } } diff --git a/jdk/src/share/classes/java/net/InetAddress.java b/jdk/src/share/classes/java/net/InetAddress.java index a64011f0914..8758cab7af3 100644 --- a/jdk/src/share/classes/java/net/InetAddress.java +++ b/jdk/src/share/classes/java/net/InetAddress.java @@ -876,10 +876,12 @@ class InetAddress implements java.io.Serializable { nameService = java.security.AccessController.doPrivileged( new java.security.PrivilegedExceptionAction() { public NameService run() { - Iterator itr = Service.providers(NameServiceDescriptor.class); + // sun.misc.Service.providers returns a raw Iterator + @SuppressWarnings("unchecked") + Iterator itr = + Service.providers(NameServiceDescriptor.class); while (itr.hasNext()) { - NameServiceDescriptor nsd - = (NameServiceDescriptor)itr.next(); + NameServiceDescriptor nsd = itr.next(); if (providerName. equalsIgnoreCase(nsd.getType()+"," +nsd.getProviderName())) { diff --git a/jdk/src/share/classes/java/net/ServerSocket.java b/jdk/src/share/classes/java/net/ServerSocket.java index 86bc174b88f..b4ab7b6b8a4 100644 --- a/jdk/src/share/classes/java/net/ServerSocket.java +++ b/jdk/src/share/classes/java/net/ServerSocket.java @@ -267,10 +267,9 @@ class ServerSocket implements java.io.Closeable { AccessController.doPrivileged( new PrivilegedExceptionAction() { public Void run() throws NoSuchMethodException { - Class[] cl = new Class[2]; - cl[0] = SocketAddress.class; - cl[1] = Integer.TYPE; - impl.getClass().getDeclaredMethod("connect", cl); + impl.getClass().getDeclaredMethod("connect", + SocketAddress.class, + int.class); return null; } }); diff --git a/jdk/src/share/classes/java/nio/charset/Charset.java b/jdk/src/share/classes/java/nio/charset/Charset.java index 53b0d2be957..2d3f020bcf6 100644 --- a/jdk/src/share/classes/java/nio/charset/Charset.java +++ b/jdk/src/share/classes/java/nio/charset/Charset.java @@ -435,7 +435,7 @@ public abstract class Charset AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { - Class epc + Class epc = Class.forName("sun.nio.cs.ext.ExtendedCharsets"); extendedProvider = (CharsetProvider)epc.newInstance(); } catch (ClassNotFoundException x) { diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index 27778294000..2683b7efe09 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -363,6 +363,17 @@ public final class Files { // -- Directories -- + private static class AcceptAllFilter + implements DirectoryStream.Filter + { + private AcceptAllFilter() { } + + @Override + public boolean accept(Path entry) { return true; } + + static final AcceptAllFilter FILTER = new AcceptAllFilter(); + } + /** * Opens a directory, returning a {@link DirectoryStream} to iterate over * all entries in the directory. The elements returned by the directory @@ -397,12 +408,7 @@ public final class Files { public static DirectoryStream newDirectoryStream(Path dir) throws IOException { - return provider(dir).newDirectoryStream(dir, new DirectoryStream.Filter() { - @Override - public boolean accept(Path entry) { - return true; - } - }); + return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER); } /** diff --git a/jdk/src/share/classes/java/security/Security.java b/jdk/src/share/classes/java/security/Security.java index b9dd1441d63..f8890e62fec 100644 --- a/jdk/src/share/classes/java/security/Security.java +++ b/jdk/src/share/classes/java/security/Security.java @@ -814,7 +814,7 @@ public final class Security { public Void run() { try { /* Get the class via the bootstrap class loader. */ - Class cl = Class.forName( + Class cl = Class.forName( "java.lang.SecurityManager", false, null); Field f = null; boolean accessible = false; diff --git a/jdk/src/share/classes/java/text/BreakIterator.java b/jdk/src/share/classes/java/text/BreakIterator.java index e00e09adc31..6010784dbaf 100644 --- a/jdk/src/share/classes/java/text/BreakIterator.java +++ b/jdk/src/share/classes/java/text/BreakIterator.java @@ -443,7 +443,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for word breaks + * for word breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for word breaks */ @@ -454,7 +454,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for word breaks + * for word breaks * for the given locale. * @param locale the desired locale * @return A break iterator for word breaks @@ -470,7 +470,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for line breaks + * for line breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for line breaks */ @@ -481,7 +481,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for line breaks + * for line breaks * for the given locale. * @param locale the desired locale * @return A break iterator for line breaks @@ -497,7 +497,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for character breaks + * for character breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for character breaks */ @@ -508,7 +508,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for character breaks + * for character breaks * for the given locale. * @param locale the desired locale * @return A break iterator for character breaks @@ -524,7 +524,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for sentence breaks + * for sentence breaks * for the {@linkplain Locale#getDefault() default locale}. * @return A break iterator for sentence breaks */ @@ -535,7 +535,7 @@ public abstract class BreakIterator implements Cloneable /** * Returns a new BreakIterator instance - * for sentence breaks + * for sentence breaks * for the given locale. * @param locale the desired locale * @return A break iterator for sentence breaks diff --git a/jdk/src/share/classes/java/util/Collections.java b/jdk/src/share/classes/java/util/Collections.java index e55eb59296e..04e642e1c00 100644 --- a/jdk/src/share/classes/java/util/Collections.java +++ b/jdk/src/share/classes/java/util/Collections.java @@ -3201,6 +3201,102 @@ public class Collections { } } + /** + * Returns the empty sorted set (immutable). This set is serializable. + * + *

This example illustrates the type-safe way to obtain an empty sorted + * set: + *

+     *     SortedSet<String> s = Collections.emptySortedSet();
+     * 
+ * Implementation note: Implementations of this method need not + * create a separate SortedSet object for each call. + * + * @since 1.8 + */ + @SuppressWarnings("unchecked") + public static final SortedSet emptySortedSet() { + return (SortedSet) new EmptySortedSet<>(); + } + + /** + * @serial include + */ + private static class EmptySortedSet + extends AbstractSet + implements SortedSet, Serializable + { + private static final long serialVersionUID = 6316515401502265487L; + public Iterator iterator() { return emptyIterator(); } + public int size() {return 0;} + public boolean isEmpty() {return true;} + public boolean contains(Object obj) {return false;} + public boolean containsAll(Collection c) { return c.isEmpty(); } + public Object[] toArray() { return new Object[0]; } + + public E[] toArray(E[] a) { + if (a.length > 0) + a[0] = null; + return a; + } + + // Preserves singleton property + private Object readResolve() { + return new EmptySortedSet<>(); + } + + public Comparator comparator() { + return null; + } + + public SortedSet subSet(Object fromElement, Object toElement) { + Objects.requireNonNull(fromElement); + Objects.requireNonNull(toElement); + + if (!(fromElement instanceof Comparable) || + !(toElement instanceof Comparable)) + { + throw new ClassCastException(); + } + + if ((((Comparable)fromElement).compareTo(toElement) >= 0) || + (((Comparable)toElement).compareTo(fromElement) < 0)) + { + throw new IllegalArgumentException(); + } + + return emptySortedSet(); + } + + public SortedSet headSet(Object toElement) { + Objects.requireNonNull(toElement); + + if (!(toElement instanceof Comparable)) { + throw new ClassCastException(); + } + + return emptySortedSet(); + } + + public SortedSet tailSet(Object fromElement) { + Objects.requireNonNull(fromElement); + + if (!(fromElement instanceof Comparable)) { + throw new ClassCastException(); + } + + return emptySortedSet(); + } + + public E first() { + throw new NoSuchElementException(); + } + + public E last() { + throw new NoSuchElementException(); + } + } + /** * The empty list (immutable). This list is serializable. * diff --git a/jdk/src/share/classes/java/util/CurrencyData.properties b/jdk/src/share/classes/java/util/CurrencyData.properties index 5cfc1397e6e..b943993522f 100644 --- a/jdk/src/share/classes/java/util/CurrencyData.properties +++ b/jdk/src/share/classes/java/util/CurrencyData.properties @@ -71,7 +71,7 @@ all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036 # # The table is based on the following web sites: # http://www.din.de/gremien/nas/nabd/iso3166ma/codlstp1/db_en.html -# http://www.bsi-global.com/iso4217currency +# http://www.currency-iso.org/iso_index/iso_tables.htm # http://www.cia.gov/cia/publications/factbook/indexgeo.html # AFGHANISTAN @@ -105,7 +105,7 @@ AU=AUD # AUSTRIA AT=EUR # AZERBAIJAN -AZ=AZM;2005-12-31-20-00-00;AZN +AZ=AZN # BAHAMAS BS=BSD # BAHRAIN @@ -378,7 +378,7 @@ MS=XCD # MOROCCO MA=MAD # MOZAMBIQUE -MZ=MZM;2006-06-30-22-00-00;MZN +MZ=MZN # MYANMAR MM=MMK # NAMIBIA @@ -440,7 +440,7 @@ QA=QAR # REUNION RE=EUR # ROMANIA -RO=ROL;2005-06-30-21-00-00;RON +RO=RON # RUSSIAN FEDERATION RU=RUB # RWANDA @@ -532,7 +532,7 @@ TT=TTD # TUNISIA TN=TND # TURKEY -TR=TRL;2004-12-31-22-00-00;TRY +TR=TRY # TURKMENISTAN TM=TMT # TURKS AND CAICOS ISLANDS @@ -558,7 +558,7 @@ UZ=UZS # VANUATU VU=VUV # VENEZUELA -VE=VEB;2008-01-01-04-00-00;VEF +VE=VEF # VIET NAM VN=VND # VIRGIN ISLANDS, BRITISH diff --git a/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java b/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java index fbd8fca1372..5027b9a5788 100644 --- a/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java +++ b/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -347,6 +347,9 @@ class HttpsURLConnection extends HttpURLConnection * @param sf the SSL socket factory * @throws IllegalArgumentException if the SSLSocketFactory * parameter is null. + * @throws SecurityException if a security manager exists and its + * checkSetFactory method does not allow + * a socket factory to be specified. * @see #getSSLSocketFactory() */ public void setSSLSocketFactory(SSLSocketFactory sf) { @@ -355,6 +358,10 @@ class HttpsURLConnection extends HttpURLConnection "no SSLSocketFactory specified"); } + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkSetFactory(); + } sslSocketFactory = sf; } diff --git a/jdk/src/share/classes/javax/net/ssl/SSLEngine.java b/jdk/src/share/classes/javax/net/ssl/SSLEngine.java index 2eea55121cb..411626cd7a1 100644 --- a/jdk/src/share/classes/javax/net/ssl/SSLEngine.java +++ b/jdk/src/share/classes/javax/net/ssl/SSLEngine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -538,7 +538,7 @@ public abstract class SSLEngine { * If this SSLEngine has not yet started its initial * handshake, this method will automatically start the handshake. *

- * This method will attempt to produce one SSL/TLS packet, and will + * This method will attempt to produce SSL/TLS records, and will * consume as much source data as possible, but will never consume * more than the sum of the bytes remaining in each buffer. Each * ByteBuffer's position is updated to reflect the diff --git a/jdk/src/share/classes/sun/net/ResourceManager.java b/jdk/src/share/classes/sun/net/ResourceManager.java index 11bfc464819..068b8484728 100644 --- a/jdk/src/share/classes/sun/net/ResourceManager.java +++ b/jdk/src/share/classes/sun/net/ResourceManager.java @@ -41,13 +41,14 @@ public class ResourceManager { /* default maximum number of udp sockets per VM * when a security manager is enabled. - * The default is 1024 which is high enough to be useful + * The default is 25 which is high enough to be useful * but low enough to be well below the maximum number - * of port numbers actually available on all OSes for - * such sockets (5000 on some versions of windows) + * of port numbers actually available on all OSes + * when multiplied by the maximum feasible number of VM processes + * that could practically be spawned. */ - private static final int DEFAULT_MAX_SOCKETS = 1024; + private static final int DEFAULT_MAX_SOCKETS = 25; private static final int maxSockets; private static final AtomicInteger numSockets; diff --git a/jdk/src/share/classes/sun/nio/ch/Util.java b/jdk/src/share/classes/sun/nio/ch/Util.java index 9aa7c162854..fafc48f3552 100644 --- a/jdk/src/share/classes/sun/nio/ch/Util.java +++ b/jdk/src/share/classes/sun/nio/ch/Util.java @@ -363,10 +363,10 @@ class Util { try { Class cl = Class.forName("java.nio.DirectByteBuffer"); Constructor ctor = cl.getDeclaredConstructor( - new Class[] { int.class, - long.class, - FileDescriptor.class, - Runnable.class }); + new Class[] { int.class, + long.class, + FileDescriptor.class, + Runnable.class }); ctor.setAccessible(true); directByteBufferConstructor = ctor; } catch (ClassNotFoundException | @@ -408,10 +408,10 @@ class Util { try { Class cl = Class.forName("java.nio.DirectByteBufferR"); Constructor ctor = cl.getDeclaredConstructor( - new Class[] { int.class, - long.class, - FileDescriptor.class, - Runnable.class }); + new Class[] { int.class, + long.class, + FileDescriptor.class, + Runnable.class }); ctor.setAccessible(true); directByteBufferRConstructor = ctor; } catch (ClassNotFoundException | diff --git a/jdk/src/share/classes/sun/nio/cs/CESU_8.java b/jdk/src/share/classes/sun/nio/cs/CESU_8.java new file mode 100644 index 00000000000..40711f83d86 --- /dev/null +++ b/jdk/src/share/classes/sun/nio/cs/CESU_8.java @@ -0,0 +1,604 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.nio.cs; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +/* Legal CESU-8 Byte Sequences + * + * # Code Points Bits Bit/Byte pattern + * 1 7 0xxxxxxx + * U+0000..U+007F 00..7F + * + * 2 11 110xxxxx 10xxxxxx + * U+0080..U+07FF C2..DF 80..BF + * + * 3 16 1110xxxx 10xxxxxx 10xxxxxx + * U+0800..U+0FFF E0 A0..BF 80..BF + * U+1000..U+FFFF E1..EF 80..BF 80..BF + * + */ + +class CESU_8 extends Unicode +{ + public CESU_8() { + super("CESU-8", StandardCharsets.aliases_CESU_8); + } + + public String historicalName() { + return "CESU8"; + } + + public CharsetDecoder newDecoder() { + return new Decoder(this); + } + + public CharsetEncoder newEncoder() { + return new Encoder(this); + } + + private static final void updatePositions(Buffer src, int sp, + Buffer dst, int dp) { + src.position(sp - src.arrayOffset()); + dst.position(dp - dst.arrayOffset()); + } + + private static class Decoder extends CharsetDecoder + implements ArrayDecoder { + private Decoder(Charset cs) { + super(cs, 1.0f, 1.0f); + } + + private static boolean isNotContinuation(int b) { + return (b & 0xc0) != 0x80; + } + + // [E0] [A0..BF] [80..BF] + // [E1..EF] [80..BF] [80..BF] + private static boolean isMalformed3(int b1, int b2, int b3) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80; + } + + // only used when there is only one byte left in src buffer + private static boolean isMalformed3_2(int b1, int b2) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80; + } + + + // [F0] [90..BF] [80..BF] [80..BF] + // [F1..F3] [80..BF] [80..BF] [80..BF] + // [F4] [80..8F] [80..BF] [80..BF] + // only check 80-be range here, the [0xf0,0x80...] and [0xf4,0x90-...] + // will be checked by Character.isSupplementaryCodePoint(uc) + private static boolean isMalformed4(int b2, int b3, int b4) { + return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 || + (b4 & 0xc0) != 0x80; + } + + // only used when there is less than 4 bytes left in src buffer + private static boolean isMalformed4_2(int b1, int b2) { + return (b1 == 0xf0 && b2 == 0x90) || + (b2 & 0xc0) != 0x80; + } + + private static boolean isMalformed4_3(int b3) { + return (b3 & 0xc0) != 0x80; + } + + private static CoderResult malformedN(ByteBuffer src, int nb) { + switch (nb) { + case 1: + case 2: // always 1 + return CoderResult.malformedForLength(1); + case 3: + int b1 = src.get(); + int b2 = src.get(); // no need to lookup b3 + return CoderResult.malformedForLength( + ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + isNotContinuation(b2)) ? 1 : 2); + case 4: // we don't care the speed here + b1 = src.get() & 0xff; + b2 = src.get() & 0xff; + if (b1 > 0xf4 || + (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) || + (b1 == 0xf4 && (b2 & 0xf0) != 0x80) || + isNotContinuation(b2)) + return CoderResult.malformedForLength(1); + if (isNotContinuation(src.get())) + return CoderResult.malformedForLength(2); + return CoderResult.malformedForLength(3); + default: + assert false; + return null; + } + } + + private static CoderResult malformed(ByteBuffer src, int sp, + CharBuffer dst, int dp, + int nb) + { + src.position(sp - src.arrayOffset()); + CoderResult cr = malformedN(src, nb); + updatePositions(src, sp, dst, dp); + return cr; + } + + + private static CoderResult malformed(ByteBuffer src, + int mark, int nb) + { + src.position(mark); + CoderResult cr = malformedN(src, nb); + src.position(mark); + return cr; + } + + private static CoderResult malformedForLength(ByteBuffer src, + int sp, + CharBuffer dst, + int dp, + int malformedNB) + { + updatePositions(src, sp, dst, dp); + return CoderResult.malformedForLength(malformedNB); + } + + private static CoderResult malformedForLength(ByteBuffer src, + int mark, + int malformedNB) + { + src.position(mark); + return CoderResult.malformedForLength(malformedNB); + } + + + private static CoderResult xflow(Buffer src, int sp, int sl, + Buffer dst, int dp, int nb) { + updatePositions(src, sp, dst, dp); + return (nb == 0 || sl - sp < nb) + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; + } + + private static CoderResult xflow(Buffer src, int mark, int nb) { + src.position(mark); + return (nb == 0 || src.remaining() < nb) + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; + } + + private CoderResult decodeArrayLoop(ByteBuffer src, + CharBuffer dst) + { + // This method is optimized for ASCII input. + byte[] sa = src.array(); + int sp = src.arrayOffset() + src.position(); + int sl = src.arrayOffset() + src.limit(); + + char[] da = dst.array(); + int dp = dst.arrayOffset() + dst.position(); + int dl = dst.arrayOffset() + dst.limit(); + int dlASCII = dp + Math.min(sl - sp, dl - dp); + + // ASCII only loop + while (dp < dlASCII && sa[sp] >= 0) + da[dp++] = (char) sa[sp++]; + while (sp < sl) { + int b1 = sa[sp]; + if (b1 >= 0) { + // 1 byte, 7 bits: 0xxxxxxx + if (dp >= dl) + return xflow(src, sp, sl, dst, dp, 1); + da[dp++] = (char) b1; + sp++; + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { + // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + if (sl - sp < 2 || dp >= dl) + return xflow(src, sp, sl, dst, dp, 2); + int b2 = sa[sp + 1]; + if (isNotContinuation(b2)) + return malformedForLength(src, sp, dst, dp, 1); + da[dp++] = (char) (((b1 << 6) ^ b2) + ^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0))); + sp += 2; + } else if ((b1 >> 4) == -2) { + // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx + int srcRemaining = sl - sp; + if (srcRemaining < 3 || dp >= dl) { + if (srcRemaining > 1 && isMalformed3_2(b1, sa[sp + 1])) + return malformedForLength(src, sp, dst, dp, 1); + return xflow(src, sp, sl, dst, dp, 3); + } + int b2 = sa[sp + 1]; + int b3 = sa[sp + 2]; + if (isMalformed3(b1, b2, b3)) + return malformed(src, sp, dst, dp, 3); + da[dp++] = (char) + ((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + sp += 3; + } else { + return malformed(src, sp, dst, dp, 1); + } + } + return xflow(src, sp, sl, dst, dp, 0); + } + + private CoderResult decodeBufferLoop(ByteBuffer src, + CharBuffer dst) + { + int mark = src.position(); + int limit = src.limit(); + while (mark < limit) { + int b1 = src.get(); + if (b1 >= 0) { + // 1 byte, 7 bits: 0xxxxxxx + if (dst.remaining() < 1) + return xflow(src, mark, 1); // overflow + dst.put((char) b1); + mark++; + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { + // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + if (limit - mark < 2|| dst.remaining() < 1) + return xflow(src, mark, 2); + int b2 = src.get(); + if (isNotContinuation(b2)) + return malformedForLength(src, mark, 1); + dst.put((char) (((b1 << 6) ^ b2) + ^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0)))); + mark += 2; + } else if ((b1 >> 4) == -2) { + // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx + int srcRemaining = limit - mark; + if (srcRemaining < 3 || dst.remaining() < 1) { + if (srcRemaining > 1 && isMalformed3_2(b1, src.get())) + return malformedForLength(src, mark, 1); + return xflow(src, mark, 3); + } + int b2 = src.get(); + int b3 = src.get(); + if (isMalformed3(b1, b2, b3)) + return malformed(src, mark, 3); + dst.put((char) + ((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0))))); + mark += 3; + } else { + return malformed(src, mark, 1); + } + } + return xflow(src, mark, 0); + } + + protected CoderResult decodeLoop(ByteBuffer src, + CharBuffer dst) + { + if (src.hasArray() && dst.hasArray()) + return decodeArrayLoop(src, dst); + else + return decodeBufferLoop(src, dst); + } + + private static ByteBuffer getByteBuffer(ByteBuffer bb, byte[] ba, int sp) + { + if (bb == null) + bb = ByteBuffer.wrap(ba); + bb.position(sp); + return bb; + } + + // returns -1 if there is/are malformed byte(s) and the + // "action" for malformed input is not REPLACE. + public int decode(byte[] sa, int sp, int len, char[] da) { + final int sl = sp + len; + int dp = 0; + int dlASCII = Math.min(len, da.length); + ByteBuffer bb = null; // only necessary if malformed + + // ASCII only optimized loop + while (dp < dlASCII && sa[sp] >= 0) + da[dp++] = (char) sa[sp++]; + + while (sp < sl) { + int b1 = sa[sp++]; + if (b1 >= 0) { + // 1 byte, 7 bits: 0xxxxxxx + da[dp++] = (char) b1; + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { + // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + if (sp < sl) { + int b2 = sa[sp++]; + if (isNotContinuation(b2)) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + sp--; // malformedN(bb, 2) always returns 1 + } else { + da[dp++] = (char) (((b1 << 6) ^ b2)^ + (((byte) 0xC0 << 6) ^ + ((byte) 0x80 << 0))); + } + continue; + } + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + return dp; + } else if ((b1 >> 4) == -2) { + // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx + if (sp + 1 < sl) { + int b2 = sa[sp++]; + int b3 = sa[sp++]; + if (isMalformed3(b1, b2, b3)) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + sp -=3; + bb = getByteBuffer(bb, sa, sp); + sp += malformedN(bb, 3).length(); + } else { + da[dp++] = (char)((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + } + continue; + } + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + if (sp < sl && isMalformed3_2(b1, sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + + } + da[dp++] = replacement().charAt(0); + return dp; + } else { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + } + } + return dp; + } + } + + private static class Encoder extends CharsetEncoder + implements ArrayEncoder { + + private Encoder(Charset cs) { + super(cs, 1.1f, 3.0f); + } + + public boolean canEncode(char c) { + return !Character.isSurrogate(c); + } + + public boolean isLegalReplacement(byte[] repl) { + return ((repl.length == 1 && repl[0] >= 0) || + super.isLegalReplacement(repl)); + } + + private static CoderResult overflow(CharBuffer src, int sp, + ByteBuffer dst, int dp) { + updatePositions(src, sp, dst, dp); + return CoderResult.OVERFLOW; + } + + private static CoderResult overflow(CharBuffer src, int mark) { + src.position(mark); + return CoderResult.OVERFLOW; + } + + private static void to3Bytes(byte[] da, int dp, char c) { + da[dp] = (byte)(0xe0 | ((c >> 12))); + da[dp + 1] = (byte)(0x80 | ((c >> 6) & 0x3f)); + da[dp + 2] = (byte)(0x80 | (c & 0x3f)); + } + + private static void to3Bytes(ByteBuffer dst, char c) { + dst.put((byte)(0xe0 | ((c >> 12)))); + dst.put((byte)(0x80 | ((c >> 6) & 0x3f))); + dst.put((byte)(0x80 | (c & 0x3f))); + } + + private Surrogate.Parser sgp; + private char[] c2; + private CoderResult encodeArrayLoop(CharBuffer src, + ByteBuffer dst) + { + char[] sa = src.array(); + int sp = src.arrayOffset() + src.position(); + int sl = src.arrayOffset() + src.limit(); + + byte[] da = dst.array(); + int dp = dst.arrayOffset() + dst.position(); + int dl = dst.arrayOffset() + dst.limit(); + int dlASCII = dp + Math.min(sl - sp, dl - dp); + + // ASCII only loop + while (dp < dlASCII && sa[sp] < '\u0080') + da[dp++] = (byte) sa[sp++]; + while (sp < sl) { + char c = sa[sp]; + if (c < 0x80) { + // Have at most seven bits + if (dp >= dl) + return overflow(src, sp, dst, dp); + da[dp++] = (byte)c; + } else if (c < 0x800) { + // 2 bytes, 11 bits + if (dl - dp < 2) + return overflow(src, sp, dst, dp); + da[dp++] = (byte)(0xc0 | (c >> 6)); + da[dp++] = (byte)(0x80 | (c & 0x3f)); + } else if (Character.isSurrogate(c)) { + // Have a surrogate pair + if (sgp == null) + sgp = new Surrogate.Parser(); + int uc = sgp.parse(c, sa, sp, sl); + if (uc < 0) { + updatePositions(src, sp, dst, dp); + return sgp.error(); + } + if (dl - dp < 6) + return overflow(src, sp, dst, dp); + to3Bytes(da, dp, Character.highSurrogate(uc)); + dp += 3; + to3Bytes(da, dp, Character.lowSurrogate(uc)); + dp += 3; + sp++; // 2 chars + } else { + // 3 bytes, 16 bits + if (dl - dp < 3) + return overflow(src, sp, dst, dp); + to3Bytes(da, dp, c); + dp += 3; + } + sp++; + } + updatePositions(src, sp, dst, dp); + return CoderResult.UNDERFLOW; + } + + private CoderResult encodeBufferLoop(CharBuffer src, + ByteBuffer dst) + { + int mark = src.position(); + while (src.hasRemaining()) { + char c = src.get(); + if (c < 0x80) { + // Have at most seven bits + if (!dst.hasRemaining()) + return overflow(src, mark); + dst.put((byte)c); + } else if (c < 0x800) { + // 2 bytes, 11 bits + if (dst.remaining() < 2) + return overflow(src, mark); + dst.put((byte)(0xc0 | (c >> 6))); + dst.put((byte)(0x80 | (c & 0x3f))); + } else if (Character.isSurrogate(c)) { + // Have a surrogate pair + if (sgp == null) + sgp = new Surrogate.Parser(); + int uc = sgp.parse(c, src); + if (uc < 0) { + src.position(mark); + return sgp.error(); + } + if (dst.remaining() < 6) + return overflow(src, mark); + to3Bytes(dst, Character.highSurrogate(uc)); + to3Bytes(dst, Character.lowSurrogate(uc)); + mark++; // 2 chars + } else { + // 3 bytes, 16 bits + if (dst.remaining() < 3) + return overflow(src, mark); + to3Bytes(dst, c); + } + mark++; + } + src.position(mark); + return CoderResult.UNDERFLOW; + } + + protected final CoderResult encodeLoop(CharBuffer src, + ByteBuffer dst) + { + if (src.hasArray() && dst.hasArray()) + return encodeArrayLoop(src, dst); + else + return encodeBufferLoop(src, dst); + } + + // returns -1 if there is malformed char(s) and the + // "action" for malformed input is not REPLACE. + public int encode(char[] sa, int sp, int len, byte[] da) { + int sl = sp + len; + int dp = 0; + int dlASCII = dp + Math.min(len, da.length); + + // ASCII only optimized loop + while (dp < dlASCII && sa[sp] < '\u0080') + da[dp++] = (byte) sa[sp++]; + + while (sp < sl) { + char c = sa[sp++]; + if (c < 0x80) { + // Have at most seven bits + da[dp++] = (byte)c; + } else if (c < 0x800) { + // 2 bytes, 11 bits + da[dp++] = (byte)(0xc0 | (c >> 6)); + da[dp++] = (byte)(0x80 | (c & 0x3f)); + } else if (Character.isSurrogate(c)) { + if (sgp == null) + sgp = new Surrogate.Parser(); + int uc = sgp.parse(c, sa, sp - 1, sl); + if (uc < 0) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement()[0]; + } else { + to3Bytes(da, dp, Character.highSurrogate(uc)); + dp += 3; + to3Bytes(da, dp, Character.lowSurrogate(uc)); + dp += 3; + sp++; // 2 chars + } + } else { + // 3 bytes, 16 bits + to3Bytes(da, dp, c); + dp += 3; + } + } + return dp; + } + } +} diff --git a/jdk/src/share/classes/sun/nio/cs/UTF_8.java b/jdk/src/share/classes/sun/nio/cs/UTF_8.java index 56d6bcc7b6d..1f7edaad2d8 100644 --- a/jdk/src/share/classes/sun/nio/cs/UTF_8.java +++ b/jdk/src/share/classes/sun/nio/cs/UTF_8.java @@ -72,8 +72,8 @@ class UTF_8 extends Unicode return new Encoder(this); } - static final void updatePositions(Buffer src, int sp, - Buffer dst, int dp) { + private static final void updatePositions(Buffer src, int sp, + Buffer dst, int dp) { src.position(sp - src.arrayOffset()); dst.position(dp - dst.arrayOffset()); } @@ -88,11 +88,6 @@ class UTF_8 extends Unicode return (b & 0xc0) != 0x80; } - // [C2..DF] [80..BF] - private static boolean isMalformed2(int b1, int b2) { - return (b1 & 0x1e) == 0x0 || (b2 & 0xc0) != 0x80; - } - // [E0] [A0..BF] [80..BF] // [E1..EF] [80..BF] [80..BF] private static boolean isMalformed3(int b1, int b2, int b3) { @@ -100,6 +95,12 @@ class UTF_8 extends Unicode (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80; } + // only used when there is only one byte left in src buffer + private static boolean isMalformed3_2(int b1, int b2) { + return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || + (b2 & 0xc0) != 0x80; + } + // [F0] [90..BF] [80..BF] [80..BF] // [F1..F3] [80..BF] [80..BF] [80..BF] // [F4] [80..8F] [80..BF] [80..BF] @@ -110,6 +111,16 @@ class UTF_8 extends Unicode (b4 & 0xc0) != 0x80; } + // only used when there is less than 4 bytes left in src buffer + private static boolean isMalformed4_2(int b1, int b2) { + return (b1 == 0xf0 && b2 == 0x90) || + (b2 & 0xc0) != 0x80; + } + + private static boolean isMalformed4_3(int b3) { + return (b3 & 0xc0) != 0x80; + } + private static CoderResult lookupN(ByteBuffer src, int n) { for (int i = 1; i < n; i++) { @@ -122,28 +133,14 @@ class UTF_8 extends Unicode private static CoderResult malformedN(ByteBuffer src, int nb) { switch (nb) { case 1: - int b1 = src.get(); - if ((b1 >> 2) == -2) { - // 5 bytes 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - if (src.remaining() < 4) - return CoderResult.UNDERFLOW; - return lookupN(src, 5); - } - if ((b1 >> 1) == -2) { - // 6 bytes 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - if (src.remaining() < 5) - return CoderResult.UNDERFLOW; - return lookupN(src, 6); - } - return CoderResult.malformedForLength(1); case 2: // always 1 return CoderResult.malformedForLength(1); case 3: - b1 = src.get(); + int b1 = src.get(); int b2 = src.get(); // no need to lookup b3 return CoderResult.malformedForLength( ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) || - isNotContinuation(b2))?1:2); + isNotContinuation(b2)) ? 1 : 2); case 4: // we don't care the speed here b1 = src.get() & 0xff; b2 = src.get() & 0xff; @@ -171,6 +168,7 @@ class UTF_8 extends Unicode return cr; } + private static CoderResult malformed(ByteBuffer src, int mark, int nb) { @@ -180,18 +178,36 @@ class UTF_8 extends Unicode return cr; } + private static CoderResult malformedForLength(ByteBuffer src, + int sp, + CharBuffer dst, + int dp, + int malformedNB) + { + updatePositions(src, sp, dst, dp); + return CoderResult.malformedForLength(malformedNB); + } + + private static CoderResult malformedForLength(ByteBuffer src, + int mark, + int malformedNB) + { + src.position(mark); + return CoderResult.malformedForLength(malformedNB); + } + + private static CoderResult xflow(Buffer src, int sp, int sl, Buffer dst, int dp, int nb) { updatePositions(src, sp, dst, dp); return (nb == 0 || sl - sp < nb) - ?CoderResult.UNDERFLOW:CoderResult.OVERFLOW; + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; } private static CoderResult xflow(Buffer src, int mark, int nb) { - CoderResult cr = (nb == 0 || src.remaining() < (nb - 1)) - ?CoderResult.UNDERFLOW:CoderResult.OVERFLOW; src.position(mark); - return cr; + return (nb == 0 || src.remaining() < nb) + ? CoderResult.UNDERFLOW : CoderResult.OVERFLOW; } private CoderResult decodeArrayLoop(ByteBuffer src, @@ -210,7 +226,6 @@ class UTF_8 extends Unicode // ASCII only loop while (dp < dlASCII && sa[sp] >= 0) da[dp++] = (char) sa[sp++]; - while (sp < sl) { int b1 = sa[sp]; if (b1 >= 0) { @@ -219,13 +234,20 @@ class UTF_8 extends Unicode return xflow(src, sp, sl, dst, dp, 1); da[dp++] = (char) b1; sp++; - } else if ((b1 >> 5) == -2) { + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx + // [C2..DF] [80..BF] if (sl - sp < 2 || dp >= dl) return xflow(src, sp, sl, dst, dp, 2); int b2 = sa[sp + 1]; - if (isMalformed2(b1, b2)) - return malformed(src, sp, dst, dp, 2); + // Now we check the first byte of 2-byte sequence as + // if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) + // no longer need to check b1 against c1 & c0 for + // malformed as we did in previous version + // (b1 & 0x1e) == 0x0 || (b2 & 0xc0) != 0x80; + // only need to check the second byte b2. + if (isNotContinuation(b2)) + return malformedForLength(src, sp, dst, dp, 1); da[dp++] = (char) (((b1 << 6) ^ b2) ^ (((byte) 0xC0 << 6) ^ @@ -233,24 +255,37 @@ class UTF_8 extends Unicode sp += 2; } else if ((b1 >> 4) == -2) { // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx - if (sl - sp < 3 || dp >= dl) + int srcRemaining = sl - sp; + if (srcRemaining < 3 || dp >= dl) { + if (srcRemaining > 1 && isMalformed3_2(b1, sa[sp + 1])) + return malformedForLength(src, sp, dst, dp, 1); return xflow(src, sp, sl, dst, dp, 3); + } int b2 = sa[sp + 1]; int b3 = sa[sp + 2]; if (isMalformed3(b1, b2, b3)) return malformed(src, sp, dst, dp, 3); - da[dp++] = (char) + char c = (char) ((b1 << 12) ^ (b2 << 6) ^ (b3 ^ (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80 << 0)))); + if (Character.isSurrogate(c)) + return malformedForLength(src, sp, dst, dp, 3); + da[dp++] = c; sp += 3; } else if ((b1 >> 3) == -2) { // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - if (sl - sp < 4 || dl - dp < 2) + int srcRemaining = sl - sp; + if (srcRemaining < 4 || dl - dp < 2) { + if (srcRemaining > 1 && isMalformed4_2(b1, sa[sp + 1])) + return malformedForLength(src, sp, dst, dp, 1); + if (srcRemaining > 2 && isMalformed4_3(sa[sp + 2])) + return malformedForLength(src, sp, dst, dp, 2); return xflow(src, sp, sl, dst, dp, 4); + } int b2 = sa[sp + 1]; int b3 = sa[sp + 2]; int b4 = sa[sp + 3]; @@ -289,38 +324,51 @@ class UTF_8 extends Unicode return xflow(src, mark, 1); // overflow dst.put((char) b1); mark++; - } else if ((b1 >> 5) == -2) { + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx if (limit - mark < 2|| dst.remaining() < 1) return xflow(src, mark, 2); int b2 = src.get(); - if (isMalformed2(b1, b2)) - return malformed(src, mark, 2); - dst.put((char) (((b1 << 6) ^ b2) + if (isNotContinuation(b2)) + return malformedForLength(src, mark, 1); + dst.put((char) (((b1 << 6) ^ b2) ^ (((byte) 0xC0 << 6) ^ ((byte) 0x80 << 0)))); mark += 2; } else if ((b1 >> 4) == -2) { // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx - if (limit - mark < 3 || dst.remaining() < 1) + int srcRemaining = limit - mark; + if (srcRemaining < 3 || dst.remaining() < 1) { + if (srcRemaining > 1 && isMalformed3_2(b1, src.get())) + return malformedForLength(src, mark, 1); return xflow(src, mark, 3); + } int b2 = src.get(); int b3 = src.get(); if (isMalformed3(b1, b2, b3)) return malformed(src, mark, 3); - dst.put((char) - ((b1 << 12) ^ - (b2 << 6) ^ - (b3 ^ - (((byte) 0xE0 << 12) ^ - ((byte) 0x80 << 6) ^ - ((byte) 0x80 << 0))))); + char c = (char) + ((b1 << 12) ^ + (b2 << 6) ^ + (b3 ^ + (((byte) 0xE0 << 12) ^ + ((byte) 0x80 << 6) ^ + ((byte) 0x80 << 0)))); + if (Character.isSurrogate(c)) + return malformedForLength(src, mark, 3); + dst.put(c); mark += 3; } else if ((b1 >> 3) == -2) { // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - if (limit - mark < 4 || dst.remaining() < 2) + int srcRemaining = limit - mark; + if (srcRemaining < 4 || dst.remaining() < 2) { + if (srcRemaining > 1 && isMalformed4_2(b1, src.get())) + return malformedForLength(src, mark, 1); + if (srcRemaining > 2 && isMalformed4_3(src.get())) + return malformedForLength(src, mark, 2); return xflow(src, mark, 4); + } int b2 = src.get(); int b3 = src.get(); int b4 = src.get(); @@ -364,7 +412,7 @@ class UTF_8 extends Unicode return bb; } - // returns -1 if there is malformed byte(s) and the + // returns -1 if there is/are malformed byte(s) and the // "action" for malformed input is not REPLACE. public int decode(byte[] sa, int sp, int len, char[] da) { final int sl = sp + len; @@ -381,11 +429,11 @@ class UTF_8 extends Unicode if (b1 >= 0) { // 1 byte, 7 bits: 0xxxxxxx da[dp++] = (char) b1; - } else if ((b1 >> 5) == -2) { + } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx if (sp < sl) { int b2 = sa[sp++]; - if (isMalformed2(b1, b2)) { + if (isNotContinuation(b2)) { if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; da[dp++] = replacement().charAt(0); @@ -410,21 +458,33 @@ class UTF_8 extends Unicode if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; da[dp++] = replacement().charAt(0); - sp -=3; + sp -= 3; bb = getByteBuffer(bb, sa, sp); sp += malformedN(bb, 3).length(); } else { - da[dp++] = (char)((b1 << 12) ^ + char c = (char)((b1 << 12) ^ (b2 << 6) ^ (b3 ^ (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80 << 0)))); + if (Character.isSurrogate(c)) { + if (malformedInputAction() != CodingErrorAction.REPLACE) + return -1; + da[dp++] = replacement().charAt(0); + } else { + da[dp++] = c; + } } continue; } if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; + if (sp < sl && isMalformed3_2(b1, sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + + } da[dp++] = replacement().charAt(0); return dp; } else if ((b1 >> 3) == -2) { @@ -458,28 +518,29 @@ class UTF_8 extends Unicode } if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; + + if (sp < sl && isMalformed4_2(b1, sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + } + sp++; + if (sp < sl && isMalformed4_3(sa[sp])) { + da[dp++] = replacement().charAt(0); + continue; + } da[dp++] = replacement().charAt(0); return dp; } else { if (malformedInputAction() != CodingErrorAction.REPLACE) return -1; da[dp++] = replacement().charAt(0); - sp--; - bb = getByteBuffer(bb, sa, sp); - CoderResult cr = malformedN(bb, 1); - if (!cr.isError()) { - // leading byte for 5 or 6-byte, but don't have enough - // bytes in buffer to check. Consumed rest as malformed. - return dp; - } - sp += cr.length(); } } return dp; } } - private static class Encoder extends CharsetEncoder + private static final class Encoder extends CharsetEncoder implements ArrayEncoder { private Encoder(Charset cs) { diff --git a/jdk/src/share/classes/sun/nio/cs/standard-charsets b/jdk/src/share/classes/sun/nio/cs/standard-charsets index 06120fee8f3..245713500a6 100644 --- a/jdk/src/share/classes/sun/nio/cs/standard-charsets +++ b/jdk/src/share/classes/sun/nio/cs/standard-charsets @@ -63,6 +63,10 @@ charset UTF-8 UTF_8 alias UTF8 # JDK historical alias unicode-1-1-utf-8 +charset CESU-8 CESU_8 + alias CESU8 + alias csCESU-8 + charset UTF-16 UTF_16 alias UTF_16 # JDK historical alias utf16 diff --git a/jdk/src/share/classes/sun/print/PSPrinterJob.java b/jdk/src/share/classes/sun/print/PSPrinterJob.java index 722537ea571..d4a0ffacb20 100644 --- a/jdk/src/share/classes/sun/print/PSPrinterJob.java +++ b/jdk/src/share/classes/sun/print/PSPrinterJob.java @@ -68,14 +68,18 @@ import javax.print.attribute.standard.Sides; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.BufferedReader; import java.io.CharConversionException; import java.io.File; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.IOException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Enumeration; @@ -673,15 +677,38 @@ public class PSPrinterJob extends RasterPrinterJob { private class PrinterSpooler implements java.security.PrivilegedAction { PrinterException pex; + private void handleProcessFailure(final Process failedProcess, + final String[] execCmd, final int result) throws IOException { + try (StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw)) { + pw.append("error=").append(Integer.toString(result)); + pw.append(" running:"); + for (String arg: execCmd) { + pw.append(" '").append(arg).append("'"); + } + try (InputStream is = failedProcess.getErrorStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr)) { + while (br.ready()) { + pw.println(); + pw.append("\t\t").append(br.readLine()); + } + } finally { + pw.flush(); + throw new IOException(sw.toString()); + } + } + } + public Object run() { + if (spoolFile == null || !spoolFile.exists()) { + pex = new PrinterException("No spool file"); + return null; + } try { /** * Spool to the printer. */ - if (spoolFile == null || !spoolFile.exists()) { - pex = new PrinterException("No spool file"); - return null; - } String fileName = spoolFile.getAbsolutePath(); String execCmd[] = printExecCmd(mDestination, mOptions, mNoJobSheet, getJobNameInt(), @@ -689,12 +716,16 @@ public class PSPrinterJob extends RasterPrinterJob { Process process = Runtime.getRuntime().exec(execCmd); process.waitFor(); - spoolFile.delete(); - + final int result = process.exitValue(); + if (0 != result) { + handleProcessFailure(process, execCmd, result); + } } catch (IOException ex) { pex = new PrinterIOException(ex); } catch (InterruptedException ie) { pex = new PrinterException(ie.toString()); + } finally { + spoolFile.delete(); } return null; } diff --git a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java index 4878609c088..db18eb3364d 100644 --- a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java @@ -38,13 +38,23 @@ import java.rmi.server.ServerNotActiveException; import java.rmi.registry.Registry; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.CodeSource; +import java.security.Policy; import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.ProtectionDomain; import java.text.MessageFormat; +import sun.rmi.server.LoaderHandler; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; import sun.rmi.transport.LiveRef; import sun.rmi.transport.ObjectTable; import sun.rmi.transport.Target; +import sun.security.action.GetPropertyAction; /** * A "registry" exists on every node that allows RMI connections to @@ -325,6 +335,19 @@ public class RegistryImpl extends java.rmi.server.RemoteServer URL[] urls = sun.misc.URLClassPath.pathToURLs(envcp); ClassLoader cl = new URLClassLoader(urls); + String codebaseProperty = null; + String prop = java.security.AccessController.doPrivileged( + new GetPropertyAction("java.rmi.server.codebase")); + if (prop != null && prop.trim().length() > 0) { + codebaseProperty = prop; + } + URL[] codebaseURLs = null; + if (codebaseProperty != null) { + codebaseURLs = sun.misc.URLClassPath.pathToURLs(codebaseProperty); + } else { + codebaseURLs = new URL[0]; + } + /* * Fix bugid 4242317: Classes defined by this class loader should * be annotated with the value of the "java.rmi.server.codebase" @@ -334,11 +357,19 @@ public class RegistryImpl extends java.rmi.server.RemoteServer Thread.currentThread().setContextClassLoader(cl); - int regPort = Registry.REGISTRY_PORT; - if (args.length >= 1) { - regPort = Integer.parseInt(args[0]); + final int regPort = (args.length >= 1) ? Integer.parseInt(args[0]) + : Registry.REGISTRY_PORT; + try { + registry = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public RegistryImpl run() throws RemoteException { + return new RegistryImpl(regPort); + } + }, getAccessControlContext(codebaseURLs)); + } catch (PrivilegedActionException ex) { + throw (RemoteException) ex.getException(); } - registry = new RegistryImpl(regPort); + // prevent registry from exiting while (true) { try { @@ -358,4 +389,48 @@ public class RegistryImpl extends java.rmi.server.RemoteServer } System.exit(1); } + + /** + * Generates an AccessControlContext from several URLs. + * The approach used here is taken from the similar method + * getAccessControlContext() in the sun.applet.AppletPanel class. + */ + private static AccessControlContext getAccessControlContext(URL[] urls) { + // begin with permissions granted to all code in current policy + PermissionCollection perms = AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public PermissionCollection run() { + CodeSource codesource = new CodeSource(null, + (java.security.cert.Certificate[]) null); + Policy p = java.security.Policy.getPolicy(); + if (p != null) { + return p.getPermissions(codesource); + } else { + return new Permissions(); + } + } + }); + + /* + * Anyone can connect to the registry and the registry can connect + * to and possibly download stubs from anywhere. Downloaded stubs and + * related classes themselves are more tightly limited by RMI. + */ + perms.add(new SocketPermission("*", "connect,accept")); + + perms.add(new RuntimePermission("accessClassInPackage.sun.*")); + + // add permissions required to load from codebase URL path + LoaderHandler.addPermissionsForURLs(urls, perms, false); + + /* + * Create an AccessControlContext that consists of a single + * protection domain with only the permissions calculated above. + */ + ProtectionDomain pd = new ProtectionDomain( + new CodeSource((urls.length > 0 ? urls[0] : null), + (java.security.cert.Certificate[]) null), + perms); + return new AccessControlContext(new ProtectionDomain[] { pd }); + } } diff --git a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java index 541c7840e08..52d9ee55172 100644 --- a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java +++ b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java @@ -1031,9 +1031,9 @@ public final class LoaderHandler { * loader. A given permission is only added to the collection if * it is not already implied by the collection. */ - private static void addPermissionsForURLs(URL[] urls, - PermissionCollection perms, - boolean forLoader) + public static void addPermissionsForURLs(URL[] urls, + PermissionCollection perms, + boolean forLoader) { for (int i = 0; i < urls.length; i++) { URL url = urls[i]; diff --git a/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java b/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java index 9a0c1afb578..fe199a23137 100644 --- a/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java +++ b/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java @@ -390,6 +390,12 @@ public class UnicastServerRef extends UnicastRef ObjectInput in; try { in = call.getInputStream(); + try { + Class clazz = Class.forName("sun.rmi.transport.DGCImpl_Skel"); + if (clazz.isAssignableFrom(skel.getClass())) { + ((MarshalInputStream)in).useCodebaseOnly(); + } + } catch (ClassNotFoundException ignore) { } hash = in.readLong(); } catch (Exception readEx) { throw new UnmarshalException("error unmarshalling call header", diff --git a/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java b/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java index 34f3be6d6a5..6be00b8e2d1 100644 --- a/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java +++ b/jdk/src/share/classes/sun/security/ssl/AppOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,12 +69,38 @@ class AppOutputStream extends OutputStream { // check if the Socket is invalid (error or closed) c.checkWrite(); + /* + * By default, we counter chosen plaintext issues on CBC mode + * ciphersuites in SSLv3/TLS1.0 by sending one byte of application + * data in the first record of every payload, and the rest in + * subsequent record(s). Note that the issues have been solved in + * TLS 1.1 or later. + * + * It is not necessary to split the very first application record of + * a freshly negotiated TLS session, as there is no previous + * application data to guess. To improve compatibility, we will not + * split such records. + * + * This avoids issues in the outbound direction. For a full fix, + * the peer must have similar protections. + */ + boolean isFirstRecordOfThePayload = true; + // Always flush at the end of each application level record. // This lets application synchronize read and write streams // however they like; if we buffered here, they couldn't. try { do { - int howmuch = Math.min(len, r.availableDataBytes()); + int howmuch; + if (isFirstRecordOfThePayload && c.needToSplitPayload()) { + howmuch = Math.min(0x01, r.availableDataBytes()); + } else { + howmuch = Math.min(len, r.availableDataBytes()); + } + + if (isFirstRecordOfThePayload && howmuch != 0) { + isFirstRecordOfThePayload = false; + } // NOTE: *must* call c.writeRecord() even for howmuch == 0 if (howmuch > 0) { diff --git a/jdk/src/share/classes/sun/security/ssl/CipherBox.java b/jdk/src/share/classes/sun/security/ssl/CipherBox.java index 16f0643a7c5..4305b44635b 100644 --- a/jdk/src/share/classes/sun/security/ssl/CipherBox.java +++ b/jdk/src/share/classes/sun/security/ssl/CipherBox.java @@ -112,6 +112,11 @@ final class CipherBox { */ private SecureRandom random; + /** + * Is the cipher of CBC mode? + */ + private final boolean isCBCMode; + /** * Fixed masks of various block size, as the initial decryption IVs * for TLS 1.1 or later. @@ -128,6 +133,7 @@ final class CipherBox { private CipherBox() { this.protocolVersion = ProtocolVersion.DEFAULT; this.cipher = null; + this.isCBCMode = false; } /** @@ -148,6 +154,7 @@ final class CipherBox { random = JsseJce.getSecureRandom(); } this.random = random; + this.isCBCMode = bulkCipher.isCBCMode; /* * RFC 4346 recommends two algorithms used to generated the @@ -694,4 +701,12 @@ final class CipherBox { } } + /* + * Does the cipher use CBC mode? + * + * @return true if the cipher use CBC mode, false otherwise. + */ + boolean isCBCMode() { + return isCBCMode; + } } diff --git a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java index 116afa43d70..bbf66ade7e1 100644 --- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java +++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java @@ -420,10 +420,16 @@ final class CipherSuite implements Comparable { // exportable under 512/40 bit rules final boolean exportable; + // Is the cipher algorithm of Cipher Block Chaining (CBC) mode? + final boolean isCBCMode; + BulkCipher(String transformation, int keySize, int expandedKeySize, int ivSize, boolean allowed) { this.transformation = transformation; - this.algorithm = transformation.split("/")[0]; + String[] splits = transformation.split("/"); + this.algorithm = splits[0]; + this.isCBCMode = + splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]); this.description = this.algorithm + "/" + (keySize << 3); this.keySize = keySize; this.ivSize = ivSize; @@ -436,7 +442,10 @@ final class CipherSuite implements Comparable { BulkCipher(String transformation, int keySize, int ivSize, boolean allowed) { this.transformation = transformation; - this.algorithm = transformation.split("/")[0]; + String[] splits = transformation.split("/"); + this.algorithm = splits[0]; + this.isCBCMode = + splits.length <= 1 ? false : "CBC".equalsIgnoreCase(splits[1]); this.description = this.algorithm + "/" + (keySize << 3); this.keySize = keySize; this.ivSize = ivSize; diff --git a/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java b/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java index 60a428396e4..707fd04f8d3 100644 --- a/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java +++ b/jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,7 @@ import sun.misc.HexDumpEncoder; */ final class EngineOutputRecord extends OutputRecord { + private SSLEngineImpl engine; private EngineWriter writer; private boolean finishedMsg = false; @@ -62,6 +63,7 @@ final class EngineOutputRecord extends OutputRecord { */ EngineOutputRecord(byte type, SSLEngineImpl engine) { super(type, recordSize(type)); + this.engine = engine; writer = engine.writer; } @@ -227,11 +229,50 @@ final class EngineOutputRecord extends OutputRecord { * implementations are fragile and don't like to see empty * records, so this increases robustness. */ - int length = Math.min(ea.getAppRemaining(), maxDataSize); - if (length == 0) { + if (ea.getAppRemaining() == 0) { return; } + /* + * By default, we counter chosen plaintext issues on CBC mode + * ciphersuites in SSLv3/TLS1.0 by sending one byte of application + * data in the first record of every payload, and the rest in + * subsequent record(s). Note that the issues have been solved in + * TLS 1.1 or later. + * + * It is not necessary to split the very first application record of + * a freshly negotiated TLS session, as there is no previous + * application data to guess. To improve compatibility, we will not + * split such records. + * + * Because of the compatibility, we'd better produce no more than + * SSLSession.getPacketBufferSize() net data for each wrap. As we + * need a one-byte record at first, the 2nd record size should be + * equal to or less than Record.maxDataSizeMinusOneByteRecord. + * + * This avoids issues in the outbound direction. For a full fix, + * the peer must have similar protections. + */ + int length; + if (engine.needToSplitPayload(writeCipher, protocolVersion)) { + write(ea, writeMAC, writeCipher, 0x01); + ea.resetLim(); // reset application data buffer limit + length = Math.min(ea.getAppRemaining(), + maxDataSizeMinusOneByteRecord); + } else { + length = Math.min(ea.getAppRemaining(), maxDataSize); + } + + // Don't bother to really write empty records. + if (length > 0) { + write(ea, writeMAC, writeCipher, length); + } + + return; + } + + void write(EngineArgs ea, MAC writeMAC, CipherBox writeCipher, + int length) throws IOException { /* * Copy out existing buffer values. */ diff --git a/jdk/src/share/classes/sun/security/ssl/MAC.java b/jdk/src/share/classes/sun/security/ssl/MAC.java index 8002148a994..ae5c9d43bc0 100644 --- a/jdk/src/share/classes/sun/security/ssl/MAC.java +++ b/jdk/src/share/classes/sun/security/ssl/MAC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,10 +172,10 @@ final class MAC { * when there are only 2^8 sequence numbers left. */ return (block != null && mac != null && - block[0] == 0xFF && block[1] == 0xFF && - block[2] == 0xFF && block[3] == 0xFF && - block[4] == 0xFF && block[5] == 0xFF && - block[6] == 0xFF); + block[0] == (byte)0xFF && block[1] == (byte)0xFF && + block[2] == (byte)0xFF && block[3] == (byte)0xFF && + block[4] == (byte)0xFF && block[5] == (byte)0xFF && + block[6] == (byte)0xFF); } /* @@ -192,7 +192,7 @@ final class MAC { * only 2^48 sequence numbers left. */ return (block != null && mac != null && - block[0] == 0xFF && block[1] == 0xFF); + block[0] == (byte)0xFF && block[1] == (byte)0xFF); } // increment the sequence number in the block array diff --git a/jdk/src/share/classes/sun/security/ssl/Record.java b/jdk/src/share/classes/sun/security/ssl/Record.java index 1378e107afc..92c8a3ebbe0 100644 --- a/jdk/src/share/classes/sun/security/ssl/Record.java +++ b/jdk/src/share/classes/sun/security/ssl/Record.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,6 +67,23 @@ interface Record { + maxPadding // padding + trailerSize; // MAC + static final boolean enableCBCProtection = + Debug.getBooleanProperty("jsse.enableCBCProtection", true); + + /* + * For CBC protection in SSL3/TLS1, we break some plaintext into two + * packets. Max application data size for the second packet. + */ + static final int maxDataSizeMinusOneByteRecord = + maxDataSize // max data size + - ( // max one byte record size + headerSize // header + + maxIVLength // iv + + 1 // one byte data + + maxPadding // padding + + trailerSize // MAC + ); + /* * The maximum large record size. * diff --git a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java index 461cbaa2054..8616a71ef13 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java @@ -308,6 +308,11 @@ final public class SSLEngineImpl extends SSLEngine { private Object unwrapLock; Object writeLock; + /* + * Is it the first application record to write? + */ + private boolean isFirstAppOutputRecord = true; + /* * Class and subclass dynamic debugging support */ @@ -612,6 +617,9 @@ final public class SSLEngineImpl extends SSLEngine { // See comment above. oldCipher.dispose(); + + // reset the flag of the first application record + isFirstAppOutputRecord = true; } /* @@ -1286,9 +1294,35 @@ final public class SSLEngineImpl extends SSLEngine { } } + /* + * turn off the flag of the first application record if we really + * consumed at least byte. + */ + if (isFirstAppOutputRecord && ea.deltaApp() > 0) { + isFirstAppOutputRecord = false; + } + return hsStatus; } + /* + * Need to split the payload except the following cases: + * + * 1. protocol version is TLS 1.1 or later; + * 2. bulk cipher does not use CBC mode, including null bulk cipher suites. + * 3. the payload is the first application record of a freshly + * negotiated TLS session. + * 4. the CBC protection is disabled; + * + * More details, please refer to + * EngineOutputRecord.write(EngineArgs, MAC, CipherBox). + */ + boolean needToSplitPayload(CipherBox cipher, ProtocolVersion protocol) { + return (protocol.v <= ProtocolVersion.TLS10.v) && + cipher.isCBCMode() && !isFirstAppOutputRecord && + Record.enableCBCProtection; + } + /* * Non-application OutputRecords go through here. */ diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java index 5bfdd46c074..814f7d2933a 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -369,6 +369,11 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { /* Class and subclass dynamic debugging support */ private static final Debug debug = Debug.getInstance("ssl"); + /* + * Is it the first application record to write? + */ + private boolean isFirstAppOutputRecord = true; + // // CONSTRUCTORS AND INITIALIZATION CODE // @@ -802,8 +807,35 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { if (connectionState < cs_ERROR) { checkSequenceNumber(writeMAC, r.contentType()); } + + // turn off the flag of the first application record + if (isFirstAppOutputRecord && + r.contentType() == Record.ct_application_data) { + isFirstAppOutputRecord = false; + } } + /* + * Need to split the payload except the following cases: + * + * 1. protocol version is TLS 1.1 or later; + * 2. bulk cipher does not use CBC mode, including null bulk cipher suites. + * 3. the payload is the first application record of a freshly + * negotiated TLS session. + * 4. the CBC protection is disabled; + * + * More details, please refer to AppOutputStream.write(byte[], int, int). + */ + boolean needToSplitPayload() { + writeLock.lock(); + try { + return (protocolVersion.v <= ProtocolVersion.TLS10.v) && + writeCipher.isCBCMode() && !isFirstAppOutputRecord && + Record.enableCBCProtection; + } finally { + writeLock.unlock(); + } + } /* * Read an application data record. Alerts and handshake @@ -2030,6 +2062,9 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { // See comment above. oldCipher.dispose(); + + // reset the flag of the first application record + isFirstAppOutputRecord = true; } /* diff --git a/jdk/src/share/classes/sun/text/resources/CollationData_th.java b/jdk/src/share/classes/sun/text/resources/CollationData_th.java index 0adc262c4db..311a11f1a0b 100644 --- a/jdk/src/share/classes/sun/text/resources/CollationData_th.java +++ b/jdk/src/share/classes/sun/text/resources/CollationData_th.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,18 +103,13 @@ public class CollationData_th extends ListResourceBundle { // // Normal vowels // + + "< \u0E4D " // NIKHAHIT + "< \u0E30 " // SARA A + "< \u0E31 " // MAI HAN-AKAT + "< \u0E32 " // SARA AA - // Normalizer will decompose this character to \u0e4d\u0e32. This is - // a Bad Thing, because we want the separate characters to sort - // differently than this individual one. Since there's no public way to - // set the decomposition to be used when creating a collator, there's - // no way around this right now. - // It's best to go ahead and leave the character in, because it occurs - // this way a lot more often than it occurs as separate characters. - + "< \u0E33 " // SARA AM + // Normalizer will decompose this character to \u0e4d\u0e32. + + "< \u0E33 = \u0E4D\u0E32 " // SARA AM + "< \u0E34 " // SARA I @@ -133,62 +128,58 @@ public class CollationData_th extends ListResourceBundle { + "< \u0E43 " // SARA AI MAIMUAN + "< \u0E44 " // SARA AI MAIMALAI - // - // Digits - // - + "< \u0E50 " // DIGIT ZERO - + "< \u0E51 " // DIGIT ONE - + "< \u0E52 " // DIGIT TWO - + "< \u0E53 " // DIGIT THREE - + "< \u0E54 " // DIGIT FOUR - + "< \u0E55 " // DIGIT FIVE - + "< \u0E56 " // DIGIT SIX - + "< \u0E57 " // DIGIT SEVEN - + "< \u0E58 " // DIGIT EIGHT - + "< \u0E59 " // DIGIT NINE - // Sorta tonal marks, but maybe not really - + "< \u0E4D " // NIKHAHIT + //according to CLDR, it's after 0e44 + + "< \u0E3A " // PHINTHU - // - // Thai symbols are supposed to sort "after white space". - // I'm treating this as making them sort just after the normal Latin-1 - // symbols, which are in turn after the white space. - // - + "&'\u007d'" // right-brace - + "< \u0E2F " // PAIYANNOI (ellipsis, abbreviation) - + "< \u0E46 " // MAIYAMOK - + "< \u0E4F " // FONGMAN - + "< \u0E5A " // ANGKHANKHU - + "< \u0E5B " // KHOMUT - + "< \u0E3F " // CURRENCY SYMBOL BAHT - // These symbols are supposed to be "after all characters" - + "< \u0E4E " // YAMAKKAN - // This rare symbol also comes after all characters. But when it is - // used in combination with RU and LU, the combination is treated as - // a separate letter, ala "CH" sorting after "C" in traditional Spanish. + // This rare symbol comes after all characters. + "< \u0E45 " // LAKKHANGYAO - + "& \u0E24 < \u0E24\u0E45 " - + "& \u0E26 < \u0E26\u0E45 " + + "& \u0E32 , \0E45 " // According to CLDR, 0E45 is after 0E32 in tertiary level - // Tonal marks are primary ignorables but are treated as secondary - // differences + + + + // Below are thai puntuation marks and Tonal(Accent) marks. According to CLDR 1.9 and + // ISO/IEC 14651, Annex C, C.2.1 Thai ordering principles, 0E2F to 0E5B are punctuaion marks that need to be ignored + // in the first three leveles. 0E4E to 0E4B are tonal marks to be compared in secondary level. + // In real implmentation, set puncutation marks in tertiary as there is no fourth level in Java. + // Set all these special marks after \u0301, the accute accent. + "& \u0301 " // acute accent + + //puncutation marks + + ", \u0E2F " // PAIYANNOI (ellipsis, abbreviation) + + ", \u0E46 " // MAIYAMOK + + ", \u0E4F " // FONGMAN + + ", \u0E5A " // ANGKHANKHU + + ", \u0E5B " // KHOMUT + + //tonal marks + + "; \u0E4E " // YAMAKKAN + + "; \u0E4C " // THANTHAKHAT + "; \u0E47 " // MAITAIKHU + "; \u0E48 " // MAI EK + "; \u0E49 " // MAI THO + "; \u0E4A " // MAI TRI + "; \u0E4B " // MAI CHATTAWA - + "; \u0E4C " // THANTHAKHAT + + // + // Digits are equal to their corresponding Arabic digits in the first level + // + + "& 0 = \u0E50 " // DIGIT ZERO + + "& 1 = \u0E51 " // DIGIT ONE + + "& 2 = \u0E52 " // DIGIT TWO + + "& 3 = \u0E53 " // DIGIT THREE + + "& 4 = \u0E54 " // DIGIT FOUR + + "& 5 = \u0E55 " // DIGIT FIVE + + "& 6 = \u0E56 " // DIGIT SIX + + "& 7 = \u0E57 " // DIGIT SEVEN + + "& 8 = \u0E58 " // DIGIT EIGHT + + "& 9 = \u0E59 " // DIGIT NINE - // These are supposed to be ignored, so I'm treating them as controls - + "& \u0001 " - + "= \u0E3A " // PHINTHU - + "= '.' " // period - } + } }; } } diff --git a/jdk/src/share/classes/sun/util/resources/CalendarData_lv.properties b/jdk/src/share/classes/sun/util/resources/CalendarData_lv.properties index 36167c9c604..126532a799c 100644 --- a/jdk/src/share/classes/sun/util/resources/CalendarData_lv.properties +++ b/jdk/src/share/classes/sun/util/resources/CalendarData_lv.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,21 +23,45 @@ # questions. # -# (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved -# (C) Copyright IBM Corp. 1996 - 1999 - All Rights Reserved # -# The original version of this source code and documentation -# is copyrighted and owned by Taligent, Inc., a wholly-owned -# subsidiary of IBM. These materials are provided under terms -# of a License Agreement between Taligent and Sun. This technology -# is protected by multiple US and International patents. +# COPYRIGHT AND PERMISSION NOTICE # -# This notice and attribution to Taligent may not be removed. -# Taligent is a registered trademark of Taligent, Inc. +# Copyright (C) 1991-2011 Unicode, Inc. All rights reserved. +# Distributed under the Terms of Use in http://www.unicode.org/copyright.html. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of the Unicode data files and any associated documentation (the +# "Data Files") or Unicode software and any associated documentation +# (the "Software") to deal in the Data Files or Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, and/or sell copies of the Data +# Files or Software, and to permit persons to whom the Data Files or +# Software are furnished to do so, provided that (a) the above copyright +# notice(s) and this permission notice appear with all copies of the +# Data Files or Software, (b) both the above copyright notice(s) and +# this permission notice appear in associated documentation, and (c) +# there is clear notice in each modified Data File or in the Software as +# well as in the documentation associated with the Data File(s) or +# Software that the data or software has been modified. +# +# THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +# ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR +# ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR +# SOFTWARE. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in these Data Files or Software without prior +# written authorization of the copyright holder. - -# This bundle is empty because the data of the base bundle -# is adequate for this locale. -# The bundle is necessary to prevent the resource -# bundle lookup from falling back to the default -# locale. +# +# Generated automatically from the Common Locale Data Repository. DO NOT EDIT! +# +firstDayOfWeek=2 +minimalDaysInFirstWeek=4 diff --git a/jdk/src/share/classes/sun/util/xml/XMLUtils.java b/jdk/src/share/classes/sun/util/xml/XMLUtils.java index ab7ca851396..07677334db8 100644 --- a/jdk/src/share/classes/sun/util/xml/XMLUtils.java +++ b/jdk/src/share/classes/sun/util/xml/XMLUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ public class XMLUtils { } catch (SAXException saxe) { throw new InvalidPropertiesFormatException(saxe); } - Element propertiesElement = (Element)doc.getChildNodes().item(1); + Element propertiesElement = doc.getDocumentElement(); String xmlVersion = propertiesElement.getAttribute("version"); if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) throw new InvalidPropertiesFormatException( diff --git a/jdk/src/share/javavm/export/jvm.h b/jdk/src/share/javavm/export/jvm.h index d1dfefca47f..8d833ebeeac 100644 --- a/jdk/src/share/javavm/export/jvm.h +++ b/jdk/src/share/javavm/export/jvm.h @@ -1424,7 +1424,8 @@ typedef struct { */ unsigned int thread_park_blocker : 1; unsigned int post_vm_init_hook_enabled : 1; - unsigned int : 30; + unsigned int pending_list_uses_discovered_field : 1; + unsigned int : 29; unsigned int : 32; unsigned int : 32; } jdk_version_info; diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp index 17c48a4ceac..cee146d4db4 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp @@ -1112,11 +1112,14 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) { uint size3 = suffix * 3; if (suffix == 0) continue; // done with empty string chars.malloc(size3); + CHECK; byte* chp = chars.ptr; band saved_band = cp_Utf8_big_chars; cp_Utf8_big_chars.readData(suffix); + CHECK; for (int j = 0; j < suffix; j++) { unsigned short ch = cp_Utf8_big_chars.getInt(); + CHECK; chp = store_Utf8_char(chp, ch); } chars.realloc(chp - chars.ptr); @@ -1134,10 +1137,12 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) { CHECK; int prevlen = 0; // previous string length (in chars) tmallocs.add(bigbuf.ptr); // free after this block + CHECK; cp_Utf8_prefix.rewind(); for (i = 0; i < len; i++) { bytes& chars = allsuffixes[i]; int prefix = (i < PREFIX_SKIP_2)? 0: cp_Utf8_prefix.getInt(); + CHECK; int suffix = (int)chars.len; byte* fillp; // by induction, the buffer is already filled with the prefix diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp index 0f770d8064a..e5197e1a3f1 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ void* must_malloc(size_t size) { if (msize >= 0 && msize < sizeof(int)) msize = sizeof(int); // see 0xbaadf00d below #endif - void* ptr = (msize > PSIZE_MAX) ? null : malloc(msize); + void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : malloc(msize); if (ptr != null) { memset(ptr, 0, size); } else { diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/utils.h b/jdk/src/share/native/com/sun/java/util/jar/pack/utils.h index d24e5b50ea8..89619316a0e 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/utils.h +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ void mtrace(char c, void* ptr, size_t size); #endif // overflow management -#define OVERFLOW ((size_t)-1) +#define OVERFLOW ((uint)-1) #define PSIZE_MAX (OVERFLOW/2) /* normal size limit */ inline size_t scale_size(size_t size, size_t scale) { diff --git a/jdk/src/share/native/common/jdk_util.c b/jdk/src/share/native/common/jdk_util.c index e737982893e..8fe32bfcfaf 100644 --- a/jdk/src/share/native/common/jdk_util.c +++ b/jdk/src/share/native/common/jdk_util.c @@ -101,5 +101,5 @@ JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size) { // Advertise presence of sun.misc.PostVMInitHook: // future optimization: detect if this is enabled. info->post_vm_init_hook_enabled = 1; - + info->pending_list_uses_discovered_field = 1; } diff --git a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c index a5117747476..23bba354756 100644 --- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c +++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -284,7 +284,7 @@ Java_sun_java2d_loops_TransformHelper_Transform TransformHelperFunc *pHelperFunc; TransformInterpFunc *pInterpFunc; jdouble xorig, yorig; - jint numedges; + jlong numedges; jint *pEdges; jint edgebuf[2 + MAXEDGES * 2]; union { @@ -379,19 +379,44 @@ Java_sun_java2d_loops_TransformHelper_Transform } Region_IntersectBounds(&clipInfo, &dstInfo.bounds); - numedges = (dstInfo.bounds.y2 - dstInfo.bounds.y1); - if (numedges > MAXEDGES) { - pEdges = malloc((2 + 2 * numedges) * sizeof (*pEdges)); - if (pEdges == NULL) { - SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); - SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); - /* edgeArray should already contain zeros for min/maxy */ - return; - } + numedges = (((jlong) dstInfo.bounds.y2) - ((jlong) dstInfo.bounds.y1)); + if (numedges <= 0) { + pEdges = NULL; + } else if (!JNU_IsNull(env, edgeArray)) { + /* + * Ideally Java should allocate an array large enough, but if + * we ever have a miscommunication about the number of edge + * lines, or if the Java array calculation should overflow to + * a positive number and succeed in allocating an array that + * is too small, we need to verify that it can still hold the + * number of integers that we plan to store to be safe. + */ + jsize edgesize = (*env)->GetArrayLength(env, edgeArray); + /* (edgesize/2 - 1) should avoid any overflow or underflow. */ + pEdges = (((edgesize / 2) - 1) >= numedges) + ? (*env)->GetPrimitiveArrayCritical(env, edgeArray, NULL) + : NULL; + } else if (numedges > MAXEDGES) { + /* numedges variable (jlong) can be at most ((1<<32)-1) */ + /* memsize can overflow a jint, but not a jlong */ + jlong memsize = ((numedges * 2) + 2) * sizeof(*pEdges); + pEdges = (memsize == ((size_t) memsize)) + ? malloc((size_t) memsize) + : NULL; } else { pEdges = edgebuf; } + if (pEdges == NULL) { + if (numedges > 0) { + JNU_ThrowInternalError(env, "Unable to allocate edge list"); + } + SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); + SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); + /* edgeArray should already contain zeros for min/maxy */ + return; + } + Transform_GetInfo(env, itxform, &itxInfo); if (!Region_IsEmpty(&clipInfo)) { @@ -500,14 +525,14 @@ Java_sun_java2d_loops_TransformHelper_Transform } else { pEdges[0] = pEdges[1] = 0; } - SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); - SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); + if (!JNU_IsNull(env, edgeArray)) { - (*env)->SetIntArrayRegion(env, edgeArray, 0, 2+numedges*2, pEdges); - } - if (pEdges != edgebuf) { + (*env)->ReleasePrimitiveArrayCritical(env, edgeArray, pEdges, 0); + } else if (pEdges != edgebuf) { free(pEdges); } + SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); + SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); } static void diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintJob.java b/jdk/src/solaris/classes/sun/print/UnixPrintJob.java index 912442a6540..206650de40e 100644 --- a/jdk/src/solaris/classes/sun/print/UnixPrintJob.java +++ b/jdk/src/solaris/classes/sun/print/UnixPrintJob.java @@ -38,7 +38,9 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.IOException; +import java.io.PrintWriter; import java.io.Reader; +import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.Vector; @@ -955,23 +957,49 @@ public class UnixPrintJob implements CancelablePrintJob { private class PrinterSpooler implements java.security.PrivilegedAction { PrintException pex; + private void handleProcessFailure(final Process failedProcess, + final String[] execCmd, final int result) throws IOException { + try (StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw)) { + pw.append("error=").append(Integer.toString(result)); + pw.append(" running:"); + for (String arg: execCmd) { + pw.append(" '").append(arg).append("'"); + } + try (InputStream is = failedProcess.getErrorStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr)) { + while (br.ready()) { + pw.println(); + pw.append("\t\t").append(br.readLine()); + } + } finally { + pw.flush(); + throw new IOException(sw.toString()); + } + } + } + public Object run() { + if (spoolFile == null || !spoolFile.exists()) { + pex = new PrintException("No spool file"); + notifyEvent(PrintJobEvent.JOB_FAILED); + return null; + } try { /** * Spool to the printer. */ - if (spoolFile == null || !spoolFile.exists()) { - pex = new PrintException("No spool file"); - notifyEvent(PrintJobEvent.JOB_FAILED); - return null; - } String fileName = spoolFile.getAbsolutePath(); String execCmd[] = printExecCmd(mDestination, mOptions, mNoJobSheet, jobName, copies, fileName); Process process = Runtime.getRuntime().exec(execCmd); process.waitFor(); - spoolFile.delete(); + final int result = process.exitValue(); + if (0 != result) { + handleProcessFailure(process, execCmd, result); + } notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE); } catch (IOException ex) { notifyEvent(PrintJobEvent.JOB_FAILED); @@ -981,6 +1009,7 @@ public class UnixPrintJob implements CancelablePrintJob { notifyEvent(PrintJobEvent.JOB_FAILED); pex = new PrintException(ie); } finally { + spoolFile.delete(); notifyEvent(PrintJobEvent.NO_MORE_EVENTS); } return null; diff --git a/jdk/src/windows/classes/java/lang/ProcessImpl.java b/jdk/src/windows/classes/java/lang/ProcessImpl.java index 05891161a42..88486e5f472 100644 --- a/jdk/src/windows/classes/java/lang/ProcessImpl.java +++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java @@ -60,10 +60,11 @@ final class ProcessImpl extends Process { throws IOException { if (append) { + String path = f.getPath(); SecurityManager sm = System.getSecurityManager(); if (sm != null) - sm.checkWrite(f.getPath()); - long handle = openForAtomicAppend(f.getPath()); + sm.checkWrite(path); + long handle = openForAtomicAppend(path); final FileDescriptor fd = new FileDescriptor(); fdAccess.setHandle(fd, handle); return AccessController.doPrivileged( diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java index 9a461f92c82..02309ff01b2 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java @@ -124,26 +124,27 @@ class WindowsDirectoryStream private boolean atEof; private String first; private Path nextEntry; + private String prefix; WindowsDirectoryIterator(String first) { atEof = false; this.first = first; + if (dir.needsSlashWhenResolving()) { + prefix = dir.toString() + "\\"; + } else { + prefix = dir.toString(); + } + } + + // links to self and parent directories are ignored + private boolean isSelfOrParent(String name) { + return name.equals(".") || name.equals(".."); } // applies filter and also ignores "." and ".." private Path acceptEntry(String s, BasicFileAttributes attrs) { - if (s.equals(".") || s.equals("..")) - return null; - if (dir.needsSlashWhenResolving()) { - StringBuilder sb = new StringBuilder(dir.toString()); - sb.append('\\'); - sb.append(s); - s = sb.toString(); - } else { - s = dir + s; - } Path entry = WindowsPath - .createFromNormalizedPath(dir.getFileSystem(), s, attrs); + .createFromNormalizedPath(dir.getFileSystem(), prefix + s, attrs); try { if (filter.accept(entry)) return entry; @@ -157,7 +158,7 @@ class WindowsDirectoryStream private Path readNextEntry() { // handle first element returned by search if (first != null) { - nextEntry = acceptEntry(first, null); + nextEntry = isSelfOrParent(first) ? null : acceptEntry(first, null); first = null; if (nextEntry != null) return nextEntry; @@ -184,6 +185,10 @@ class WindowsDirectoryStream return null; } + // ignore link to self and parent directories + if (isSelfOrParent(name)) + continue; + // grab the attributes from the WIN32_FIND_DATA structure // (needs to be done while holding closeLock because close // will release the buffer) diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java index f1158e5f7de..c45858b4ae9 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPathParser.java @@ -120,12 +120,18 @@ class WindowsPathParser { off = next; } else { if (isLetter(c0) && c1 == ':') { - root = input.substring(0, 2); - if (len > 2 && isSlash(input.charAt(2))) { + char c2; + if (len > 2 && isSlash(c2 = input.charAt(2))) { + // avoid concatenation when root is "D:\" + if (c2 == '\\') { + root = input.substring(0, 3); + } else { + root = input.substring(0, 2) + '\\'; + } off = 3; - root += "\\"; type = WindowsPathType.ABSOLUTE; } else { + root = input.substring(0, 2); off = 2; type = WindowsPathType.DRIVE_RELATIVE; } diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index c742aca9000..83f6f0b9b1c 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -355,7 +355,7 @@ void AwtWindow::RepositionSecurityWarning(JNIEnv *env) RECT rect; CalculateWarningWindowBounds(env, &rect); - ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(), + ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | @@ -835,7 +835,7 @@ void AwtWindow::StartSecurityAnimation(AnimationKind kind) if (securityAnimationKind == akShow) { ::SetWindowPos(warningWindow, - IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(), + IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 9f91b1879b2..5b483f97cb4 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -490,9 +490,6 @@ sun/security/pkcs11/ec/TestECDSA.java solaris-i586 #sun/security/pkcs11/ec/TestKeyFactory.java solaris-i586 sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-i586 -# Directly references PKCS11 class -sun/security/pkcs11/Provider/Absolute.java windows-x64 - # Fails on Fedora 9/Ubuntu 10.04 64bit, PKCS11Exception: CKR_DEVICE_ERROR sun/security/pkcs11/KeyAgreement/TestDH.java generic-all diff --git a/jdk/test/java/lang/ref/ReferenceEnqueue.java b/jdk/test/java/lang/ref/ReferenceEnqueue.java new file mode 100644 index 00000000000..25907a034cc --- /dev/null +++ b/jdk/test/java/lang/ref/ReferenceEnqueue.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 4268317 + * @summary Test if Reference.enqueue() works properly with GC + */ + +import java.lang.ref.*; + +public class ReferenceEnqueue { + + public static void main(String args[]) throws Exception { + for (int i=0; i < 5; i++) + new WeakRef().run(); + System.out.println("Test passed."); + } + + static class WeakRef { + final ReferenceQueue queue = new ReferenceQueue(); + final Reference ref; + final int iterations = 1000; + + WeakRef() { + this.ref = new WeakReference(new Object(), queue); + } + + void run() throws InterruptedException { + System.gc(); + for (int i = 0; i < iterations; i++) { + System.gc(); + if (ref.isEnqueued()) { + break; + } + + Thread.sleep(100); + } + + if (ref.isEnqueued() == false) { + // GC have not enqueued refWeak for the timeout period + System.out.println("Reference not enqueued yet"); + return; + } + + if (ref.enqueue() == true) { + // enqueue() should return false since + // ref is already enqueued by the GC + throw new RuntimeException("Error: enqueue() returned true;" + + " expected false"); + } + + if (queue.poll() == null) { + // poll() should return ref enqueued by the GC + throw new RuntimeException("Error: poll() returned null;" + + " expected ref object"); + } + } + } +} diff --git a/jdk/test/java/lang/ref/ReferenceEnqueuePending.java b/jdk/test/java/lang/ref/ReferenceEnqueuePending.java new file mode 100644 index 00000000000..0e8868fa9fd --- /dev/null +++ b/jdk/test/java/lang/ref/ReferenceEnqueuePending.java @@ -0,0 +1,201 @@ +/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 4243978 + * @summary Test if Reference.enqueue() works properly with pending references + */ +import java.lang.ref.*; + +public class ReferenceEnqueuePending { + static class NumberedWeakReference extends WeakReference { + // Add an integer to identify the weak reference object. + int number; + + NumberedWeakReference(Integer referent, ReferenceQueue q, int i) { + super(referent, q); + number = i; + } + } + + final static boolean debug = System.getProperty("test.debug") != null; + final static int iterations = 1000; + final static int gc_trigger = 99; + static int[] a = new int[2 * iterations]; + // Keep all weak references alive with the following array. + static NumberedWeakReference[] b = new NumberedWeakReference[iterations]; + + public static void main(String[] argv) throws Exception { + if (debug) { + System.out.println("Starting the test."); + } + // Raise thread priority to match the referenceHandler + // priority, so that they can race also on a uniprocessor. + raisePriority(); + + ReferenceQueue refQueue = new ReferenceQueue<>(); + + // Our objective is to let the mutator enqueue + // a Reference object that may already be in the + // pending state because of having been identified + // as weakly reachable at a previous garbage collection. + // To this end, we create many Reference objects, each with a + // a unique integer object as its referant. + // We let the referents become eligible for collection, + // while racing with the garbage collector which may + // have pended some of these Reference objects. + // Finally we check that all of the Reference objects + // end up on the their queue. The test was originally + // submitted to show that such races could break the + // pending list and/or the reference queue, because of sharing + // the same link ("next") for maintaining both lists, thus + // losing some of the Reference objects on either queue. + + Integer obj = new Integer(0); + NumberedWeakReference weaky = new NumberedWeakReference(obj, refQueue, 0); + for (int i = 1; i < iterations; i++) { + // Create a new object, dropping the onlY strong reference to + // the previous Integer object. + obj = new Integer(i); + // Trigger gc each gc_trigger iterations. + if ((i % gc_trigger) == 0) { + forceGc(0); + } + // Enqueue every other weaky. + if ((i % 2) == 0) { + weaky.enqueue(); + } + // Remember the Reference objects, for testing later. + b[i - 1] = weaky; + // Get a new weaky for the Integer object just + // created, which may be explicitly enqueued in + // our next trip around the loop. + weaky = new NumberedWeakReference(obj, refQueue, i); + } + + // Do a final collection to discover and process all + // Reference objects created above, allowing enough time + // for the ReferenceHandler thread to queue the References. + forceGc(100); + forceGc(100); + + // Verify that all WeakReference objects ended up queued. + checkResult(refQueue, obj, iterations-1); + System.out.println("Test passed."); + } + + private static void checkResult(ReferenceQueue queue, + Integer obj, + int expected) { + if (debug) { + System.out.println("Reading the queue"); + } + + // Empty the queue and record numbers into a[]; + NumberedWeakReference weakRead = (NumberedWeakReference) queue.poll(); + int length = 0; + while (weakRead != null) { + a[length++] = weakRead.number; + weakRead = (NumberedWeakReference) queue.poll(); + } + if (debug) { + System.out.println("Reference Queue had " + length + " elements"); + } + // Use the last Reference object of those created above, so as to keep it "alive". + System.out.println("I must write " + obj + " to prevent compiler optimizations."); + + + // verify the queued references: all but the last Reference object + // should have been in the queue. + if (debug) { + System.out.println("Start of final check"); + } + + // Sort the first "length" elements in array "a[]". + sort(length); + + boolean fail = (length != expected); + for (int i = 0; i < length; i++) { + if (a[i] != i) { + if (debug) { + System.out.println("a[" + i + "] is not " + i + " but " + a[i]); + } + fail = true; + } + } + if (fail) { + printMissingElements(length, expected); + throw new RuntimeException("TEST FAILED: only " + length + + " reference objects have been queued out of " + + expected); + } + } + + private static void printMissingElements(int length, int expected) { + System.out.println("The following numbers were not found in the reference queue: "); + int missing = 0; + int element = 0; + for (int i = 0; i < length; i++) { + while ((a[i] != element) & (element < expected)) { + System.out.print(element + " "); + if (missing % 20 == 19) { + System.out.println(" "); + } + missing++; + element++; + } + element++; + } + System.out.print("\n"); + } + + private static void forceGc(long millis) throws InterruptedException { + Runtime.getRuntime().gc(); + Thread.sleep(millis); + } + + // Bubble sort the first "length" elements in array "a". + private static void sort(int length) { + int hold; + if (debug) { + System.out.println("Sorting. Length=" + length); + } + for (int pass = 1; pass < length; pass++) { // passes over the array + for (int i = 0; i < length - pass; i++) { // a single pass + if (a[i] > a[i + 1]) { // then swap + hold = a[i]; + a[i] = a[i + 1]; + a[i + 1] = hold; + } + } // End of i loop + } // End of pass loop + } + + // Raise thread priority so as to increase the + // probability of the mutator succeeding in enqueueing + // an object that is still in the pending state. + // This is (probably) only required for a uniprocessor. + static void raisePriority() { + Thread tr = Thread.currentThread(); + tr.setPriority(Thread.MAX_PRIORITY); + } +} // End of class ReferenceEnqueuePending diff --git a/jdk/test/java/nio/charset/coders/Errors.java b/jdk/test/java/nio/charset/coders/Errors.java index be19c0b403d..0b74001dd6e 100644 --- a/jdk/test/java/nio/charset/coders/Errors.java +++ b/jdk/test/java/nio/charset/coders/Errors.java @@ -23,7 +23,7 @@ /* @test * @summary Check that error cases are replaced correctly in String/ISR/OSW - * @bug 4457851 + * @bug 4457851 7096080 * * @build Errors Util * @run main Errors @@ -193,11 +193,9 @@ public class Errors { t.test("\uFFFF", new byte[] { (byte)0xEF, (byte)0xBF, (byte)0xBF }); t.test(new byte[] { X, (byte)0x7f, Y }, "x\u007Fy"); t.test(new byte[] { X, (byte)0x80, Y }, "x\uFFFDy"); - t.test(new byte[] { (byte)0xf0, (byte)0xf0 }, "\uFFFD"); } public static void main(String[] args) throws Exception { - test_US_ASCII(new TestString("US-ASCII")); test_US_ASCII(new TestStream("US-ASCII")); diff --git a/jdk/test/java/util/Collections/EmptySortedSet.java b/jdk/test/java/util/Collections/EmptySortedSet.java new file mode 100644 index 00000000000..224400ec7a8 --- /dev/null +++ b/jdk/test/java/util/Collections/EmptySortedSet.java @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4533691 + * @summary Unit test for Collections.emptySortedSet + */ + +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.SortedSet; +import java.util.TreeSet; + +public class EmptySortedSet { + static int status = 0; + private static final String FAILED = " failed. "; + private static final String PERIOD = "."; + private final String thisClassName = this.getClass().getName(); + + public static void main(String[] args) throws Exception { + new EmptySortedSet(); + } + + public EmptySortedSet() throws Exception { + run(); + } + + /** + * Returns {@code true} if the {@link Object} passed in is an empty + * {@link SortedSet}. + * + * @param obj the object to test + * @return {@code true} if the {@link Object} is an empty {@link SortedSet} + * otherwise {@code false}. + */ + private boolean isEmptySortedSet(Object obj) { + boolean isEmptySortedSet = false; + + // We determine if the object is an empty sorted set by testing if it's + // an instance of SortedSet, and if so, if it's empty. Currently the + // testing doesn't include checks of the other methods. + if (obj instanceof SortedSet) { + SortedSet ss = (SortedSet) obj; + + if ((ss.isEmpty()) && (ss.size() == 0)) { + isEmptySortedSet = true; + } + } + + return isEmptySortedSet; + } + + private void run() throws Exception { + Method[] methods = this.getClass().getDeclaredMethods(); + + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + String methodName = method.getName(); + + if (methodName.startsWith("test")) { + try { + Object obj = method.invoke(this, new Object[0]); + } catch(Exception e) { + throw new Exception(this.getClass().getName() + "." + + methodName + " test failed, test exception " + + "follows\n" + e.getCause()); + } + } + } + } + + private void throwException(String methodName, String reason) + throws Exception + { + StringBuilder sb = new StringBuilder(thisClassName); + sb.append(PERIOD); + sb.append(methodName); + sb.append(FAILED); + sb.append(reason); + throw new Exception(sb.toString()); + } + + /** + * + */ + private void test00() throws Exception { + //throwException("test00", "This test has not been implemented yet."); + } + + /** + * Tests that the comparator is {@code null}. + */ + private void testComparatorIsNull() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + Comparator comparator = sortedSet.comparator(); + + if (comparator != null) { + throwException("testComparatorIsNull", "Comparator is not null."); + } + } + + /** + * Tests that the contains method returns {@code false}. + */ + private void testContains() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + if (sortedSet.contains(new Object())) { + throwException("testContains", "Should not contain any elements."); + } + } + + /** + * Tests that the containsAll method returns {@code false}. + */ + private void testContainsAll() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + TreeSet treeSet = new TreeSet(); + treeSet.add("1"); + treeSet.add("2"); + treeSet.add("3"); + + if (sortedSet.containsAll(treeSet)) { + throwException("testContainsAll", + "Should not contain any elements."); + } + } + + /** + * Tests that the iterator is empty. + */ + private void testEmptyIterator() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + Iterator emptyIterator = sortedSet.iterator(); + + if ((emptyIterator != null) && (emptyIterator.hasNext())) { + throwException("testEmptyIterator", "The iterator is not empty."); + } + } + + /** + * Tests that the set is empty. + */ + private void testIsEmpty() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + if ((sortedSet != null) && (!sortedSet.isEmpty())) { + throwException("testSizeIsZero", "The set is not empty."); + } + } + + /** + * Tests that the first() method throws NoSuchElementException + */ + private void testFirst() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + try { + sortedSet.first(); + throwException("testFirst", + "NoSuchElemenException was not thrown."); + } catch(NoSuchElementException nsee) { + // Do nothing + } + } + + /** + * Tests the headSet() method. + */ + private void testHeadSet() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + SortedSet ss; + + try { + ss = sortedSet.headSet(null); + throwException("testHeadSet", + "Must throw NullPointerException for null element"); + } catch(NullPointerException npe) { + // Do nothing + } + + try { + ss = sortedSet.headSet(new Object()); + throwException("testHeadSet", + "Must throw ClassCastException for non-Comparable element"); + } catch(ClassCastException cce) { + // Do nothing. + } + + ss = sortedSet.headSet("1"); + + if ((ss == null) || !isEmptySortedSet(ss)) { + throwException("testHeadSet", + "Returned value is null or not an EmptySortedSet."); + } + } + + /** + * Tests that the last() method throws NoSuchElementException + */ + private void testLast() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + + try { + sortedSet.last(); + throwException("testLast", + "NoSuchElemenException was not thrown."); + } catch(NoSuchElementException nsee) { + // Do nothing + } + } + + /** + * Tests that the size is 0. + */ + private void testSizeIsZero() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + int size = sortedSet.size(); + + if (size > 0) { + throwException("testSizeIsZero", + "The size of the set is greater then 0."); + } + } + + /** + * Tests the subSet() method. + */ + private void testSubSet() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + SortedSet ss = sortedSet.headSet("1"); + + try { + ss = sortedSet.subSet(null, BigInteger.TEN); + ss = sortedSet.subSet(BigInteger.ZERO, null); + ss = sortedSet.subSet(null, null); + throwException("testSubSet", + "Must throw NullPointerException for null element"); + } catch(NullPointerException npe) { + // Do nothing + } + + try { + Object obj1 = new Object(); + Object obj2 = new Object(); + ss = sortedSet.subSet(obj1, BigInteger.TEN); + ss = sortedSet.subSet(BigInteger.ZERO, obj2); + ss = sortedSet.subSet(obj1, obj2); + throwException("testSubSet", + "Must throw ClassCastException for parameter which is " + + "not Comparable."); + } catch(ClassCastException cce) { + // Do nothing. + } + + try { + ss = sortedSet.subSet(BigInteger.ZERO, BigInteger.ZERO); + ss = sortedSet.subSet(BigInteger.TEN, BigInteger.ZERO); + throwException("testSubSet", + "Must throw IllegalArgumentException when fromElement is " + + "not less then then toElement."); + } catch(IllegalArgumentException iae) { + // Do nothing. + } + + ss = sortedSet.subSet(BigInteger.ZERO, BigInteger.TEN); + + if (!isEmptySortedSet(ss)) { + throw new Exception("Returned value is not empty sorted set."); + } + } + + /** + * Tests the tailSet() method. + */ + private void testTailSet() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + SortedSet ss; + + try { + ss = sortedSet.tailSet(null); + throwException("testTailSet", + "Must throw NullPointerException for null element"); + } catch(NullPointerException npe) { + // Do nothing + } + + try { + SortedSet ss2 = sortedSet.tailSet(new Object()); + throwException("testTailSet", + "Must throw ClassCastException for non-Comparable element"); + } catch(ClassCastException cce) { + // Do nothing. + } + + ss = sortedSet.tailSet("1"); + + if ((ss == null) || !isEmptySortedSet(ss)) { + throwException("testTailSet", + "Returned value is null or not an EmptySortedSet."); + } + } + + /** + * Tests that the array has a size of 0. + */ + private void testToArray() throws Exception { + SortedSet sortedSet = Collections.emptySortedSet(); + Object[] emptySortedSetArray = sortedSet.toArray(); + + if ((emptySortedSetArray == null) || (emptySortedSetArray.length > 0)) { + throwException("testToArray", + "Returned null array or array with length > 0."); + } + + String[] strings = new String[2]; + strings[0] = "1"; + strings[1] = "2"; + emptySortedSetArray = sortedSet.toArray(strings); + + if ((emptySortedSetArray == null) || (emptySortedSetArray[0] != null)) { + throwException("testToArray", + "Returned null array or array with length > 0."); + } + } +} diff --git a/jdk/test/java/util/Currency/CurrencyTest.java b/jdk/test/java/util/Currency/CurrencyTest.java index e7ae4fd79fc..c22813845ce 100644 --- a/jdk/test/java/util/Currency/CurrencyTest.java +++ b/jdk/test/java/util/Currency/CurrencyTest.java @@ -128,18 +128,20 @@ public class CurrencyTest { checkCountryCurrency(country1[i], currency1[i]); } - // check currency changes - String[] switchOverCtry = {"DE", "FR", "ES", "IT", "NL", "BE", "TR", "RO", "AZ", "MZ", "GH", "VE"}; - String[] switchOverOld = {"DEM", "FRF", "ESP", "ITL", "NLG", "BEF", "TRL", "ROL", "AZM", "MZM", "GHC", "VEB"}; - String[] switchOverNew = {"EUR", "EUR", "EUR", "EUR", "EUR", "EUR", "TRY", "RON", "AZN", "MZN", "GHS", "VEF"}; - String[] switchOverTZ = {"Europe/Paris", "Europe/Paris", "Europe/Paris", "Europe/Paris", - "Europe/Paris", "Europe/Paris", "Asia/Istanbul", "Europe/Bucharest", - "Asia/Baku", "Africa/Maputo", "Africa/Accra", "America/Caracas"}; - int[] switchOverYear = {2002, 2002, 2002, 2002, 2002, 2002, 2005, 2005, 2006, 2006, 2007, 2008}; - int[] switchOverMonth = {Calendar.JANUARY, Calendar.JANUARY, Calendar.JANUARY, Calendar.JANUARY, - Calendar.JANUARY, Calendar.JANUARY, Calendar.JANUARY, Calendar.JULY, - Calendar.JANUARY, Calendar.JULY, Calendar.JULY, Calendar.JANUARY}; - int[] switchOverDay = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + /* + * check currency changes + * In current implementation, there is no data of old currency and transition date at jdk/src/share/classes/java/util/CurrencyData.properties. + * So, all the switch data arrays are empty. In the future, if data of old currency and transition date are necessary for any country, the + * arrays here can be updated so that the program can check the currency switch. + */ + String[] switchOverCtry = {}; + String[] switchOverOld = {}; + String[] switchOverNew = {}; + String[] switchOverTZ = {}; + int[] switchOverYear = {}; + int[] switchOverMonth = {}; + int[] switchOverDay = {}; + for (int i = 0; i < switchOverCtry.length; i++) { TimeZone.setDefault(TimeZone.getTimeZone(switchOverTZ[i])); Calendar date = new GregorianCalendar(switchOverYear[i], switchOverMonth[i], switchOverDay[i]); diff --git a/jdk/test/java/util/Currency/ValidateISO4217.java b/jdk/test/java/util/Currency/ValidateISO4217.java index 3f5078060d4..679acfa20a9 100644 --- a/jdk/test/java/util/Currency/ValidateISO4217.java +++ b/jdk/test/java/util/Currency/ValidateISO4217.java @@ -92,7 +92,7 @@ public class ValidateISO4217 { /* Codes that are obsolete, do not have related country */ static final String otherCodes = - "ADP-AFA-ATS-AYM-BEF-BGL-BOV-BYB-CLF-CUC-CYP-DEM-EEK-ESP-FIM-FRF-GRD-GWP-IEP-ITL-LUF-MGF-MTL-MXV-NLG-PTE-RUR-SDD-SIT-SKK-SRG-TMM-TPE-TRL-VEF-USN-USS-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-YUM-ZWD-ZWN-ZWR"; + "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-CLF-CUC-CYP-DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LUF-MGF-MTL-MXV-MZM-NLG-PTE-ROL-RUR-SDD-SIT-SKK-SRG-TMM-TPE-TRL-VEF-USN-USS-VEB-XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-YUM-ZWD-ZWN-ZWR"; static boolean err = false; diff --git a/jdk/test/java/util/Currency/tablea1.txt b/jdk/test/java/util/Currency/tablea1.txt index 898af09b538..8b2e1b5871f 100644 --- a/jdk/test/java/util/Currency/tablea1.txt +++ b/jdk/test/java/util/Currency/tablea1.txt @@ -23,7 +23,7 @@ AW AWG 533 2 AU AUD 36 2 AT EUR 978 2 # MA 129 -AZ AZM 31 2 2005-12-31-20-00-00 AZN 944 2 +AZ AZN 944 2 BS BSD 44 2 BH BHD 48 3 BD BDT 50 2 @@ -96,7 +96,7 @@ GA XAF 950 0 GM GMD 270 2 GE GEL 981 2 DE EUR 978 2 -GH GHC 288 2 2007-07-01-00-00-00 GHS 936 2 +GH GHS 936 2 GI GIP 292 2 GR EUR 978 2 GL DKK 208 2 @@ -166,7 +166,7 @@ MN MNT 496 2 MS XCD 951 2 MA MAD 504 2 # MA 130 -MZ MZM 508 2 2006-06-30-22-00-00 MZN 943 2 +MZ MZN 943 2 MM MMK 104 2 # MA 134 ME EUR 978 2 @@ -200,7 +200,7 @@ PT EUR 978 2 PR USD 840 2 QA QAR 634 2 RE EUR 978 2 -RO ROL 946 2 2005-06-30-21-00-00 RON 946 2 +RO RON 946 2 RU RUB 643 2 RW RWF 646 0 SH SHP 654 2 @@ -266,7 +266,7 @@ UM USD 840 2 UY UYU 858 2 UZ UZS 860 2 VU VUV 548 0 -VE VEB 862 2 2008-01-01-04-00-00 VEF 937 2 +VE VEF 937 2 VN VND 704 2 VG USD 840 2 VI USD 840 2 diff --git a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java index e4a963847ec..60ce1c66de2 100644 --- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java +++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 4635230 6283345 6303830 6824440 6867348 + * @bug 4635230 6283345 6303830 6824440 6867348 7094155 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java GenerationTests.java @@ -134,6 +134,7 @@ public class GenerationTests { test_create_signature_enveloping_sha512_rsa_sha384(); test_create_signature_enveloping_sha512_rsa_sha512(); test_create_signature_reference_dependency(); + test_create_signature_with_attr_in_no_namespace(); } private static void setup() throws Exception { @@ -443,6 +444,52 @@ public class GenerationTests { sig.sign(dsc); +// dumpDocument(doc, new PrintWriter(System.out)); + + DOMValidateContext dvc = new DOMValidateContext + (kvks, doc.getDocumentElement()); + XMLSignature sig2 = fac.unmarshalXMLSignature(dvc); + + if (sig.equals(sig2) == false) { + throw new Exception + ("Unmarshalled signature is not equal to generated signature"); + } + if (sig2.validate(dvc) == false) { + throw new Exception("Validation of generated signature failed"); + } + + System.out.println(); + } + + static void test_create_signature_with_attr_in_no_namespace() + throws Exception + { + System.out.println + ("* Generating signature-with-attr-in-no-namespace.xml"); + + // create references + List refs = Collections.singletonList + (fac.newReference("#unknown", sha1)); + + // create SignedInfo + SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs); + + // create object-1 + Document doc = db.newDocument(); + Element nc = doc.createElementNS(null, "NonCommentandus"); + // add attribute with no namespace + nc.setAttribute("Id", "unknown"); + XMLObject obj = fac.newXMLObject(Collections.singletonList + (new DOMStructure(nc)), "object-1", null, null); + + // create XMLSignature + XMLSignature sig = fac.newXMLSignature(si, rsa, + Collections.singletonList(obj), + "signature", null); + DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc); + + sig.sign(dsc); + // dumpDocument(doc, new PrintWriter(System.out)); DOMValidateContext dvc = new DOMValidateContext diff --git a/jdk/test/sun/nio/cs/TestStringCoding.java b/jdk/test/sun/nio/cs/TestStringCoding.java index c4837e956ae..09e61444889 100644 --- a/jdk/test/sun/nio/cs/TestStringCoding.java +++ b/jdk/test/sun/nio/cs/TestStringCoding.java @@ -24,7 +24,7 @@ */ /* @test - @bug 6636323 6636319 7040220 + @bug 6636323 6636319 7040220 7096080 @summary Test if StringCoding and NIO result have the same de/encoding result * @run main/othervm/timeout=2000 TestStringCoding */ @@ -111,7 +111,8 @@ public class TestStringCoding { //encode unmappable surrogates if (enc instanceof sun.nio.cs.ArrayEncoder && cs.contains(Charset.forName("ASCII"))) { - if (cs.name().equals("UTF-8")) // utf8 handles surrogates + if (cs.name().equals("UTF-8") || // utf8 handles surrogates + cs.name().equals("CESU-8")) // utf8 handles surrogates return; enc.replaceWith(new byte[] { (byte)'A'}); sun.nio.cs.ArrayEncoder cae = (sun.nio.cs.ArrayEncoder)enc; @@ -136,7 +137,6 @@ public class TestStringCoding { cs.name()))) throw new RuntimeException("encode3(surrogates) failed -> " + cs.name()); - ba = new byte[str.length() - 1]; n = cae.encode(str.toCharArray(), 0, str.length(), ba); if (n != 7 || !"abABABc".equals(new String(ba, 0, n, diff --git a/jdk/test/sun/nio/cs/TestStringCodingUTF8.java b/jdk/test/sun/nio/cs/TestStringCodingUTF8.java index fdc204849b7..d1f69950684 100644 --- a/jdk/test/sun/nio/cs/TestStringCodingUTF8.java +++ b/jdk/test/sun/nio/cs/TestStringCodingUTF8.java @@ -33,14 +33,16 @@ import java.nio.charset.*; public class TestStringCodingUTF8 { public static void main(String[] args) throws Throwable { - test(); + test("UTF-8"); + test("CESU-8"); // security manager on System.setSecurityManager(new PermissiveSecurityManger()); - test(); + test("UTF-8"); + test("CESU-8"); } - static void test() throws Throwable { - Charset cs = Charset.forName("UTF-8"); + static void test(String csn) throws Throwable { + Charset cs = Charset.forName(csn); char[] bmp = new char[0x10000]; for (int i = 0; i < 0x10000; i++) { bmp[i] = (char)i; diff --git a/jdk/test/sun/nio/cs/TestUTF8.java b/jdk/test/sun/nio/cs/TestUTF8.java index f339eae046b..e83f8fbb51a 100644 --- a/jdk/test/sun/nio/cs/TestUTF8.java +++ b/jdk/test/sun/nio/cs/TestUTF8.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4486841 7040220 + * @bug 4486841 7040220 7096080 * @summary Test UTF-8 charset */ @@ -156,15 +156,22 @@ public class TestUTF8 { return 3; } + static int to4ByteUTF8(int uc, byte[] bb, int pos) { + bb[pos++] = (byte)(0xf0 | ((uc >> 18))); + bb[pos++] = (byte)(0x80 | ((uc >> 12) & 0x3f)); + bb[pos++] = (byte)(0x80 | ((uc >> 6) & 0x3f)); + bb[pos++] = (byte)(0x80 | (uc & 0x3f)); + return 4; + } + static void checkRoundtrip(String csn) throws Exception { System.out.printf(" Check roundtrip <%s>...", csn); char[] cc = getUTFChars(); byte[] bb = encode(cc, csn, false); char[] ccO = decode(bb, csn, false); - if (!Arrays.equals(cc, ccO)) { + if (!Arrays.equals(cc, ccO)) System.out.printf(" non-direct failed"); - } bb = encode(cc, csn, true); ccO = decode(bb, csn, true); if (!Arrays.equals(cc, ccO)) { @@ -180,6 +187,40 @@ public class TestUTF8 { System.out.println(); } + static void check4ByteSurrs(String csn) throws Exception { + System.out.printf(" Check 4-byte Surrogates <%s>...%n", csn); + byte[] bb = new byte[(0x110000 - 0x10000) * 4]; + char[] cc = new char[(0x110000 - 0x10000) * 2]; + int bpos = 0; + int cpos = 0; + for (int i = 0x10000; i < 0x110000; i++) { + Character.toChars(i, cc, cpos); + bpos += to4ByteUTF8(i, bb, bpos); + cpos += 2; + } + checkSurrs(csn, bb, cc); + } + + + static void checkSurrs(String csn, byte[] bb, char[] cc) + throws Exception + { + char[] ccO = decode(bb, csn, false); + if (!Arrays.equals(cc, ccO)) { + System.out.printf(" decoding failed%n"); + } + ccO = decode(bb, csn, true); + if (!Arrays.equals(cc, ccO)) { + System.out.printf(" decoding(direct) failed%n"); + } + if (!Arrays.equals(cc, new String(bb, csn).toCharArray())) { + System.out.printf(" String.toCharArray() failed"); + } + if (!Arrays.equals(bb, new String(cc).getBytes(csn))) { + System.out.printf(" String.getBytes() failed"); + } + } + static void check6ByteSurrs(String csn) throws Exception { System.out.printf(" Check 6-byte Surrogates <%s>...%n", csn); byte[] bb = new byte[(0x110000 - 0x10000) * 6]; @@ -192,23 +233,10 @@ public class TestUTF8 { bpos += to3ByteUTF8(cc[cpos + 1], bb, bpos); cpos += 2; } - - char[] ccO = decode(bb, csn, false); - if (!Arrays.equals(cc, ccO)) { - System.out.printf(" decoding failed%n"); - } - ccO = decode(bb, csn, true); - if (!Arrays.equals(cc, ccO)) { - System.out.printf(" decoding(direct) failed%n"); - } - // new String(bb, csn).getBytes(csn) will not return - // the 6 bytes surrogates as in bb, so only test - // toCharArray() here. - if (!Arrays.equals(cc, new String(bb, csn).toCharArray())) { - System.out.printf(" String.toCharArray() failed"); - } + checkSurrs(csn, bb, cc); } + static void compare(String csn1, String csn2) throws Exception { System.out.printf(" Diff <%s> <%s>...%n", csn1, csn2); char[] cc = getUTFChars(); @@ -266,6 +294,10 @@ public class TestUTF8 { {1, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones {1, (byte)0xE0, (byte)0xC0, (byte)0x80 }, // invalid second byte {1, (byte)0xE0, (byte)0x80, (byte)0xC0 }, // invalid first byte + {1, (byte)0xE0, (byte)0x41,}, // invalid second byte & 2 bytes + {3, (byte)0xED, (byte)0xAE, (byte)0x80 }, // 3 bytes surrogate + {3, (byte)0xED, (byte)0xB0, (byte)0x80 }, // 3 bytes surrogate + // Four-byte sequences {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded @@ -276,8 +308,13 @@ public class TestUTF8 { {1, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid second byte {1, (byte)0xF0, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte + {1, (byte)0xF0, (byte)41 }, // invalid second byte + // & only 2 bytes + {2, (byte)0xF0, (byte)0x90, (byte)0xC0, (byte)0x80 }, // invalid third byte - {3, (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0xC0 }, // invalid third byte + {3, (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0xC0 }, // invalid forth byte + {2, (byte)0xF0, (byte)0x90, (byte)0x41 }, // invalid third byte + // & 3 bytes input {1, (byte)0xF1, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte {2, (byte)0xF1, (byte)0x80, (byte)0xC0, (byte)0x80 }, // invalid third byte @@ -287,30 +324,113 @@ public class TestUTF8 { {1, (byte)0xF5, (byte)0x80, (byte)0x80, (byte)0xC0 }, // out-range 4-byte // Five-byte sequences - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid first byte - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded - {5, (byte)0xF8, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid first byte + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80}, - {2, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80 }, - {3, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF }, - {4, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0 }, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0 }, // Six-byte sequences - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded - {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, - {2, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80 }, - {3, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF, (byte)0x80 }, - {4, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0, (byte)0x80 }, - {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0x80, (byte)0xC0 }, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0x80, (byte)0xC0 }, }; - static void checkMalformed(String csn) throws Exception { + // The first byte is the length of malformed bytes + static byte[][] malformed_cesu8 = { + // One-byte sequences: + {1, (byte)0xFF }, + {1, (byte)0xC0 }, + {1, (byte)0x80 }, + + {1, (byte)0xFF, (byte)0xFF}, // all ones + {1, (byte)0xA0, (byte)0x80}, // 101x first byte first nibble + + // Two-byte sequences: + {1, (byte)0xC0, (byte)0x80}, // invalid first byte + {1, (byte)0xC1, (byte)0xBF}, // invalid first byte + {1, (byte)0xC2, (byte)0x00}, // invalid second byte + {1, (byte)0xC2, (byte)0xC0}, // invalid second byte + {1, (byte)0xD0, (byte)0x00}, // invalid second byte + {1, (byte)0xD0, (byte)0xC0}, // invalid second byte + {1, (byte)0xDF, (byte)0x00}, // invalid second byte + {1, (byte)0xDF, (byte)0xC0}, // invalid second byte + + // Three-byte sequences + {1, (byte)0xE0, (byte)0x80, (byte)0x80}, // 111x first byte first nibble + {1, (byte)0xE0, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xE0, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xE0, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + + {1, (byte)0xE0, (byte)0xC0, (byte)0xBF }, // invalid second byte + {2, (byte)0xE0, (byte)0xA0, (byte)0x7F }, // invalid third byte + {2, (byte)0xE0, (byte)0xA0, (byte)0xC0 }, // invalid third byte + {1, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones + {1, (byte)0xE0, (byte)0xC0, (byte)0x80 }, // invalid second byte + {1, (byte)0xE0, (byte)0x80, (byte)0xC0 }, // invalid first byte + {1, (byte)0xE0, (byte)0x41,}, // invalid second byte & 2 bytes + + // CESU-8 does not have 4, 5, 6 bytes sequenc + // Four-byte sequences + {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xF0, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF0, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF0, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+07FF zero-padded + + {1, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones + {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid second byte + {1, (byte)0xF0, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte + {1, (byte)0xF0, (byte)41 }, // invalid second byte + // & only 2 bytes + {1, (byte)0xF0, (byte)0x90, (byte)0xC0, (byte)0x80 }, // invalid third byte + {1, (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0xC0 }, // invalid forth byte + {1, (byte)0xF0, (byte)0x90, (byte)0x41 }, // invalid third byte + // & 3 bytes input + + {1, (byte)0xF1, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte + {1, (byte)0xF1, (byte)0x80, (byte)0xC0, (byte)0x80 }, // invalid third byte + {1, (byte)0xF1, (byte)0x80, (byte)0x80, (byte)0xC0 }, // invalid forth byte + {1, (byte)0xF4, (byte)0x90, (byte)0x80, (byte)0xC0 }, // out-range 4-byte + {1, (byte)0xF4, (byte)0xC0, (byte)0x80, (byte)0xC0 }, // out-range 4-byte + {1, (byte)0xF5, (byte)0x80, (byte)0x80, (byte)0xC0 }, // out-range 4-byte + + // Five-byte sequences + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80}, // invalid first byte + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xF8, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + + {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80}, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0 }, + + // Six-byte sequences + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded + {1, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded + {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0, (byte)0x80 }, + {1, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0x80, (byte)0xC0 }, + }; + + + static void checkMalformed(String csn, byte[][] malformed) throws Exception { boolean failed = false; System.out.printf(" Check malformed <%s>...%n", csn); Charset cs = Charset.forName(csn); @@ -430,9 +550,12 @@ public class TestUTF8 { public static void main(String[] args) throws Exception { checkRoundtrip("UTF-8"); - check6ByteSurrs("UTF-8"); - //compare("UTF-8", "UTF-8-OLD"); - checkMalformed("UTF-8"); + check4ByteSurrs("UTF-8"); + checkMalformed("UTF-8", malformed); checkUnderOverflow("UTF-8"); + + checkRoundtrip("CESU-8"); + check6ByteSurrs("CESU-8"); + checkMalformed("CESU-8", malformed_cesu8); } } diff --git a/jdk/test/sun/security/pkcs11/Provider/Absolute.java b/jdk/test/sun/security/pkcs11/Provider/Absolute.java index e35f9c60c58..fc035dc7c73 100644 --- a/jdk/test/sun/security/pkcs11/Provider/Absolute.java +++ b/jdk/test/sun/security/pkcs11/Provider/Absolute.java @@ -27,7 +27,6 @@ */ import java.security.*; import java.lang.reflect.*; -import sun.security.pkcs11.*; public class Absolute { diff --git a/jdk/test/sun/security/pkcs11/fips/CipherTest.java b/jdk/test/sun/security/pkcs11/fips/CipherTest.java index 0d9f8b363e0..32bc6df4e16 100644 --- a/jdk/test/sun/security/pkcs11/fips/CipherTest.java +++ b/jdk/test/sun/security/pkcs11/fips/CipherTest.java @@ -394,52 +394,47 @@ public class CipherTest { public static void main(PeerFactory peerFactory, KeyStore keyStore, String[] args) throws Exception { - SSLContext reservedSSLContext = SSLContext.getDefault(); - try { - long time = System.currentTimeMillis(); - String relPath; - if ((args != null) && (args.length > 0) && args[0].equals("sh")) { - relPath = pathToStoresSH; - } else { - relPath = pathToStores; - } - PATH = new File(System.getProperty("test.src", "."), relPath); - CipherTest.peerFactory = peerFactory; - System.out.print( - "Initializing test '" + peerFactory.getName() + "'..."); -// secureRandom = new SecureRandom(); -// secureRandom.nextInt(); -// trustStore = readKeyStore(trustStoreFile); - CipherTest.keyStore = keyStore; -// keyStore = readKeyStore(keyStoreFile); - KeyManagerFactory keyFactory = - KeyManagerFactory.getInstance( - KeyManagerFactory.getDefaultAlgorithm()); - keyFactory.init(keyStore, "test12".toCharArray()); - keyManager = (X509ExtendedKeyManager)keyFactory.getKeyManagers()[0]; - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(keyStore); - trustManager = (X509TrustManager)tmf.getTrustManagers()[0]; - -// trustManager = new AlwaysTrustManager(); - SSLContext context = SSLContext.getInstance("TLS"); - context.init(new KeyManager[] {keyManager}, - new TrustManager[] {trustManager}, null); - SSLContext.setDefault(context); - - CipherTest cipherTest = new CipherTest(peerFactory); - Thread serverThread = new Thread(peerFactory.newServer(cipherTest), - "Server"); - serverThread.setDaemon(true); - serverThread.start(); - System.out.println("Done"); - cipherTest.run(); - time = System.currentTimeMillis() - time; - System.out.println("Done. (" + time + " ms)"); - } finally { - SSLContext.setDefault(reservedSSLContext); + long time = System.currentTimeMillis(); + String relPath; + if ((args != null) && (args.length > 0) && args[0].equals("sh")) { + relPath = pathToStoresSH; + } else { + relPath = pathToStores; } + PATH = new File(System.getProperty("test.src", "."), relPath); + CipherTest.peerFactory = peerFactory; + System.out.print( + "Initializing test '" + peerFactory.getName() + "'..."); +// secureRandom = new SecureRandom(); +// secureRandom.nextInt(); +// trustStore = readKeyStore(trustStoreFile); + CipherTest.keyStore = keyStore; +// keyStore = readKeyStore(keyStoreFile); + KeyManagerFactory keyFactory = + KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); + keyFactory.init(keyStore, "test12".toCharArray()); + keyManager = (X509ExtendedKeyManager)keyFactory.getKeyManagers()[0]; + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + trustManager = (X509TrustManager)tmf.getTrustManagers()[0]; + +// trustManager = new AlwaysTrustManager(); + SSLContext context = SSLContext.getInstance("TLS"); + context.init(new KeyManager[] {keyManager}, + new TrustManager[] {trustManager}, null); + SSLContext.setDefault(context); + + CipherTest cipherTest = new CipherTest(peerFactory); + Thread serverThread = new Thread(peerFactory.newServer(cipherTest), + "Server"); + serverThread.setDaemon(true); + serverThread.start(); + System.out.println("Done"); + cipherTest.run(); + time = System.currentTimeMillis() - time; + System.out.println("Done. (" + time + " ms)"); } static abstract class PeerFactory { diff --git a/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java b/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java index 4cf931d969e..98dbdeea5e4 100644 --- a/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java +++ b/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java @@ -26,9 +26,9 @@ * @bug 6313675 6323647 * @summary Verify that all ciphersuites work in FIPS mode * @library .. - * @run main/othervm ClientJSSEServerJSSE * @ignore JSSE supported cipher suites are changed with CR 6916074, * need to update this test case in JDK 7 soon + * @run main/othervm ClientJSSEServerJSSE * @author Andreas Sterbenz */ diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java index 9a18be3240f..432aed4ffe3 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java @@ -1,10 +1,7 @@ /* * @test * @build TestThread Traffic Handler ServerHandler ServerThread ClientThread - * @run main/othervm/timeout=140 main - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. + * @run main/othervm/timeout=140 -Djsse.enableCBCProtection=false main * @summary Make sure that different configurations of SSL sockets work */ diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java index c29f55a04b9..dfdefa9f1f7 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ * This is a simple hack to test a bunch of conditions and check * their return codes. * + * @run main/othervm -Djsse.enableCBCProtection=false CheckStatus + * * @author Brad Wetmore */ diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java index 849e739c823..5960ea63992 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargeBufs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ * This is to test larger buffer arrays, and make sure the maximum * is being passed. * + * @run main/othervm -Djsse.enableCBCProtection=false LargeBufs + * * @author Brad R. Wetmore */ diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java index 9740b67021e..498df71463a 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,10 +27,7 @@ * @bug 6388456 * @summary Need adjustable TLS max record size for interoperability * with non-compliant - * @run main/othervm LargePacket - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. + * @run main/othervm -Djsse.enableCBCProtection=false LargePacket * * @author Xuelei Fan */ diff --git a/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java b/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java new file mode 100644 index 00000000000..e31409a0f74 --- /dev/null +++ b/jdk/test/sun/security/ssl/templates/SSLSocketSSLEngineTemplate.java @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7105780 + * @summary Add SSLSocket client/SSLEngine server to templates directory. + * + * SunJSSE does not support dynamic system properties, no way to re-use + * system properties in samevm/agentvm mode. + * + * @run main/othervm SSLSocketSSLEngineTemplate + */ + +/** + * A SSLSocket/SSLEngine interop test case. This is not the way to + * code SSLEngine-based servers, but works for what we need to do here, + * which is to make sure that SSLEngine/SSLSockets can talk to each other. + * SSLEngines can use direct or indirect buffers, and different code + * is used to get at the buffer contents internally, so we test that here. + * + * The test creates one SSLSocket (client) and one SSLEngine (server). + * The SSLSocket talks to a raw ServerSocket, and the server code + * does the translation between byte [] and ByteBuffers that the SSLEngine + * can use. The "transport" layer consists of a Socket Input/OutputStream + * and two byte buffers for the SSLEngines: think of them + * as directly connected pipes. + * + * Again, this is a *very* simple example: real code will be much more + * involved. For example, different threading and I/O models could be + * used, transport mechanisms could close unexpectedly, and so on. + * + * When this application runs, notice that several messages + * (wrap/unwrap) pass before any application data is consumed or + * produced. (For more information, please see the SSL/TLS + * specifications.) There may several steps for a successful handshake, + * so it's typical to see the following series of operations: + * + * client server message + * ====== ====== ======= + * write() ... ClientHello + * ... unwrap() ClientHello + * ... wrap() ServerHello/Certificate + * read() ... ServerHello/Certificate + * write() ... ClientKeyExchange + * write() ... ChangeCipherSpec + * write() ... Finished + * ... unwrap() ClientKeyExchange + * ... unwrap() ChangeCipherSpec + * ... unwrap() Finished + * ... wrap() ChangeCipherSpec + * ... wrap() Finished + * read() ... ChangeCipherSpec + * read() ... Finished + */ +import javax.net.ssl.*; +import javax.net.ssl.SSLEngineResult.*; +import java.io.*; +import java.net.*; +import java.security.*; +import java.nio.*; + +public class SSLSocketSSLEngineTemplate { + + /* + * Enables logging of the SSL/TLS operations. + */ + private static boolean logging = true; + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static boolean debug = false; + private SSLContext sslc; + private SSLEngine serverEngine; // server-side SSLEngine + private SSLSocket sslSocket; // client-side socket + private ServerSocket serverSocket; // server-side Socket, generates the... + private Socket socket; // server-side socket that will read + + private final byte[] serverMsg = + "Hi there Client, I'm a Server.".getBytes(); + private final byte[] clientMsg = + "Hello Server, I'm a Client! Pleased to meet you!".getBytes(); + + private ByteBuffer serverOut; // write side of serverEngine + private ByteBuffer serverIn; // read side of serverEngine + + private volatile Exception clientException; + private volatile Exception serverException; + + /* + * For data transport, this example uses local ByteBuffers. + */ + private ByteBuffer cTOs; // "reliable" transport client->server + private ByteBuffer sTOc; // "reliable" transport server->client + + /* + * The following is to set up the keystores/trust material. + */ + private static final String pathToStores = "../etc/"; + private static final String keyStoreFile = "keystore"; + private static final String trustStoreFile = "truststore"; + private static final String passwd = "passphrase"; + private static String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + private static String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + /* + * Main entry point for this test. + */ + public static void main(String args[]) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + + String [] protocols = new String [] { + "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }; + + for (String protocol : protocols) { + log("Testing " + protocol); + /* + * Run the tests with direct and indirect buffers. + */ + SSLSocketSSLEngineTemplate test = + new SSLSocketSSLEngineTemplate(protocol); + test.runTest(true); + test.runTest(false); + } + + System.out.println("Test Passed."); + } + + /* + * Create an initialized SSLContext to use for these tests. + */ + public SSLSocketSSLEngineTemplate(String protocol) throws Exception { + + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + + char[] passphrase = "passphrase".toCharArray(); + + ks.load(new FileInputStream(keyFilename), passphrase); + ts.load(new FileInputStream(trustFilename), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance(protocol); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + sslc = sslCtx; + } + + /* + * Run the test. + * + * Sit in a tight loop, with the server engine calling wrap/unwrap + * regardless of whether data is available or not. We do this until + * we get the application data. Then we shutdown and go to the next one. + * + * The main loop handles all of the I/O phases of the SSLEngine's + * lifetime: + * + * initial handshaking + * application data transfer + * engine closing + * + * One could easily separate these phases into separate + * sections of code. + */ + private void runTest(boolean direct) throws Exception { + boolean serverClose = direct; + + serverSocket = new ServerSocket(0); + int port = serverSocket.getLocalPort(); + Thread thread = createClientThread(port, serverClose); + + socket = serverSocket.accept(); + socket.setSoTimeout(500); + serverSocket.close(); + + createSSLEngine(); + createBuffers(direct); + + try { + boolean closed = false; + + InputStream is = socket.getInputStream(); + OutputStream os = socket.getOutputStream(); + + SSLEngineResult serverResult; // results from last operation + + /* + * Examining the SSLEngineResults could be much more involved, + * and may alter the overall flow of the application. + * + * For example, if we received a BUFFER_OVERFLOW when trying + * to write to the output pipe, we could reallocate a larger + * pipe, but instead we wait for the peer to drain it. + */ + byte[] inbound = new byte[8192]; + byte[] outbound = new byte[8192]; + + while (!isEngineClosed(serverEngine)) { + int len = 0; + + // Inbound data + log("================"); + + // Read from the Client side. + try { + len = is.read(inbound); + if (len == -1) { + throw new Exception("Unexpected EOF"); + } + cTOs.put(inbound, 0, len); + } catch (SocketTimeoutException ste) { + // swallow. Nothing yet, probably waiting on us. + } + + cTOs.flip(); + + serverResult = serverEngine.unwrap(cTOs, serverIn); + log("server unwrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + cTOs.compact(); + + // Outbound data + log("----"); + + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + + sTOc.flip(); + + if ((len = sTOc.remaining()) != 0) { + sTOc.get(outbound, 0, len); + os.write(outbound, 0, len); + // Give the other side a chance to process + } + + sTOc.compact(); + + if (!closed && (serverOut.remaining() == 0)) { + closed = true; + + /* + * We'll alternate initiatating the shutdown. + * When the server initiates, it will take one more + * loop, but tests the orderly shutdown. + */ + if (serverClose) { + serverEngine.closeOutbound(); + } + serverIn.flip(); + + /* + * A sanity check to ensure we got what was sent. + */ + if (serverIn.remaining() != clientMsg.length) { + throw new Exception("Client: Data length error"); + } + + for (int i = 0; i < clientMsg.length; i++) { + if (clientMsg[i] != serverIn.get()) { + throw new Exception("Client: Data content error"); + } + } + serverIn.compact(); + } + } + return; + } catch (Exception e) { + serverException = e; + } finally { + socket.close(); + + // Wait for the client to join up with us. + thread.join(); + if (serverException != null) { + throw serverException; + } + if (clientException != null) { + throw clientException; + } + } + } + + /* + * Create a client thread which does simple SSLSocket operations. + * We'll write and read one data packet. + */ + private Thread createClientThread(final int port, + final boolean serverClose) throws Exception { + + Thread t = new Thread("ClientThread") { + + @Override + public void run() { + try { + Thread.sleep(1000); // Give server time to finish setup. + + sslSocket = (SSLSocket) sslc.getSocketFactory(). + createSocket("localhost", port); + OutputStream os = sslSocket.getOutputStream(); + InputStream is = sslSocket.getInputStream(); + + // write(byte[]) goes in one shot. + os.write(clientMsg); + + byte[] inbound = new byte[2048]; + int pos = 0; + + int len; +done: + while ((len = is.read(inbound, pos, 2048 - pos)) != -1) { + pos += len; + // Let the client do the closing. + if ((pos == serverMsg.length) && !serverClose) { + sslSocket.close(); + break done; + } + } + + if (pos != serverMsg.length) { + throw new Exception("Client: Data length error"); + } + + for (int i = 0; i < serverMsg.length; i++) { + if (inbound[i] != serverMsg[i]) { + throw new Exception("Client: Data content error"); + } + } + } catch (Exception e) { + clientException = e; + } + } + }; + t.start(); + return t; + } + + /* + * Using the SSLContext created during object creation, + * create/configure the SSLEngines we'll use for this test. + */ + private void createSSLEngine() throws Exception { + /* + * Configure the serverEngine to act as a server in the SSL/TLS + * handshake. + */ + serverEngine = sslc.createSSLEngine(); + serverEngine.setUseClientMode(false); + serverEngine.getNeedClientAuth(); + } + + /* + * Create and size the buffers appropriately. + */ + private void createBuffers(boolean direct) { + + SSLSession session = serverEngine.getSession(); + int appBufferMax = session.getApplicationBufferSize(); + int netBufferMax = session.getPacketBufferSize(); + + /* + * We'll make the input buffers a bit bigger than the max needed + * size, so that unwrap()s following a successful data transfer + * won't generate BUFFER_OVERFLOWS. + * + * We'll use a mix of direct and indirect ByteBuffers for + * tutorial purposes only. In reality, only use direct + * ByteBuffers when they give a clear performance enhancement. + */ + if (direct) { + serverIn = ByteBuffer.allocateDirect(appBufferMax + 50); + cTOs = ByteBuffer.allocateDirect(netBufferMax); + sTOc = ByteBuffer.allocateDirect(netBufferMax); + } else { + serverIn = ByteBuffer.allocate(appBufferMax + 50); + cTOs = ByteBuffer.allocate(netBufferMax); + sTOc = ByteBuffer.allocate(netBufferMax); + } + + serverOut = ByteBuffer.wrap(serverMsg); + } + + /* + * If the result indicates that we have outstanding tasks to do, + * go ahead and run them in this thread. + */ + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + log("\trunning delegated task..."); + runnable.run(); + } + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception( + "handshake shouldn't need additional tasks"); + } + log("\tnew HandshakeStatus: " + hsStatus); + } + } + + private static boolean isEngineClosed(SSLEngine engine) { + return (engine.isOutboundDone() && engine.isInboundDone()); + } + + /* + * Logging code + */ + private static boolean resultOnce = true; + + private static void log(String str, SSLEngineResult result) { + if (!logging) { + return; + } + if (resultOnce) { + resultOnce = false; + System.out.println("The format of the SSLEngineResult is: \n" + + "\t\"getStatus() / getHandshakeStatus()\" +\n" + + "\t\"bytesConsumed() / bytesProduced()\"\n"); + } + HandshakeStatus hsStatus = result.getHandshakeStatus(); + log(str + + result.getStatus() + "/" + hsStatus + ", " + + result.bytesConsumed() + "/" + result.bytesProduced() + + " bytes"); + if (hsStatus == HandshakeStatus.FINISHED) { + log("\t...ready for application data"); + } + } + + private static void log(String str) { + if (logging) { + System.out.println(str); + } + } +} diff --git a/jdk/test/sun/text/resources/Collator/Bug6755060.java b/jdk/test/sun/text/resources/Collator/Bug6755060.java new file mode 100644 index 00000000000..ee23487d44b --- /dev/null +++ b/jdk/test/sun/text/resources/Collator/Bug6755060.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6755060 + * @summary updating collation tables for thai to make it consistent with CLDR 1.9 + */ + +import java.text.*; +import java.util.*; + +public class Bug6755060 { + + /******************************************************** + *********************************************************/ + public static void main (String[] args) { + + Locale reservedLocale = Locale.getDefault(); + + try{ + + int errors=0; + + Locale loc = new Locale ("th", "TH"); // Thai + + Locale.setDefault (loc); + Collator col = Collator.getInstance (); + + /* + * The original data "data" are the data to be sorted provided by the submitter of the CR. + * It's in correct order in accord with thai collation in CLDR 1.9. If we use old Java without this fix, + * the output order will be incorrect. Correct order will be turned into incorrect order. + + * If fix is there, "data" after sorting will be unchanged, same as "sortedData". If fix is lost (regression), + * "data" after sorting will be changed, not as "sortedData".(not correct anymore) + + * The submitter of the CR also gives a expected "sortedData" in the CR, but it's in accord with collation in CLDR 1.4. + * His data to be sorted are actually well sorted in accord with CLDR 1.9. + */ + + String[] data = {"\u0e01", "\u0e01\u0e2f", "\u0e01\u0e46", "\u0e01\u0e4f", "\u0e01\u0e5a", "\u0e01\u0e5b", "\u0e01\u0e4e", "\u0e01\u0e4c", "\u0e01\u0e48", "\u0e01\u0e01", "\u0e01\u0e4b\u0e01", "\u0e01\u0e4d", "\u0e01\u0e30", "\u0e01\u0e31\u0e01", "\u0e01\u0e32", "\u0e01\u0e33", "\u0e01\u0e34", "\u0e01\u0e35", "\u0e01\u0e36", "\u0e01\u0e37", "\u0e01\u0e38", "\u0e01\u0e39", "\u0e40\u0e01", "\u0e40\u0e01\u0e48", "\u0e40\u0e01\u0e49", "\u0e40\u0e01\u0e4b", "\u0e41\u0e01", "\u0e42\u0e01", "\u0e43\u0e01", "\u0e44\u0e01", "\u0e01\u0e3a", "\u0e24\u0e32", "\u0e24\u0e45", "\u0e40\u0e25", "\u0e44\u0e26"}; + + String[] sortedData = {"\u0e01", "\u0e01\u0e2f", "\u0e01\u0e46", "\u0e01\u0e4f", "\u0e01\u0e5a", "\u0e01\u0e5b", "\u0e01\u0e4e", "\u0e01\u0e4c", "\u0e01\u0e48", "\u0e01\u0e01", "\u0e01\u0e4b\u0e01", "\u0e01\u0e4d", "\u0e01\u0e30", "\u0e01\u0e31\u0e01", "\u0e01\u0e32", "\u0e01\u0e33", "\u0e01\u0e34", "\u0e01\u0e35", "\u0e01\u0e36", "\u0e01\u0e37", "\u0e01\u0e38", "\u0e01\u0e39", "\u0e40\u0e01", "\u0e40\u0e01\u0e48", "\u0e40\u0e01\u0e49", "\u0e40\u0e01\u0e4b", "\u0e41\u0e01", "\u0e42\u0e01", "\u0e43\u0e01", "\u0e44\u0e01", "\u0e01\u0e3a", "\u0e24\u0e32", "\u0e24\u0e45", "\u0e40\u0e25", "\u0e44\u0e26"}; + + Arrays.sort (data, col); + + System.out.println ("Using " + loc.getDisplayName()); + for (int i = 0; i < data.length; i++) { + System.out.println(data[i] + " : " + sortedData[i]); + if (sortedData[i].compareTo(data[i]) != 0) { + errors++; + } + }//end for + + if (errors > 0){ + StringBuffer expected = new StringBuffer(), actual = new StringBuffer(); + expected.append(sortedData[0]); + actual.append(data[0]); + + for (int i=1; i&' with an external RMI registry diff --git a/langtools/.hgtags b/langtools/.hgtags index 06958e1b0c5..ffd905c4f03 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -133,3 +133,5 @@ e8acc2d6c32f0c8321e642e1a86672a2e196a056 jdk8-b08 b7a7e47c8d3daf7822abf7c37e5179ccbbf53008 jdk8-b09 f6c783e18bdf4d46a0ab273868afebbf32600ff7 jdk8-b10 4bf01f1c4e3464f378959d10f3983a0469181d94 jdk8-b11 +f2d6ed25857dfa7f269ac66e13666d648cb988c6 jdk8-b12 +ae25163501bc7477cd907e26a006a6f1b05fdb6d jdk8-b13 diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index 1b1e331dae9..e1a82e6cc54 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -325,7 +325,7 @@ public class JavacTaskImpl extends JavacTask { ListBuffer elements = new ListBuffer(); for (JCCompilationUnit unit : units) { for (JCTree node : unit.defs) { - if (node.getTag() == JCTree.CLASSDEF) { + if (node.hasTag(JCTree.Tag.CLASSDEF)) { JCClassDecl cdef = (JCClassDecl) node; if (cdef.sym != null) // maybe null if errors in anno processing elements.append(cdef.sym); @@ -383,12 +383,12 @@ public class JavacTaskImpl extends JavacTask { private void handleFlowResults(Queue> queue, ListBuffer elems) { for (Env env: queue) { switch (env.tree.getTag()) { - case JCTree.CLASSDEF: + case CLASSDEF: JCClassDecl cdef = (JCClassDecl) env.tree; if (cdef.sym != null) elems.append(cdef.sym); break; - case JCTree.TOPLEVEL: + case TOPLEVEL: JCCompilationUnit unit = (JCCompilationUnit) env.tree; if (unit.packge != null) elems.append(unit.packge); diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java index 7bd384bb5ac..1c6f7302751 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -207,7 +207,7 @@ public class JavacTrees extends Trees { if (sym == null && TreeInfo.isDeclaration(tree)) { for (TreePath p = path; p != null; p = p.getParentPath()) { JCTree t = (JCTree) p.getLeaf(); - if (t.getTag() == JCTree.CLASSDEF) { + if (t.hasTag(JCTree.Tag.CLASSDEF)) { JCClassDecl ct = (JCClassDecl) t; if (ct.sym != null) { if ((ct.sym.flags_field & Flags.UNATTRIBUTED) != 0) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index 3d13527da8c..724481e54ae 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; + /** Enter annotations on symbols. Annotations accumulate in a queue, * which is processed at the top level of any set of recursive calls * requesting it be processed. @@ -148,7 +150,7 @@ public class Annotate { return new Attribute.Compound(a.type, List.>nil()); } List args = a.args; - if (args.length() == 1 && args.head.getTag() != JCTree.ASSIGN) { + if (args.length() == 1 && !args.head.hasTag(ASSIGN)) { // special case: elided "value=" assumed args.head = make.at(args.head.pos). Assign(make.Ident(names.value), args.head); @@ -157,12 +159,12 @@ public class Annotate { new ListBuffer>(); for (List tl = args; tl.nonEmpty(); tl = tl.tail) { JCExpression t = tl.head; - if (t.getTag() != JCTree.ASSIGN) { + if (!t.hasTag(ASSIGN)) { log.error(t.pos(), "annotation.value.must.be.name.value"); continue; } JCAssign assign = (JCAssign)t; - if (assign.lhs.getTag() != JCTree.IDENT) { + if (!assign.lhs.hasTag(IDENT)) { log.error(t.pos(), "annotation.value.must.be.name.value"); continue; } @@ -222,14 +224,14 @@ public class Annotate { (((JCFieldAccess) tree).selected).type); } if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) { - if (tree.getTag() != JCTree.ANNOTATION) { + if (!tree.hasTag(ANNOTATION)) { log.error(tree.pos(), "annotation.value.must.be.annotation"); expected = syms.errorType; } return enterAnnotation((JCAnnotation)tree, expected, env); } if (expected.tag == TypeTags.ARRAY) { // should really be isArray() - if (tree.getTag() != JCTree.NEWARRAY) { + if (!tree.hasTag(NEWARRAY)) { tree = make.at(tree.pos). NewArray(null, List.nil(), List.of(tree)); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 68b782f44ed..ebecb033566 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -49,8 +49,13 @@ import com.sun.source.tree.TreeVisitor; import com.sun.source.util.SimpleTreeVisitor; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Flags.ANNOTATION; +import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Kinds.*; +import static com.sun.tools.javac.code.Kinds.ERRONEOUS; import static com.sun.tools.javac.code.TypeTags.*; +import static com.sun.tools.javac.code.TypeTags.WILDCARD; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** This is the main context-dependent analysis phase in GJC. It * encompasses name resolution, type checking and constant folding as @@ -245,7 +250,7 @@ public class Attr extends JCTree.Visitor { ((v.flags() & HASINIT) != 0 || !((base == null || - (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) && + (base.hasTag(IDENT) && TreeInfo.name(base) == names._this)) && isAssignableAsBlankFinal(v, env)))) { if (v.isResourceVariable()) { //TWR resource log.error(pos, "try.resource.may.not.be.assigned", v); @@ -263,7 +268,7 @@ public class Attr extends JCTree.Visitor { * @param tree The candidate tree. */ boolean isStaticReference(JCTree tree) { - if (tree.getTag() == JCTree.SELECT) { + if (tree.hasTag(SELECT)) { Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected); if (lsym == null || lsym.kind != TYP) { return false; @@ -693,7 +698,7 @@ public class Attr extends JCTree.Visitor { // disable implicit outer instance from being passed. // (This would be an illegal access to "this before super"). if (env.info.isSelfCall && - env.tree.getTag() == JCTree.NEWCLASS && + env.tree.hasTag(NEWCLASS) && ((JCNewClass) env.tree).encl == null) { c.flags_field |= NOOUTERTHIS; @@ -863,7 +868,7 @@ public class Attr extends JCTree.Visitor { chk.checkDeprecatedAnnotation(tree.pos(), v); if (tree.init != null) { - if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) { + if ((v.flags_field & FINAL) != 0 && !tree.init.hasTag(NEWCLASS)) { // In this case, `v' is final. Ensure that it's initializer is // evaluated. v.getConstValue(); // ensure initializer is evaluated @@ -971,8 +976,8 @@ public class Attr extends JCTree.Visitor { public void visitLabelled(JCLabeledStatement tree) { // Check that label is not used in an enclosing statement Env env1 = env; - while (env1 != null && env1.tree.getTag() != JCTree.CLASSDEF) { - if (env1.tree.getTag() == JCTree.LABELLED && + while (env1 != null && !env1.tree.hasTag(CLASSDEF)) { + if (env1.tree.hasTag(LABELLED) && ((JCLabeledStatement) env1.tree).label == tree.label) { log.error(tree.pos(), "label.already.in.use", tree.label); @@ -1052,14 +1057,14 @@ public class Attr extends JCTree.Visitor { private static void addVars(List stats, Scope switchScope) { for (;stats.nonEmpty(); stats = stats.tail) { JCTree stat = stats.head; - if (stat.getTag() == JCTree.VARDEF) + if (stat.hasTag(VARDEF)) switchScope.enter(((JCVariableDecl) stat).sym); } } // where /** Return the selected enumeration constant symbol, or null. */ private Symbol enumConstant(JCTree tree, Type enumType) { - if (tree.getTag() != JCTree.IDENT) { + if (!tree.hasTag(IDENT)) { log.error(tree.pos(), "enum.label.must.be.unqualified.enum"); return syms.errSymbol; } @@ -1094,7 +1099,7 @@ public class Attr extends JCTree.Visitor { localEnv; // Attribute resource declarations for (JCTree resource : tree.resources) { - if (resource.getTag() == JCTree.VARDEF) { + if (resource.hasTag(VARDEF)) { attribStat(resource, tryEnv); chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type"); @@ -1312,7 +1317,7 @@ public class Attr extends JCTree.Visitor { * @param env The environment current at the jump statement. */ private JCTree findJumpTarget(DiagnosticPosition pos, - int tag, + JCTree.Tag tag, Name label, Env env) { // Search environments outwards from the point of jump. @@ -1320,15 +1325,15 @@ public class Attr extends JCTree.Visitor { LOOP: while (env1 != null) { switch (env1.tree.getTag()) { - case JCTree.LABELLED: + case LABELLED: JCLabeledStatement labelled = (JCLabeledStatement)env1.tree; if (label == labelled.label) { // If jump is a continue, check that target is a loop. - if (tag == JCTree.CONTINUE) { - if (labelled.body.getTag() != JCTree.DOLOOP && - labelled.body.getTag() != JCTree.WHILELOOP && - labelled.body.getTag() != JCTree.FORLOOP && - labelled.body.getTag() != JCTree.FOREACHLOOP) + if (tag == CONTINUE) { + if (!labelled.body.hasTag(DOLOOP) && + !labelled.body.hasTag(WHILELOOP) && + !labelled.body.hasTag(FORLOOP) && + !labelled.body.hasTag(FOREACHLOOP)) log.error(pos, "not.loop.label", label); // Found labelled statement target, now go inwards // to next non-labelled tree. @@ -1338,17 +1343,17 @@ public class Attr extends JCTree.Visitor { } } break; - case JCTree.DOLOOP: - case JCTree.WHILELOOP: - case JCTree.FORLOOP: - case JCTree.FOREACHLOOP: + case DOLOOP: + case WHILELOOP: + case FORLOOP: + case FOREACHLOOP: if (label == null) return env1.tree; break; - case JCTree.SWITCH: - if (label == null && tag == JCTree.BREAK) return env1.tree; + case SWITCH: + if (label == null && tag == BREAK) return env1.tree; break; - case JCTree.METHODDEF: - case JCTree.CLASSDEF: + case METHODDEF: + case CLASSDEF: break LOOP; default: } @@ -1356,7 +1361,7 @@ public class Attr extends JCTree.Visitor { } if (label != null) log.error(pos, "undef.label", label); - else if (tag == JCTree.CONTINUE) + else if (tag == CONTINUE) log.error(pos, "cont.outside.loop"); else log.error(pos, "break.outside.switch.loop"); @@ -1452,7 +1457,7 @@ public class Attr extends JCTree.Visitor { if (encl.tag == CLASS) { // we are calling a nested class - if (tree.meth.getTag() == JCTree.SELECT) { + if (tree.meth.hasTag(SELECT)) { JCTree qualifier = ((JCFieldAccess) tree.meth).selected; // We are seeing a prefixed call, of the form @@ -1468,7 +1473,7 @@ public class Attr extends JCTree.Visitor { rs.resolveImplicitThis(tree.meth.pos(), localEnv, site, true); } - } else if (tree.meth.getTag() == JCTree.SELECT) { + } else if (tree.meth.hasTag(SELECT)) { log.error(tree.meth.pos(), "illegal.qual.not.icls", site.tsym); } @@ -1522,7 +1527,7 @@ public class Attr extends JCTree.Visitor { // as a special case, array.clone() has a result that is // the same as static type of the array being cloned - if (tree.meth.getTag() == JCTree.SELECT && + if (tree.meth.hasTag(SELECT) && allowCovariantReturns && methName == names.clone && types.isArray(((JCFieldAccess) tree.meth).selected.type)) @@ -1531,7 +1536,7 @@ public class Attr extends JCTree.Visitor { // as a special case, x.getClass() has type Class if (allowGenerics && methName == names.getClass && tree.args.isEmpty()) { - Type qualifier = (tree.meth.getTag() == JCTree.SELECT) + Type qualifier = (tree.meth.hasTag(SELECT)) ? ((JCFieldAccess) tree.meth).selected.type : env.enclClass.sym.type; restype = new @@ -1560,7 +1565,7 @@ public class Attr extends JCTree.Visitor { JCMethodDecl enclMethod = env.enclMethod; if (enclMethod != null && enclMethod.name == names.init) { JCBlock body = enclMethod.body; - if (body.stats.head.getTag() == JCTree.EXEC && + if (body.stats.head.hasTag(EXEC) && ((JCExpressionStatement) body.stats.head).expr == tree) return true; } @@ -1591,7 +1596,7 @@ public class Attr extends JCTree.Visitor { // complete class name to be fully qualified JCExpression clazz = tree.clazz; // Class field following new JCExpression clazzid = // Identifier in class field - (clazz.getTag() == JCTree.TYPEAPPLY) + (clazz.hasTag(TYPEAPPLY)) ? ((JCTypeApply) clazz).clazz : clazz; @@ -1610,7 +1615,7 @@ public class Attr extends JCTree.Visitor { attribExpr(tree.encl, env)); clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), ((JCIdent) clazzid).name); - if (clazz.getTag() == JCTree.TYPEAPPLY) + if (clazz.hasTag(TYPEAPPLY)) clazz = make.at(tree.pos). TypeApply(clazzid1, ((JCTypeApply) clazz).arguments); @@ -1689,7 +1694,7 @@ public class Attr extends JCTree.Visitor { // Enums may not be instantiated except implicitly if (allowEnums && (clazztype.tsym.flags_field&Flags.ENUM) != 0 && - (env.tree.getTag() != JCTree.VARDEF || + (!env.tree.hasTag(VARDEF) || (((JCVariableDecl) env.tree).mods.flags&Flags.ENUM) == 0 || ((JCVariableDecl) env.tree).init != tree)) log.error(tree.pos(), "enum.cant.be.instantiated"); @@ -1930,7 +1935,7 @@ public class Attr extends JCTree.Visitor { Name name = TreeInfo.name(arg); if (name == names._this || name == names._super) return arg; - int optag = JCTree.NULLCHK; + JCTree.Tag optag = NULLCHK; JCUnary tree = make.at(arg.pos).Unary(optag, arg); tree.operator = syms.nullcheck; tree.type = arg.type; @@ -1991,7 +1996,7 @@ public class Attr extends JCTree.Visitor { Type operand = attribExpr(tree.rhs, env); // Find operator. Symbol operator = tree.operator = rs.resolveBinaryOperator( - tree.pos(), tree.getTag() - JCTree.ASGOffset, env, + tree.pos(), tree.getTag().noAssignOp(), env, owntype, operand); if (operator.kind == MTH && @@ -1999,7 +2004,7 @@ public class Attr extends JCTree.Visitor { !operand.isErroneous()) { chk.checkOperator(tree.pos(), (OperatorSymbol)operator, - tree.getTag() - JCTree.ASGOffset, + tree.getTag().noAssignOp(), owntype, operand); chk.checkDivZero(tree.rhs.pos(), operator, operand); @@ -2012,7 +2017,7 @@ public class Attr extends JCTree.Visitor { public void visitUnary(JCUnary tree) { // Attribute arguments. - Type argtype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC) + Type argtype = (tree.getTag().isIncOrDecUnaryOp()) ? attribTree(tree.arg, env, VAR, Type.noType) : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env)); @@ -2023,7 +2028,7 @@ public class Attr extends JCTree.Visitor { Type owntype = types.createErrorType(tree.type); if (operator.kind == MTH && !argtype.isErroneous()) { - owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC) + owntype = (tree.getTag().isIncOrDecUnaryOp()) ? tree.arg.type : operator.type.getReturnType(); int opc = ((OperatorSymbol)operator).opcode; @@ -2621,7 +2626,7 @@ public class Attr extends JCTree.Visitor { canOwnInitializer(env.info.scope.owner) && v.owner == env.info.scope.owner.enclClass() && ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && - (env.tree.getTag() != JCTree.ASSIGN || + (!env.tree.hasTag(ASSIGN) || TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { String suffix = (env.info.enclVar == v) ? "self.ref" : "forward.ref"; @@ -2812,10 +2817,10 @@ public class Attr extends JCTree.Visitor { } Type elemtype = types.elemtype(argtype); switch (tree.getTag()) { - case JCTree.APPLY: + case APPLY: ((JCMethodInvocation) tree).varargsElement = elemtype; break; - case JCTree.NEWCLASS: + case NEWCLASS: ((JCNewClass) tree).varargsElement = elemtype; break; default: @@ -2896,9 +2901,9 @@ public class Attr extends JCTree.Visitor { if (clazzOuter.tag == CLASS) { Type site; JCExpression clazz = TreeInfo.typeIn(tree.clazz); - if (clazz.getTag() == JCTree.IDENT) { + if (clazz.hasTag(IDENT)) { site = env.enclClass.sym.type; - } else if (clazz.getTag() == JCTree.SELECT) { + } else if (clazz.hasTag(SELECT)) { site = ((JCFieldAccess) clazz).selected.type; } else throw new AssertionError(""+tree); if (clazzOuter.tag == CLASS && site != clazzOuter) { @@ -3068,7 +3073,7 @@ public class Attr extends JCTree.Visitor { * Attribute an env for either a top level tree or class declaration. */ public void attrib(Env env) { - if (env.tree.getTag() == JCTree.TOPLEVEL) + if (env.tree.hasTag(TOPLEVEL)) attribTopLevel(env); else attribClass(env.tree.pos(), env.enclClass.sym); @@ -3245,7 +3250,7 @@ public class Attr extends JCTree.Visitor { ((c.flags() & STATIC) == 0 || c.name == names.empty) && (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) { Symbol sym = null; - if (l.head.getTag() == JCTree.VARDEF) sym = ((JCVariableDecl) l.head).sym; + if (l.head.hasTag(VARDEF)) sym = ((JCVariableDecl) l.head).sym; if (sym == null || sym.kind != VAR || ((VarSymbol) sym).getConstValue() == null) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index cd5ced051fd..e384efa9022 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -42,10 +42,14 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Symbol.*; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Flags.ANNOTATION; +import static com.sun.tools.javac.code.Flags.SYNCHRONIZED; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; +import static com.sun.tools.javac.code.TypeTags.WILDCARD; import static com.sun.tools.javac.main.OptionName.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** Type checking helper class for the attribution phase. * @@ -987,7 +991,7 @@ public class Check { * not final. */ private long implicitEnumFinalFlag(JCTree tree) { - if (tree.getTag() != JCTree.CLASSDEF) return 0; + if (!tree.hasTag(CLASSDEF)) return 0; class SpecialTreeVisitor extends JCTree.Visitor { boolean specialized; SpecialTreeVisitor() { @@ -1099,7 +1103,7 @@ public class Check { // not parameterized at all. if (tree.type.getEnclosingType().isRaw()) log.error(tree.pos(), "improperly.formed.type.inner.raw.param"); - if (tree.clazz.getTag() == JCTree.SELECT) + if (tree.clazz.hasTag(SELECT)) visitSelectInternal((JCFieldAccess)tree.clazz); } } @@ -2413,7 +2417,7 @@ public class Check { // count them off as they're annotated for (JCTree arg : a.args) { - if (arg.getTag() != JCTree.ASSIGN) continue; // recovery + if (!arg.hasTag(ASSIGN)) continue; // recovery JCAssign assign = (JCAssign) arg; Symbol m = TreeInfo.symbol(assign.lhs); if (m == null || m.type.isErroneous()) continue; @@ -2442,12 +2446,12 @@ public class Check { a.args.tail == null) return; - if (a.args.head.getTag() != JCTree.ASSIGN) return; // error recovery + if (!a.args.head.hasTag(ASSIGN)) return; // error recovery JCAssign assign = (JCAssign) a.args.head; Symbol m = TreeInfo.symbol(assign.lhs); if (m.name != names.value) return; JCTree rhs = assign.rhs; - if (rhs.getTag() != JCTree.NEWARRAY) return; + if (!rhs.hasTag(NEWARRAY)) return; JCNewArray na = (JCNewArray) rhs; Set targets = new HashSet(); for (JCTree elem : na.elems) { @@ -2506,7 +2510,7 @@ public class Check { try { tree.sym.flags_field |= LOCKED; for (JCTree def : tree.defs) { - if (def.getTag() != JCTree.METHODDEF) continue; + if (!def.hasTag(METHODDEF)) continue; JCMethodDecl meth = (JCMethodDecl)def; checkAnnotationResType(meth.pos(), meth.restype.type); } @@ -2614,7 +2618,7 @@ public class Check { */ int checkOperator(DiagnosticPosition pos, OperatorSymbol operator, - int tag, + JCTree.Tag tag, Type left, Type right) { if (operator.opcode == ByteCodes.error) { @@ -2650,7 +2654,8 @@ public class Check { * Check for empty statements after if */ void checkEmptyIf(JCIf tree) { - if (tree.thenpart.getTag() == JCTree.SKIP && tree.elsepart == null && lint.isEnabled(LintCategory.EMPTY)) + if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null && + lint.isEnabled(LintCategory.EMPTY)) log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if"); } @@ -2754,7 +2759,7 @@ public class Check { } // where private boolean isCanonical(JCTree tree) { - while (tree.getTag() == JCTree.SELECT) { + while (tree.hasTag(SELECT)) { JCFieldAccess s = (JCFieldAccess) tree; if (s.sym.owner != TreeInfo.symbol(s.selected)) return false; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index 864698458fc..ac8ce840afb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -228,7 +228,7 @@ public class Enter extends JCTree.Visitor { * only, and members go into the class member scope. */ Scope enterScope(Env env) { - return (env.tree.getTag() == JCTree.CLASSDEF) + return (env.tree.hasTag(JCTree.Tag.CLASSDEF)) ? ((JCClassDecl) env.tree).sym.members_field : env.info.scope; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Env.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Env.java index c46cafe0396..f61ed700e0b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Env.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Env.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,9 +116,9 @@ public class Env implements Iterable> { /** Return closest enclosing environment which points to a tree with given tag. */ - public Env enclosing(int tag) { + public Env enclosing(JCTree.Tag tag) { Env env1 = this; - while (env1 != null && env1.tree.getTag() != tag) env1 = env1.next; + while (env1 != null && !env1.tree.hasTag(tag)) env1 = env1.next; return env1; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index 0c685f932e4..d54a295b9b0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -40,8 +40,10 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** This pass implements dataflow analysis for Java programs. * Liveness analysis checks that every statement is reachable. @@ -321,7 +323,7 @@ public class Flow extends TreeScanner { log.error(exit.tree.pos(), "unreported.exception.default.constructor", exit.thrown); - } else if (exit.tree.getTag() == JCTree.VARDEF && + } else if (exit.tree.hasTag(VARDEF) && ((JCVariableDecl)exit.tree).sym.isResourceVariable()) { log.error(exit.tree.pos(), "unreported.exception.implicit.close", @@ -416,7 +418,7 @@ public class Flow extends TreeScanner { */ void letInit(JCTree tree) { tree = TreeInfo.skipParens(tree); - if (tree.getTag() == JCTree.IDENT || tree.getTag() == JCTree.SELECT) { + if (tree.hasTag(IDENT) || tree.hasTag(SELECT)) { Symbol sym = TreeInfo.symbol(tree); if (sym.kind == VAR) { letInit(tree.pos(), (VarSymbol)sym); @@ -452,7 +454,7 @@ public class Flow extends TreeScanner { pendingExits = oldPendingExits; for (; exits.nonEmpty(); exits = exits.tail) { PendingExit exit = exits.head; - if (exit.tree.getTag() == JCTree.BREAK && + if (exit.tree.hasTag(BREAK) && ((JCBreak) exit.tree).target == tree) { inits.andSet(exit.inits); uninits.andSet(exit.uninits); @@ -471,7 +473,7 @@ public class Flow extends TreeScanner { pendingExits = new ListBuffer(); for (; exits.nonEmpty(); exits = exits.tail) { PendingExit exit = exits.head; - if (exit.tree.getTag() == JCTree.CONTINUE && + if (exit.tree.hasTag(CONTINUE) && ((JCContinue) exit.tree).target == tree) { inits.andSet(exit.inits); uninits.andSet(exit.uninits); @@ -517,7 +519,7 @@ public class Flow extends TreeScanner { */ void scanDef(JCTree tree) { scanStat(tree); - if (tree != null && tree.getTag() == JCTree.BLOCK && !alive) { + if (tree != null && tree.hasTag(JCTree.Tag.BLOCK) && !alive) { log.error(tree.pos(), "initializer.must.be.able.to.complete.normally"); } @@ -528,7 +530,7 @@ public class Flow extends TreeScanner { void scanStat(JCTree tree) { if (!alive && tree != null) { log.error(tree.pos(), "unreachable.stmt"); - if (tree.getTag() != JCTree.SKIP) alive = true; + if (!tree.hasTag(SKIP)) alive = true; } scan(tree); } @@ -614,7 +616,7 @@ public class Flow extends TreeScanner { try { // define all the static fields for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.getTag() == JCTree.VARDEF) { + if (l.head.hasTag(VARDEF)) { JCVariableDecl def = (JCVariableDecl)l.head; if ((def.mods.flags & STATIC) != 0) { VarSymbol sym = def.sym; @@ -626,7 +628,7 @@ public class Flow extends TreeScanner { // process all the static initializers for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.getTag() != JCTree.METHODDEF && + if (!l.head.hasTag(METHODDEF) && (TreeInfo.flags(l.head) & STATIC) != 0) { scanDef(l.head); errorUncaught(); @@ -653,7 +655,7 @@ public class Flow extends TreeScanner { // define all the instance fields for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.getTag() == JCTree.VARDEF) { + if (l.head.hasTag(VARDEF)) { JCVariableDecl def = (JCVariableDecl)l.head; if ((def.mods.flags & STATIC) == 0) { VarSymbol sym = def.sym; @@ -665,7 +667,7 @@ public class Flow extends TreeScanner { // process all the instance initializers for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.getTag() != JCTree.METHODDEF && + if (!l.head.hasTag(METHODDEF) && (TreeInfo.flags(l.head) & STATIC) == 0) { scanDef(l.head); errorUncaught(); @@ -691,7 +693,7 @@ public class Flow extends TreeScanner { // process all the methods for (List l = tree.defs; l.nonEmpty(); l = l.tail) { - if (l.head.getTag() == JCTree.METHODDEF) { + if (l.head.hasTag(METHODDEF)) { scan(l.head); errorUncaught(); } @@ -760,7 +762,7 @@ public class Flow extends TreeScanner { PendingExit exit = exits.head; exits = exits.tail; if (exit.thrown == null) { - Assert.check(exit.tree.getTag() == JCTree.RETURN); + Assert.check(exit.tree.hasTag(RETURN)); if (isInitialConstructor) { inits = exit.inits; for (int i = firstadr; i < nextadr; i++) @@ -989,7 +991,7 @@ public class Flow extends TreeScanner { Bits uninits) { for (;stats.nonEmpty(); stats = stats.tail) { JCTree stat = stats.head; - if (stat.getTag() == JCTree.VARDEF) { + if (stat.hasTag(VARDEF)) { int adr = ((JCVariableDecl) stat).sym.adr; inits.excl(adr); uninits.incl(adr); @@ -1346,7 +1348,7 @@ public class Flow extends TreeScanner { public void visitUnary(JCUnary tree) { switch (tree.getTag()) { - case JCTree.NOT: + case NOT: scanCond(tree.arg); Bits t = initsWhenFalse; initsWhenFalse = initsWhenTrue; @@ -1355,8 +1357,8 @@ public class Flow extends TreeScanner { uninitsWhenFalse = uninitsWhenTrue; uninitsWhenTrue = t; break; - case JCTree.PREINC: case JCTree.POSTINC: - case JCTree.PREDEC: case JCTree.POSTDEC: + case PREINC: case POSTINC: + case PREDEC: case POSTDEC: scanExpr(tree.arg); letInit(tree.arg); break; @@ -1367,7 +1369,7 @@ public class Flow extends TreeScanner { public void visitBinary(JCBinary tree) { switch (tree.getTag()) { - case JCTree.AND: + case AND: scanCond(tree.lhs); Bits initsWhenFalseLeft = initsWhenFalse; Bits uninitsWhenFalseLeft = uninitsWhenFalse; @@ -1377,7 +1379,7 @@ public class Flow extends TreeScanner { initsWhenFalse.andSet(initsWhenFalseLeft); uninitsWhenFalse.andSet(uninitsWhenFalseLeft); break; - case JCTree.OR: + case OR: scanCond(tree.lhs); Bits initsWhenTrueLeft = initsWhenTrue; Bits uninitsWhenTrueLeft = uninitsWhenTrue; @@ -1418,7 +1420,7 @@ public class Flow extends TreeScanner { private boolean is292targetTypeCast(JCTypeCast tree) { boolean is292targetTypeCast = false; JCExpression expr = TreeInfo.skipParens(tree.expr); - if (expr.getTag() == JCTree.APPLY) { + if (expr.hasTag(APPLY)) { JCMethodInvocation apply = (JCMethodInvocation)expr; Symbol sym = TreeInfo.symbol(apply.meth); is292targetTypeCast = sym != null && diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index cc5ed20727e..00564d9e5f7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -633,13 +633,13 @@ public class Infer { //the polymorphic signature call environment is nested. switch (env.next.tree.getTag()) { - case JCTree.TYPECAST: + case TYPECAST: JCTypeCast castTree = (JCTypeCast)env.next.tree; restype = (TreeInfo.skipParens(castTree.expr) == env.tree) ? castTree.clazz.type : syms.objectType; break; - case JCTree.EXEC: + case EXEC: JCTree.JCExpressionStatement execTree = (JCTree.JCExpressionStatement)env.next.tree; restype = (TreeInfo.skipParens(execTree.expr) == env.tree) ? diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 6c687fb7c4d..d4bb9fc8ded 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -42,9 +42,11 @@ import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.jvm.Target; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.ByteCodes.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** This pass translates away some syntactic sugar: inner classes, * class literals, assertions, foreach loops, etc. @@ -303,7 +305,7 @@ public class Lower extends TreeTranslator { Symbol constructor = TreeInfo.symbol(tree.meth); ClassSymbol c = (ClassSymbol)constructor.owner; if (c.hasOuterInstance() && - tree.meth.getTag() != JCTree.SELECT && + !tree.meth.hasTag(SELECT) && outerThisStack.head != null) visitSymbol(outerThisStack.head); } @@ -508,7 +510,7 @@ public class Lower extends TreeTranslator { * @param optag The operators tree tag. * @param arg The operator's argument. */ - JCUnary makeUnary(int optag, JCExpression arg) { + JCUnary makeUnary(JCTree.Tag optag, JCExpression arg) { JCUnary tree = make.Unary(optag, arg); tree.operator = rs.resolveUnaryOperator( make_pos, optag, attrEnv, arg.type); @@ -521,7 +523,7 @@ public class Lower extends TreeTranslator { * @param lhs The operator's left argument. * @param rhs The operator's right argument. */ - JCBinary makeBinary(int optag, JCExpression lhs, JCExpression rhs) { + JCBinary makeBinary(JCTree.Tag optag, JCExpression lhs, JCExpression rhs) { JCBinary tree = make.Binary(optag, lhs, rhs); tree.operator = rs.resolveBinaryOperator( make_pos, optag, attrEnv, lhs.type, rhs.type); @@ -534,10 +536,10 @@ public class Lower extends TreeTranslator { * @param lhs The operator's left argument. * @param rhs The operator's right argument. */ - JCAssignOp makeAssignop(int optag, JCTree lhs, JCTree rhs) { + JCAssignOp makeAssignop(JCTree.Tag optag, JCTree lhs, JCTree rhs) { JCAssignOp tree = make.Assignop(optag, lhs, rhs); tree.operator = rs.resolveBinaryOperator( - make_pos, tree.getTag() - JCTree.ASGOffset, attrEnv, lhs.type, rhs.type); + make_pos, tree.getTag().noAssignOp(), attrEnv, lhs.type, rhs.type); tree.type = lhs.type; return tree; } @@ -720,7 +722,7 @@ public class Lower extends TreeTranslator { // where private boolean isTranslatedClassAvailable(ClassSymbol c) { for (JCTree tree: translated) { - if (tree.getTag() == JCTree.CLASSDEF + if (tree.hasTag(CLASSDEF) && ((JCClassDecl) tree).sym == c) { return true; } @@ -802,13 +804,13 @@ public class Lower extends TreeTranslator { private static int accessCode(JCTree tree, JCTree enclOp) { if (enclOp == null) return DEREFcode; - else if (enclOp.getTag() == JCTree.ASSIGN && + else if (enclOp.hasTag(ASSIGN) && tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs)) return ASSIGNcode; - else if (JCTree.PREINC <= enclOp.getTag() && enclOp.getTag() <= JCTree.POSTDEC && + else if (enclOp.getTag().isIncOrDecUnaryOp() && tree == TreeInfo.skipParens(((JCUnary) enclOp).arg)) - return (enclOp.getTag() - JCTree.PREINC) * 2 + PREINCcode; - else if (JCTree.BITOR_ASG <= enclOp.getTag() && enclOp.getTag() <= JCTree.MOD_ASG && + return mapTagToUnaryOpCode(enclOp.getTag()); + else if (enclOp.getTag().isAssignop() && tree == TreeInfo.skipParens(((JCAssignOp) enclOp).lhs)) return accessCode(((OperatorSymbol) ((JCAssignOp) enclOp).operator).opcode); else @@ -832,39 +834,39 @@ public class Lower extends TreeTranslator { /** Return tree tag for assignment operation corresponding * to given binary operator. */ - private static int treeTag(OperatorSymbol operator) { + private static JCTree.Tag treeTag(OperatorSymbol operator) { switch (operator.opcode) { case ByteCodes.ior: case ByteCodes.lor: - return JCTree.BITOR_ASG; + return BITOR_ASG; case ByteCodes.ixor: case ByteCodes.lxor: - return JCTree.BITXOR_ASG; + return BITXOR_ASG; case ByteCodes.iand: case ByteCodes.land: - return JCTree.BITAND_ASG; + return BITAND_ASG; case ByteCodes.ishl: case ByteCodes.lshl: case ByteCodes.ishll: case ByteCodes.lshll: - return JCTree.SL_ASG; + return SL_ASG; case ByteCodes.ishr: case ByteCodes.lshr: case ByteCodes.ishrl: case ByteCodes.lshrl: - return JCTree.SR_ASG; + return SR_ASG; case ByteCodes.iushr: case ByteCodes.lushr: case ByteCodes.iushrl: case ByteCodes.lushrl: - return JCTree.USR_ASG; + return USR_ASG; case ByteCodes.iadd: case ByteCodes.ladd: case ByteCodes.fadd: case ByteCodes.dadd: case ByteCodes.string_add: - return JCTree.PLUS_ASG; + return PLUS_ASG; case ByteCodes.isub: case ByteCodes.lsub: case ByteCodes.fsub: case ByteCodes.dsub: - return JCTree.MINUS_ASG; + return MINUS_ASG; case ByteCodes.imul: case ByteCodes.lmul: case ByteCodes.fmul: case ByteCodes.dmul: - return JCTree.MUL_ASG; + return MUL_ASG; case ByteCodes.idiv: case ByteCodes.ldiv: case ByteCodes.fdiv: case ByteCodes.ddiv: - return JCTree.DIV_ASG; + return DIV_ASG; case ByteCodes.imod: case ByteCodes.lmod: case ByteCodes.fmod: case ByteCodes.dmod: - return JCTree.MOD_ASG; + return MOD_ASG; default: throw new AssertionError(); } @@ -1003,7 +1005,7 @@ public class Lower extends TreeTranslator { if (!currentClass.isSubClass(sym.owner, types)) return true; if ((sym.flags() & STATIC) != 0 || - tree.getTag() != JCTree.SELECT || + !tree.hasTag(SELECT) || TreeInfo.name(((JCFieldAccess) tree).selected) == names._super) return false; return !((JCFieldAccess) tree).selected.type.tsym.isSubClass(currentClass, types); @@ -1018,7 +1020,7 @@ public class Lower extends TreeTranslator { if (protAccess) { Symbol qualifier = null; ClassSymbol c = currentClass; - if (tree.getTag() == JCTree.SELECT && (sym.flags() & STATIC) == 0) { + if (tree.hasTag(SELECT) && (sym.flags() & STATIC) == 0) { qualifier = ((JCFieldAccess) tree).selected.type.tsym; while (!qualifier.isSubClass(c, types)) { c = c.owner.enclClass(); @@ -1058,7 +1060,7 @@ public class Lower extends TreeTranslator { Assert.check(sym != null && (sym.flags_field & FINAL) != 0); tree = make.at(tree.pos).Ident(sym); } - JCExpression base = (tree.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree).selected : null; + JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null; switch (sym.kind) { case TYP: if (sym.owner.kind != PCK) { @@ -1068,11 +1070,11 @@ public class Lower extends TreeTranslator { while (base != null && TreeInfo.symbol(base) != null && TreeInfo.symbol(base).kind != PCK) { - base = (base.getTag() == JCTree.SELECT) + base = (base.hasTag(SELECT)) ? ((JCFieldAccess) base).selected : null; } - if (tree.getTag() == JCTree.IDENT) { + if (tree.hasTag(IDENT)) { ((JCIdent) tree).name = flatname; } else if (base == null) { tree = make.at(tree.pos).Ident(sym); @@ -1220,6 +1222,42 @@ public class Lower extends TreeTranslator { } } + /** Maps unary operator integer codes to JCTree.Tag objects + * @param unaryOpCode the unary operator code + */ + private static Tag mapUnaryOpCodeToTag(int unaryOpCode){ + switch (unaryOpCode){ + case PREINCcode: + return PREINC; + case PREDECcode: + return PREDEC; + case POSTINCcode: + return POSTINC; + case POSTDECcode: + return POSTDEC; + default: + return NO_TAG; + } + } + + /** Maps JCTree.Tag objects to unary operator integer codes + * @param tag the JCTree.Tag + */ + private static int mapTagToUnaryOpCode(Tag tag){ + switch (tag){ + case PREINC: + return PREINCcode; + case PREDEC: + return PREDECcode; + case POSTINC: + return POSTINCcode; + case POSTDEC: + return POSTDECcode; + default: + return -1; + } + } + /** Construct definition of an access method. * @param pos The source code position of the definition. * @param vsym The private or protected symbol. @@ -1259,8 +1297,7 @@ public class Lower extends TreeTranslator { expr = make.Assign(ref, args.head); break; case PREINCcode: case POSTINCcode: case PREDECcode: case POSTDECcode: - expr = makeUnary( - ((acode1 - PREINCcode) >> 1) + JCTree.PREINC, ref); + expr = makeUnary(mapUnaryOpCodeToTag(acode1), ref); break; default: expr = make.Assignop( @@ -1576,7 +1613,7 @@ public class Lower extends TreeTranslator { } private JCExpression makeNonNullCheck(JCExpression expression) { - return makeBinary(JCTree.NE, expression, makeNull()); + return makeBinary(NE, expression, makeNull()); } /** Construct a tree that represents the outer instance @@ -1808,7 +1845,7 @@ public class Lower extends TreeTranslator { // $newcache.getClass().getComponentType().getClassLoader() : cl$" JCExpression clvalue = make.Conditional( - makeBinary(JCTree.EQ, make.Ident(clsym), makeNull()), + makeBinary(EQ, make.Ident(clsym), makeNull()), make.Assign( make.Ident(clsym), makeCall( @@ -1976,7 +2013,7 @@ public class Lower extends TreeTranslator { writer.xClassName(type).toString().replace('/', '.'); Symbol cs = cacheSym(pos, sig); return make_at(pos).Conditional( - makeBinary(JCTree.EQ, make.Ident(cs), makeNull()), + makeBinary(EQ, make.Ident(cs), makeNull()), make.Assign( make.Ident(cs), make.App( @@ -2023,7 +2060,7 @@ public class Lower extends TreeTranslator { List.nil()); JCClassDecl containerDef = classDef(container); make_at(containerDef.pos()); - JCExpression notStatus = makeUnary(JCTree.NOT, make.App(make.Select( + JCExpression notStatus = makeUnary(NOT, make.App(make.Select( classOfType(types.erasure(outermostClass.type), containerDef.pos()), desiredAssertionStatusSym))); @@ -2032,7 +2069,7 @@ public class Lower extends TreeTranslator { containerDef.defs = containerDef.defs.prepend(assertDisabledDef); } make_at(pos); - return makeUnary(JCTree.NOT, make.Ident(assertDisabledSym)); + return makeUnary(NOT, make.Ident(assertDisabledSym)); } @@ -2062,9 +2099,9 @@ public class Lower extends TreeTranslator { JCTree abstractRval(JCTree rval, Type type, TreeBuilder builder) { rval = TreeInfo.skipParens(rval); switch (rval.getTag()) { - case JCTree.LITERAL: + case LITERAL: return builder.build(rval); - case JCTree.IDENT: + case IDENT: JCIdent id = (JCIdent) rval; if ((id.sym.flags() & FINAL) != 0 && id.sym.owner.kind == MTH) return builder.build(rval); @@ -2097,9 +2134,9 @@ public class Lower extends TreeTranslator { JCTree abstractLval(JCTree lval, final TreeBuilder builder) { lval = TreeInfo.skipParens(lval); switch (lval.getTag()) { - case JCTree.IDENT: + case IDENT: return builder.build(lval); - case JCTree.SELECT: { + case SELECT: { final JCFieldAccess s = (JCFieldAccess)lval; JCTree selected = TreeInfo.skipParens(s.selected); Symbol lid = TreeInfo.symbol(s.selected); @@ -2110,7 +2147,7 @@ public class Lower extends TreeTranslator { } }); } - case JCTree.INDEXED: { + case INDEXED: { final JCArrayAccess i = (JCArrayAccess)lval; return abstractRval(i.indexed, new TreeBuilder() { public JCTree build(final JCTree indexed) { @@ -2125,7 +2162,7 @@ public class Lower extends TreeTranslator { } }); } - case JCTree.TYPECAST: { + case TYPECAST: { return abstractLval(((JCTypeCast)lval).expr, builder); } } @@ -2345,7 +2382,7 @@ public class Lower extends TreeTranslator { for (List defs = tree.defs; defs.nonEmpty(); defs=defs.tail) { - if (defs.head.getTag() == JCTree.VARDEF && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) { + if (defs.head.hasTag(VARDEF) && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) { JCVariableDecl var = (JCVariableDecl)defs.head; visitEnumConstantDef(var, nextOrdinal++); values.append(make.QualIdent(var.sym)); @@ -2757,9 +2794,9 @@ public class Lower extends TreeTranslator { List.nil() : List.of(translate(tree.detail)); if (!tree.cond.type.isFalse()) { cond = makeBinary - (JCTree.AND, + (AND, cond, - makeUnary(JCTree.NOT, tree.cond)); + makeUnary(NOT, tree.cond)); } result = make.If(cond, @@ -2816,7 +2853,7 @@ public class Lower extends TreeTranslator { // first argument. if (c.hasOuterInstance()) { JCExpression thisArg; - if (tree.meth.getTag() == JCTree.SELECT) { + if (tree.meth.hasTag(SELECT)) { thisArg = attr. makeNullCheck(translate(((JCFieldAccess) tree.meth).selected)); tree.meth = make.Ident(constructor); @@ -2837,7 +2874,7 @@ public class Lower extends TreeTranslator { // If the translated method itself is an Apply tree, we are // seeing an access method invocation. In this case, append // the method arguments to the arguments of the access method. - if (tree.meth.getTag() == JCTree.APPLY) { + if (tree.meth.hasTag(APPLY)) { JCMethodInvocation app = (JCMethodInvocation)tree.meth; app.args = tree.args.prependList(app.args); result = app; @@ -2971,7 +3008,7 @@ public class Lower extends TreeTranslator { // If translated left hand side is an Apply, we are // seeing an access method invocation. In this case, append // right hand side as last argument of the access method. - if (tree.lhs.getTag() == JCTree.APPLY) { + if (tree.lhs.hasTag(APPLY)) { JCMethodInvocation app = (JCMethodInvocation)tree.lhs; app.args = List.of(tree.rhs).prependList(app.args); result = app; @@ -2988,7 +3025,7 @@ public class Lower extends TreeTranslator { // (but without recomputing x) JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() { public JCTree build(final JCTree lhs) { - int newTag = tree.getTag() - JCTree.ASGOffset; + JCTree.Tag newTag = tree.getTag().noAssignOp(); // Erasure (TransTypes) can change the type of // tree.lhs. However, we can still get the // unerased type of tree.lhs as it is stored @@ -3018,7 +3055,7 @@ public class Lower extends TreeTranslator { // If translated left hand side is an Apply, we are // seeing an access method invocation. In this case, append // right hand side as last argument of the access method. - if (tree.lhs.getTag() == JCTree.APPLY) { + if (tree.lhs.hasTag(APPLY)) { JCMethodInvocation app = (JCMethodInvocation)tree.lhs; // if operation is a += on strings, // make sure to convert argument to string @@ -3038,13 +3075,13 @@ public class Lower extends TreeTranslator { // or // translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2 // where OP is += or -= - final boolean cast = TreeInfo.skipParens(tree.arg).getTag() == JCTree.TYPECAST; + final boolean cast = TreeInfo.skipParens(tree.arg).hasTag(TYPECAST); return abstractLval(tree.arg, new TreeBuilder() { public JCTree build(final JCTree tmp1) { return abstractRval(tmp1, tree.arg.type, new TreeBuilder() { public JCTree build(final JCTree tmp2) { - int opcode = (tree.getTag() == JCTree.POSTINC) - ? JCTree.PLUS_ASG : JCTree.MINUS_ASG; + JCTree.Tag opcode = (tree.hasTag(POSTINC)) + ? PLUS_ASG : MINUS_ASG; JCTree lhs = cast ? make.TypeCast(tree.arg.type, (JCExpression)tmp1) : tmp1; @@ -3059,25 +3096,24 @@ public class Lower extends TreeTranslator { } public void visitUnary(JCUnary tree) { - boolean isUpdateOperator = - JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC; + boolean isUpdateOperator = tree.getTag().isIncOrDecUnaryOp(); if (isUpdateOperator && !tree.arg.type.isPrimitive()) { switch(tree.getTag()) { - case JCTree.PREINC: // ++ e + case PREINC: // ++ e // translate to e += 1 - case JCTree.PREDEC: // -- e + case PREDEC: // -- e // translate to e -= 1 { - int opcode = (tree.getTag() == JCTree.PREINC) - ? JCTree.PLUS_ASG : JCTree.MINUS_ASG; + JCTree.Tag opcode = (tree.hasTag(PREINC)) + ? PLUS_ASG : MINUS_ASG; JCAssignOp newTree = makeAssignop(opcode, tree.arg, make.Literal(1)); result = translate(newTree, tree.type); return; } - case JCTree.POSTINC: // e ++ - case JCTree.POSTDEC: // e -- + case POSTINC: // e ++ + case POSTDEC: // e -- { result = translate(lowerBoxedPostop(tree), tree.type); return; @@ -3088,14 +3124,14 @@ public class Lower extends TreeTranslator { tree.arg = boxIfNeeded(translate(tree.arg, tree), tree.type); - if (tree.getTag() == JCTree.NOT && tree.arg.type.constValue() != null) { + if (tree.hasTag(NOT) && tree.arg.type.constValue() != null) { tree.type = cfolder.fold1(bool_not, tree.arg.type); } // If translated left hand side is an Apply, we are // seeing an access method invocation. In this case, return // that access method invocation as result. - if (isUpdateOperator && tree.arg.getTag() == JCTree.APPLY) { + if (isUpdateOperator && tree.arg.hasTag(APPLY)) { result = tree.arg; } else { result = tree; @@ -3106,7 +3142,7 @@ public class Lower extends TreeTranslator { List formals = tree.operator.type.getParameterTypes(); JCTree lhs = tree.lhs = translate(tree.lhs, formals.head); switch (tree.getTag()) { - case JCTree.OR: + case OR: if (lhs.type.isTrue()) { result = lhs; return; @@ -3116,7 +3152,7 @@ public class Lower extends TreeTranslator { return; } break; - case JCTree.AND: + case AND: if (lhs.type.isFalse()) { result = lhs; return; @@ -3186,9 +3222,9 @@ public class Lower extends TreeTranslator { indexdef.init.type = indexdef.type = syms.intType.constType(0); List loopinit = List.of(arraycachedef, lencachedef, indexdef); - JCBinary cond = makeBinary(JCTree.LT, make.Ident(index), make.Ident(lencache)); + JCBinary cond = makeBinary(LT, make.Ident(index), make.Ident(lencache)); - JCExpressionStatement step = make.Exec(makeUnary(JCTree.PREINC, make.Ident(index))); + JCExpressionStatement step = make.Exec(makeUnary(PREINC, make.Ident(index))); Type elemtype = types.elemtype(tree.expr.type); JCExpression loopvarinit = make.Indexed(make.Ident(arraycache), @@ -3592,7 +3628,7 @@ public class Lower extends TreeTranslator { // need to special case-access of the form C.super.x // these will always need an access method. boolean qualifiedSuperAccess = - tree.selected.getTag() == JCTree.SELECT && + tree.selected.hasTag(SELECT) && TreeInfo.name(tree.selected) == names._super; tree.selected = translate(tree.selected); if (tree.name == names._class) @@ -3642,7 +3678,7 @@ public class Lower extends TreeTranslator { endPositions = env.toplevel.endPositions; currentClass = null; currentMethodDef = null; - outermostClassDef = (cdef.getTag() == JCTree.CLASSDEF) ? (JCClassDecl)cdef : null; + outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null; outermostMemberDef = null; this.translated = new ListBuffer(); classdefs = new HashMap(); @@ -3838,7 +3874,7 @@ public class Lower extends TreeTranslator { JCIdent fLocUsageId = make.Ident(otherVarSym); JCExpression sel = make.Select(fLocUsageId, ordinalSymbol); - JCBinary bin = makeBinary(JCTree.MINUS, id1, sel); + JCBinary bin = makeBinary(MINUS, id1, sel); JCReturn ret = make.Return(bin); blockStatements.append(ret); JCMethodDecl compareToMethod = make.MethodDef((MethodSymbol)compareToSym, diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index d7583989614..a30c97b9120 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -40,8 +40,10 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Flags.ANNOTATION; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; /** This is the second phase of Enter, in which classes are completed @@ -644,7 +646,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { tree.sym = v; if (tree.init != null) { v.flags_field |= HASINIT; - if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) { + if ((v.flags_field & FINAL) != 0 && !tree.init.hasTag(NEWCLASS)) { Env initEnv = getInitEnv(tree, env); initEnv.info.enclVar = v; v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init); @@ -868,7 +870,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { // If this is a toplevel-class, make sure any preceding import // clauses have been seen. if (c.owner.kind == PCK) { - memberEnter(env.toplevel, env.enclosing(JCTree.TOPLEVEL)); + memberEnter(env.toplevel, env.enclosing(TOPLEVEL)); todo.append(env); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 3d6374dbaf1..bb7a5351a9e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -49,9 +49,12 @@ import java.util.Set; import javax.lang.model.element.ElementVisitor; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Kinds.*; +import static com.sun.tools.javac.code.Kinds.ERRONEOUS; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** Helper class for name resolution, used mostly by the attribution phase. * @@ -1269,7 +1272,7 @@ public class Resolve { staticOnly = true; } - if (env.tree.getTag() != JCTree.IMPORT) { + if (!env.tree.hasTag(IMPORT)) { sym = findGlobalType(env, env.toplevel.namedImportScope, name); if (sym.exists()) return sym; else if (sym.kind < bestSoFar.kind) bestSoFar = sym; @@ -1796,7 +1799,7 @@ public class Resolve { * @param env The environment current at the operation. * @param argtypes The types of the operands. */ - Symbol resolveOperator(DiagnosticPosition pos, int optag, + Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, Env env, List argtypes) { startResolution(); Name name = treeinfo.operatorName(optag); @@ -1815,7 +1818,7 @@ public class Resolve { * @param env The environment current at the operation. * @param arg The type of the operand. */ - Symbol resolveUnaryOperator(DiagnosticPosition pos, int optag, Env env, Type arg) { + Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env env, Type arg) { return resolveOperator(pos, optag, env, List.of(arg)); } @@ -1827,7 +1830,7 @@ public class Resolve { * @param right The types of the right operand. */ Symbol resolveBinaryOperator(DiagnosticPosition pos, - int optag, + JCTree.Tag optag, Env env, Type left, Type right) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java index a2c1edc9735..92c02113f25 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java @@ -532,7 +532,7 @@ implements CRTFlags { */ public int endPos(JCTree tree) { if (tree == null) return Position.NOPOS; - if (tree.getTag() == JCTree.BLOCK) + if (tree.hasTag(JCTree.Tag.BLOCK)) return ((JCBlock) tree).endpos; Integer endpos = endPositions.get(tree); if (endpos != null) diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index f1a2a71f2d6..9b745c33305 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -47,6 +47,8 @@ import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.jvm.CRTFlags.*; import static com.sun.tools.javac.main.OptionName.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; +import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK; /** This pass maps flat Java (i.e. without inner classes) to bytecodes. * @@ -433,7 +435,7 @@ public class Gen extends JCTree.Visitor { */ boolean hasFinally(JCTree target, Env env) { while (env.tree != target) { - if (env.tree.getTag() == JCTree.TRY && env.info.finalize.hasFinalizer()) + if (env.tree.hasTag(TRY) && env.info.finalize.hasFinalizer()) return true; env = env.next; } @@ -460,17 +462,17 @@ public class Gen extends JCTree.Visitor { for (List l = defs; l.nonEmpty(); l = l.tail) { JCTree def = l.head; switch (def.getTag()) { - case JCTree.BLOCK: + case BLOCK: JCBlock block = (JCBlock)def; if ((block.flags & STATIC) != 0) clinitCode.append(block); else initCode.append(block); break; - case JCTree.METHODDEF: + case METHODDEF: methodDefs.append(def); break; - case JCTree.VARDEF: + case VARDEF: JCVariableDecl vdef = (JCVariableDecl) def; VarSymbol sym = vdef.sym; checkDimension(vdef.pos(), sym.type); @@ -707,7 +709,7 @@ public class Gen extends JCTree.Visitor { } int startpc = code.curPc(); genStat(tree, env); - if (tree.getTag() == JCTree.BLOCK) crtFlags |= CRT_BLOCK; + if (tree.hasTag(BLOCK)) crtFlags |= CRT_BLOCK; code.crt.put(tree, crtFlags, startpc, code.curPc()); } @@ -717,7 +719,7 @@ public class Gen extends JCTree.Visitor { if (code.isAlive()) { code.statBegin(tree.pos); genDef(tree, env); - } else if (env.info.isSwitch && tree.getTag() == JCTree.VARDEF) { + } else if (env.info.isSwitch && tree.hasTag(VARDEF)) { // variables whose declarations are in a switch // can be used even if the decl is unreachable. code.newLocal(((JCVariableDecl) tree).sym); @@ -784,7 +786,7 @@ public class Gen extends JCTree.Visitor { */ public CondItem genCond(JCTree _tree, boolean markBranches) { JCTree inner_tree = TreeInfo.skipParens(_tree); - if (inner_tree.getTag() == JCTree.CONDEXPR) { + if (inner_tree.hasTag(CONDEXPR)) { JCConditional tree = (JCConditional)inner_tree; CondItem cond = genCond(tree.cond, CRT_FLOW_CONTROLLER); if (cond.isTrue()) { @@ -1033,7 +1035,7 @@ public class Gen extends JCTree.Visitor { Env localEnv = env.dup(tree, new GenContext()); genStats(tree.stats, localEnv); // End the scope of all block-local variables in variable info. - if (env.tree.getTag() != JCTree.METHODDEF) { + if (!env.tree.hasTag(METHODDEF)) { code.statBegin(tree.endpos); code.endScopes(limit); code.pendingStatPos = Position.NOPOS; @@ -1628,11 +1630,11 @@ public class Gen extends JCTree.Visitor { // Optimize x++ to ++x and x-- to --x. JCExpression e = tree.expr; switch (e.getTag()) { - case JCTree.POSTINC: - ((JCUnary) e).setTag(JCTree.PREINC); + case POSTINC: + ((JCUnary) e).setTag(PREINC); break; - case JCTree.POSTDEC: - ((JCUnary) e).setTag(JCTree.PREDEC); + case POSTDEC: + ((JCUnary) e).setTag(PREDEC); break; } genExpr(tree.expr, tree.expr.type).drop(); @@ -1819,13 +1821,13 @@ public class Gen extends JCTree.Visitor { // If we have an increment of -32768 to +32767 of a local // int variable we can use an incr instruction instead of // proceeding further. - if ((tree.getTag() == JCTree.PLUS_ASG || tree.getTag() == JCTree.MINUS_ASG) && + if ((tree.hasTag(PLUS_ASG) || tree.hasTag(MINUS_ASG)) && l instanceof LocalItem && tree.lhs.type.tag <= INT && tree.rhs.type.tag <= INT && tree.rhs.type.constValue() != null) { int ival = ((Number) tree.rhs.type.constValue()).intValue(); - if (tree.getTag() == JCTree.MINUS_ASG) ival = -ival; + if (tree.hasTag(MINUS_ASG)) ival = -ival; ((LocalItem)l).incr(ival); result = l; return; @@ -1841,29 +1843,29 @@ public class Gen extends JCTree.Visitor { public void visitUnary(JCUnary tree) { OperatorSymbol operator = (OperatorSymbol)tree.operator; - if (tree.getTag() == JCTree.NOT) { + if (tree.hasTag(NOT)) { CondItem od = genCond(tree.arg, false); result = od.negate(); } else { Item od = genExpr(tree.arg, operator.type.getParameterTypes().head); switch (tree.getTag()) { - case JCTree.POS: + case POS: result = od.load(); break; - case JCTree.NEG: + case NEG: result = od.load(); code.emitop0(operator.opcode); break; - case JCTree.COMPL: + case COMPL: result = od.load(); emitMinusOne(od.typecode); code.emitop0(operator.opcode); break; - case JCTree.PREINC: case JCTree.PREDEC: + case PREINC: case PREDEC: od.duplicate(); if (od instanceof LocalItem && (operator.opcode == iadd || operator.opcode == isub)) { - ((LocalItem)od).incr(tree.getTag() == JCTree.PREINC ? 1 : -1); + ((LocalItem)od).incr(tree.hasTag(PREINC) ? 1 : -1); result = od; } else { od.load(); @@ -1877,12 +1879,12 @@ public class Gen extends JCTree.Visitor { result = items.makeAssignItem(od); } break; - case JCTree.POSTINC: case JCTree.POSTDEC: + case POSTINC: case POSTDEC: od.duplicate(); if (od instanceof LocalItem && (operator.opcode == iadd || operator.opcode == isub)) { Item res = od.load(); - ((LocalItem)od).incr(tree.getTag() == JCTree.POSTINC ? 1 : -1); + ((LocalItem)od).incr(tree.hasTag(POSTINC) ? 1 : -1); result = res; } else { Item res = od.load(); @@ -1898,7 +1900,7 @@ public class Gen extends JCTree.Visitor { result = res; } break; - case JCTree.NULLCHK: + case NULLCHK: result = od.load(); code.emitop0(dup); genNullCheck(tree.pos()); @@ -1926,7 +1928,7 @@ public class Gen extends JCTree.Visitor { // Convert buffer to string. bufferToString(tree.pos()); result = items.makeStackItem(syms.stringType); - } else if (tree.getTag() == JCTree.AND) { + } else if (tree.hasTag(AND)) { CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER); if (!lcond.isFalse()) { Chain falseJumps = lcond.jumpFalse(); @@ -1940,7 +1942,7 @@ public class Gen extends JCTree.Visitor { } else { result = lcond; } - } else if (tree.getTag() == JCTree.OR) { + } else if (tree.hasTag(OR)) { CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER); if (!lcond.isTrue()) { Chain trueJumps = lcond.jumpTrue(); @@ -1997,7 +1999,7 @@ public class Gen extends JCTree.Visitor { */ void appendStrings(JCTree tree) { tree = TreeInfo.skipParens(tree); - if (tree.getTag() == JCTree.PLUS && tree.type.constValue() == null) { + if (tree.hasTag(PLUS) && tree.type.constValue() == null) { JCBinary op = (JCBinary) tree; if (op.operator.kind == MTH && ((OperatorSymbol) op.operator).opcode == string_add) { @@ -2240,7 +2242,7 @@ public class Gen extends JCTree.Visitor { if (nerrs != 0) { // if errors, discard code for (List l = cdef.defs; l.nonEmpty(); l = l.tail) { - if (l.head.getTag() == JCTree.METHODDEF) + if (l.head.hasTag(METHODDEF)) ((JCMethodDecl) l.head).sym.code = null; } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index a1190b08909..232419d0231 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1506,20 +1506,20 @@ public class JavaCompiler implements ClassReader.SourceCompleter { for (List it = tree.defs; it.tail != null; it = it.tail) { JCTree t = it.head; switch (t.getTag()) { - case JCTree.CLASSDEF: + case CLASSDEF: if (isInterface || (((JCClassDecl) t).mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 || (((JCClassDecl) t).mods.flags & (Flags.PRIVATE)) == 0 && ((JCClassDecl) t).sym.packge().getQualifiedName() == names.java_lang) newdefs.append(t); break; - case JCTree.METHODDEF: + case METHODDEF: if (isInterface || (((JCMethodDecl) t).mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 || ((JCMethodDecl) t).sym.name == names.init || (((JCMethodDecl) t).mods.flags & (Flags.PRIVATE)) == 0 && ((JCMethodDecl) t).sym.packge().getQualifiedName() == names.java_lang) newdefs.append(t); break; - case JCTree.VARDEF: + case VARDEF: if (isInterface || (((JCVariableDecl) t).mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 || (((JCVariableDecl) t).mods.flags & (Flags.PRIVATE)) == 0 && ((JCVariableDecl) t).sym.packge().getQualifiedName() == names.java_lang) newdefs.append(t); diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java index c00a3728d4a..cb9c1650863 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,7 @@ import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.Name; +import static com.sun.tools.javac.tree.JCTree.Tag.*; import static javax.lang.model.util.ElementFilter.methodsIn; /** @@ -288,7 +289,7 @@ public class JavacElements implements Elements { } } public void visitArray(Attribute.Array array) { - if (tree.getTag() == JCTree.NEWARRAY && + if (tree.hasTag(NEWARRAY) && types.elemtype(array.type).tsym == findme.type.tsym) { List elems = ((JCNewArray) tree).elems; for (Attribute value : array.values) { @@ -327,7 +328,7 @@ public class JavacElements implements Elements { scan(t.args); } public void visitAssign(JCAssign t) { - if (t.lhs.getTag() == JCTree.IDENT) { + if (t.lhs.hasTag(IDENT)) { JCIdent ident = (JCIdent) t.lhs; if (ident.sym == sym) result = t.rhs; diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java index f5a99ae9fa4..f9ce7a251de 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java @@ -25,10 +25,11 @@ package com.sun.tools.javac.parser; -import java.nio.CharBuffer; import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.util.*; +import java.nio.CharBuffer; import static com.sun.tools.javac.parser.Tokens.*; import static com.sun.tools.javac.util.LayoutCharacters.*; @@ -65,9 +66,6 @@ public class JavaTokenizer { */ private final Log log; - /** The name table. */ - private final Names names; - /** The token factory. */ private final Tokens tokens; @@ -87,18 +85,12 @@ public class JavaTokenizer { */ protected int errPos = Position.NOPOS; - /** Has a @deprecated been encountered in last doc comment? - * this needs to be reset by client. + /** The Unicode reader (low-level stream reader). */ - protected boolean deprecatedFlag = false; - - /** A character buffer for saved chars. - */ - protected char[] sbuf = new char[128]; - protected int sp; - protected UnicodeReader reader; + protected ScannerFactory fac; + private static final boolean hexFloatsWork = hexFloatsWork(); private static boolean hexFloatsWork() { try { @@ -129,14 +121,14 @@ public class JavaTokenizer { } protected JavaTokenizer(ScannerFactory fac, UnicodeReader reader) { - log = fac.log; - names = fac.names; - tokens = fac.tokens; - source = fac.source; + this.fac = fac; + this.log = fac.log; + this.tokens = fac.tokens; + this.source = fac.source; this.reader = reader; - allowBinaryLiterals = source.allowBinaryLiterals(); - allowHexFloats = source.allowHexFloats(); - allowUnderscoresInLiterals = source.allowUnderscoresInLiterals(); + this.allowBinaryLiterals = source.allowBinaryLiterals(); + this.allowHexFloats = source.allowHexFloats(); + this.allowUnderscoresInLiterals = source.allowUnderscoresInLiterals(); } /** Report an error at the given position using the provided arguments. @@ -147,38 +139,13 @@ public class JavaTokenizer { errPos = pos; } - /** Read next character in comment, skipping over double '\' characters. - */ - protected void scanCommentChar() { - reader.scanChar(); - if (reader.ch == '\\') { - if (reader.peekChar() == '\\' && !reader.isUnicode()) { - reader.skipChar(); - } else { - reader.convertUnicode(); - } - } - } - - /** Append a character to sbuf. - */ - private void putChar(char ch) { - if (sp == sbuf.length) { - char[] newsbuf = new char[sbuf.length * 2]; - System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); - sbuf = newsbuf; - } - sbuf[sp++] = ch; - } - /** Read next character in character or string literal and copy into sbuf. */ private void scanLitChar(int pos) { if (reader.ch == '\\') { if (reader.peekChar() == '\\' && !reader.isUnicode()) { reader.skipChar(); - putChar('\\'); - reader.scanChar(); + reader.putChar('\\', true); } else { reader.scanChar(); switch (reader.ch) { @@ -195,30 +162,30 @@ public class JavaTokenizer { reader.scanChar(); } } - putChar((char)oct); + reader.putChar((char)oct); break; case 'b': - putChar('\b'); reader.scanChar(); break; + reader.putChar('\b', true); break; case 't': - putChar('\t'); reader.scanChar(); break; + reader.putChar('\t', true); break; case 'n': - putChar('\n'); reader.scanChar(); break; + reader.putChar('\n', true); break; case 'f': - putChar('\f'); reader.scanChar(); break; + reader.putChar('\f', true); break; case 'r': - putChar('\r'); reader.scanChar(); break; + reader.putChar('\r', true); break; case '\'': - putChar('\''); reader.scanChar(); break; + reader.putChar('\'', true); break; case '\"': - putChar('\"'); reader.scanChar(); break; + reader.putChar('\"', true); break; case '\\': - putChar('\\'); reader.scanChar(); break; + reader.putChar('\\', true); break; default: lexError(reader.bp, "illegal.esc.char"); } } } else if (reader.bp != reader.buflen) { - putChar(reader.ch); reader.scanChar(); + reader.putChar(true); } } @@ -227,7 +194,7 @@ public class JavaTokenizer { int savePos; do { if (reader.ch != '_') { - putChar(reader.ch); + reader.putChar(false); } else { if (!allowUnderscoresInLiterals) { lexError(pos, "unsupported.underscore.lit", source.name); @@ -246,12 +213,10 @@ public class JavaTokenizer { */ private void scanHexExponentAndSuffix(int pos) { if (reader.ch == 'p' || reader.ch == 'P') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); skipIllegalUnderscores(); if (reader.ch == '+' || reader.ch == '-') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); } skipIllegalUnderscores(); if ('0' <= reader.ch && reader.ch <= '9') { @@ -268,14 +233,12 @@ public class JavaTokenizer { lexError(pos, "malformed.fp.lit"); } if (reader.ch == 'f' || reader.ch == 'F') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); tk = TokenKind.FLOATLITERAL; radix = 16; } else { if (reader.ch == 'd' || reader.ch == 'D') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); } tk = TokenKind.DOUBLELITERAL; radix = 16; @@ -289,14 +252,12 @@ public class JavaTokenizer { if ('0' <= reader.ch && reader.ch <= '9') { scanDigits(pos, 10); } - int sp1 = sp; + int sp1 = reader.sp; if (reader.ch == 'e' || reader.ch == 'E') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); skipIllegalUnderscores(); if (reader.ch == '+' || reader.ch == '-') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); } skipIllegalUnderscores(); if ('0' <= reader.ch && reader.ch <= '9') { @@ -304,7 +265,7 @@ public class JavaTokenizer { return; } lexError(pos, "malformed.fp.lit"); - sp = sp1; + reader.sp = sp1; } } @@ -314,13 +275,11 @@ public class JavaTokenizer { radix = 10; scanFraction(pos); if (reader.ch == 'f' || reader.ch == 'F') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); tk = TokenKind.FLOATLITERAL; } else { if (reader.ch == 'd' || reader.ch == 'D') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); } tk = TokenKind.DOUBLELITERAL; } @@ -331,8 +290,7 @@ public class JavaTokenizer { private void scanHexFractionAndSuffix(int pos, boolean seendigit) { radix = 16; Assert.check(reader.ch == '.'); - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); skipIllegalUnderscores(); if (reader.digit(pos, 16) >= 0) { seendigit = true; @@ -369,8 +327,7 @@ public class JavaTokenizer { } else if (seendigit && radix == 16 && (reader.ch == 'p' || reader.ch == 'P')) { scanHexExponentAndSuffix(pos); } else if (digitRadix == 10 && reader.ch == '.') { - putChar(reader.ch); - reader.scanChar(); + reader.putChar(true); scanFractionAndSuffix(pos); } else if (digitRadix == 10 && (reader.ch == 'e' || reader.ch == 'E' || @@ -393,10 +350,7 @@ public class JavaTokenizer { boolean isJavaIdentifierPart; char high; do { - if (sp == sbuf.length) putChar(reader.ch); else sbuf[sp++] = reader.ch; - // optimization, was: putChar(reader.ch); - - reader.scanChar(); + reader.putChar(true); switch (reader.ch) { case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': @@ -423,7 +377,7 @@ public class JavaTokenizer { break; case '\u001A': // EOI is also a legal identifier part if (reader.bp >= reader.buflen) { - name = names.fromChars(sbuf, 0, sp); + name = reader.name(); tk = tokens.lookupKind(name); return; } @@ -435,11 +389,7 @@ public class JavaTokenizer { } else { high = reader.scanSurrogates(); if (high != 0) { - if (sp == sbuf.length) { - putChar(high); - } else { - sbuf[sp++] = high; - } + reader.putChar(high); isJavaIdentifierPart = Character.isJavaIdentifierPart( Character.toCodePoint(high, reader.ch)); } else { @@ -447,7 +397,7 @@ public class JavaTokenizer { } } if (!isJavaIdentifierPart) { - name = names.fromChars(sbuf, 0, sp); + name = reader.name(); tk = tokens.lookupKind(name); return; } @@ -474,11 +424,11 @@ public class JavaTokenizer { */ private void scanOperator() { while (true) { - putChar(reader.ch); - Name newname = names.fromChars(sbuf, 0, sp); + reader.putChar(false); + Name newname = reader.name(); TokenKind tk1 = tokens.lookupKind(newname); if (tk1 == TokenKind.IDENTIFIER) { - sp--; + reader.sp--; break; } tk = tk1; @@ -487,111 +437,17 @@ public class JavaTokenizer { } } - /** - * Scan a documentation comment; determine if a deprecated tag is present. - * Called once the initial /, * have been skipped, positioned at the second * - * (which is treated as the beginning of the first line). - * Stops positioned at the closing '/'. - */ - @SuppressWarnings("fallthrough") - private void scanDocComment() { - boolean deprecatedPrefix = false; - - forEachLine: - while (reader.bp < reader.buflen) { - - // Skip optional WhiteSpace at beginning of line - while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) { - scanCommentChar(); - } - - // Skip optional consecutive Stars - while (reader.bp < reader.buflen && reader.ch == '*') { - scanCommentChar(); - if (reader.ch == '/') { - return; - } - } - - // Skip optional WhiteSpace after Stars - while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) { - scanCommentChar(); - } - - deprecatedPrefix = false; - // At beginning of line in the JavaDoc sense. - if (reader.bp < reader.buflen && reader.ch == '@' && !deprecatedFlag) { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'd') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'e') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'p') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'r') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'e') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'c') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'a') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 't') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'e') { - scanCommentChar(); - if (reader.bp < reader.buflen && reader.ch == 'd') { - deprecatedPrefix = true; - scanCommentChar(); - }}}}}}}}}}} - if (deprecatedPrefix && reader.bp < reader.buflen) { - if (Character.isWhitespace(reader.ch)) { - deprecatedFlag = true; - } else if (reader.ch == '*') { - scanCommentChar(); - if (reader.ch == '/') { - deprecatedFlag = true; - return; - } - } - } - - // Skip rest of line - while (reader.bp < reader.buflen) { - switch (reader.ch) { - case '*': - scanCommentChar(); - if (reader.ch == '/') { - return; - } - break; - case CR: // (Spec 3.4) - scanCommentChar(); - if (reader.ch != LF) { - continue forEachLine; - } - /* fall through to LF case */ - case LF: // (Spec 3.4) - scanCommentChar(); - continue forEachLine; - default: - scanCommentChar(); - } - } // rest of line - } // forEachLine - return; - } - /** Read token. */ public Token readToken() { - sp = 0; + reader.sp = 0; name = null; - deprecatedFlag = false; radix = 0; + int pos = 0; int endPos = 0; + List comments = null; try { loop: while (true) { @@ -656,7 +512,7 @@ public class JavaTokenizer { scanNumber(pos, 2); } } else { - putChar('0'); + reader.putChar('0'); if (reader.ch == '_') { int savePos = reader.bp; do { @@ -676,14 +532,13 @@ public class JavaTokenizer { case '.': reader.scanChar(); if ('0' <= reader.ch && reader.ch <= '9') { - putChar('.'); + reader.putChar('.'); scanFractionAndSuffix(pos); } else if (reader.ch == '.') { - putChar('.'); putChar('.'); - reader.scanChar(); + reader.putChar('.'); reader.putChar('.', true); if (reader.ch == '.') { reader.scanChar(); - putChar('.'); + reader.putChar('.'); tk = TokenKind.ELLIPSIS; } else { lexError(pos, "malformed.fp.lit"); @@ -712,32 +567,36 @@ public class JavaTokenizer { reader.scanChar(); if (reader.ch == '/') { do { - scanCommentChar(); + reader.scanCommentChar(); } while (reader.ch != CR && reader.ch != LF && reader.bp < reader.buflen); if (reader.bp < reader.buflen) { - processComment(pos, reader.bp, CommentStyle.LINE); + comments = addDocReader(comments, processComment(pos, reader.bp, CommentStyle.LINE)); } break; } else if (reader.ch == '*') { + boolean isEmpty = false; reader.scanChar(); CommentStyle style; if (reader.ch == '*') { style = CommentStyle.JAVADOC; - scanDocComment(); + reader.scanCommentChar(); + if (reader.ch == '/') { + isEmpty = true; + } } else { style = CommentStyle.BLOCK; - while (reader.bp < reader.buflen) { - if (reader.ch == '*') { - reader.scanChar(); - if (reader.ch == '/') break; - } else { - scanCommentChar(); - } + } + while (!isEmpty && reader.bp < reader.buflen) { + if (reader.ch == '*') { + reader.scanChar(); + if (reader.ch == '/') break; + } else { + reader.scanCommentChar(); } } if (reader.ch == '/') { reader.scanChar(); - processComment(pos, reader.bp, style); + comments = addDocReader(comments, processComment(pos, reader.bp, style)); break; } else { lexError(pos, "unclosed.comment"); @@ -789,11 +648,7 @@ public class JavaTokenizer { } else { char high = reader.scanSurrogates(); if (high != 0) { - if (sp == sbuf.length) { - putChar(high); - } else { - sbuf[sp++] = high; - } + reader.putChar(high); isJavaIdentifierStart = Character.isJavaIdentifierStart( Character.toCodePoint(high, reader.ch)); @@ -816,10 +671,10 @@ public class JavaTokenizer { } endPos = reader.bp; switch (tk.tag) { - case DEFAULT: return new Token(tk, pos, endPos, deprecatedFlag); - case NAMED: return new NamedToken(tk, pos, endPos, name, deprecatedFlag); - case STRING: return new StringToken(tk, pos, endPos, new String(sbuf, 0, sp), deprecatedFlag); - case NUMERIC: return new NumericToken(tk, pos, endPos, new String(sbuf, 0, sp), radix, deprecatedFlag); + case DEFAULT: return new Token(tk, pos, endPos, comments); + case NAMED: return new NamedToken(tk, pos, endPos, name, comments); + case STRING: return new StringToken(tk, pos, endPos, reader.chars(), comments); + case NUMERIC: return new NumericToken(tk, pos, endPos, reader.chars(), radix, comments); default: throw new AssertionError(); } } @@ -832,6 +687,12 @@ public class JavaTokenizer { } } } + //where + List addDocReader(List docReaders, Comment docReader) { + return docReaders == null ? + List.of(docReader) : + docReaders.prepend(docReader); + } /** Return the position where a lexical error occurred; */ @@ -845,22 +706,18 @@ public class JavaTokenizer { errPos = pos; } - public enum CommentStyle { - LINE, - BLOCK, - JAVADOC, - } - /** * Called when a complete comment has been scanned. pos and endPos * will mark the comment boundary. */ - protected void processComment(int pos, int endPos, CommentStyle style) { + protected Tokens.Comment processComment(int pos, int endPos, CommentStyle style) { if (scannerDebug) System.out.println("processComment(" + pos + "," + endPos + "," + style + ")=|" + new String(reader.getRawCharacters(pos, endPos)) + "|"); + char[] buf = reader.getRawCharacters(pos, endPos); + return new BasicComment(new UnicodeReader(fac, buf, buf.length), style); } /** @@ -893,4 +750,125 @@ public class JavaTokenizer { public Position.LineMap getLineMap() { return Position.makeLineMap(reader.getRawCharacters(), reader.buflen, false); } + + + /** + * Scan a documentation comment; determine if a deprecated tag is present. + * Called once the initial /, * have been skipped, positioned at the second * + * (which is treated as the beginning of the first line). + * Stops positioned at the closing '/'. + */ + protected class BasicComment implements Comment { + + CommentStyle cs; + U comment_reader; + + protected boolean deprecatedFlag = false; + protected boolean scanned = false; + + protected BasicComment(U comment_reader, CommentStyle cs) { + this.comment_reader = comment_reader; + this.cs = cs; + } + + public String getText() { + return null; + } + + public CommentStyle getStyle() { + return cs; + } + + public boolean isDeprecated() { + if (!scanned && cs == CommentStyle.JAVADOC) { + scanDocComment(); + } + return deprecatedFlag; + } + + @SuppressWarnings("fallthrough") + protected void scanDocComment() { + try { + boolean deprecatedPrefix = false; + + comment_reader.bp += 3; // '/**' + comment_reader.ch = comment_reader.buf[comment_reader.bp]; + + forEachLine: + while (comment_reader.bp < comment_reader.buflen) { + + // Skip optional WhiteSpace at beginning of line + while (comment_reader.bp < comment_reader.buflen && (comment_reader.ch == ' ' || comment_reader.ch == '\t' || comment_reader.ch == FF)) { + comment_reader.scanCommentChar(); + } + + // Skip optional consecutive Stars + while (comment_reader.bp < comment_reader.buflen && comment_reader.ch == '*') { + comment_reader.scanCommentChar(); + if (comment_reader.ch == '/') { + return; + } + } + + // Skip optional WhiteSpace after Stars + while (comment_reader.bp < comment_reader.buflen && (comment_reader.ch == ' ' || comment_reader.ch == '\t' || comment_reader.ch == FF)) { + comment_reader.scanCommentChar(); + } + + deprecatedPrefix = false; + // At beginning of line in the JavaDoc sense. + if (!deprecatedFlag) { + String deprecated = "@deprecated"; + int i = 0; + while (comment_reader.bp < comment_reader.buflen && comment_reader.ch == deprecated.charAt(i)) { + comment_reader.scanCommentChar(); + i++; + if (i == deprecated.length()) { + deprecatedPrefix = true; + break; + } + } + } + + if (deprecatedPrefix && comment_reader.bp < comment_reader.buflen) { + if (Character.isWhitespace(comment_reader.ch)) { + deprecatedFlag = true; + } else if (comment_reader.ch == '*') { + comment_reader.scanCommentChar(); + if (comment_reader.ch == '/') { + deprecatedFlag = true; + return; + } + } + } + + // Skip rest of line + while (comment_reader.bp < comment_reader.buflen) { + switch (comment_reader.ch) { + case '*': + comment_reader.scanCommentChar(); + if (comment_reader.ch == '/') { + return; + } + break; + case CR: // (Spec 3.4) + comment_reader.scanCommentChar(); + if (comment_reader.ch != LF) { + continue forEachLine; + } + /* fall through to LF case */ + case LF: // (Spec 3.4) + comment_reader.scanCommentChar(); + continue forEachLine; + default: + comment_reader.scanCommentChar(); + } + } // rest of line + } // forEachLine + return; + } finally { + scanned = true; + } + } + } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 9c754978a56..bbec01c8e7e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -29,6 +29,7 @@ import java.util.*; import com.sun.tools.javac.code.*; import com.sun.tools.javac.parser.Tokens.*; +import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.*; @@ -36,8 +37,16 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; -import static com.sun.tools.javac.util.ListBuffer.lb; import static com.sun.tools.javac.parser.Tokens.TokenKind.*; +import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT; +import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE; +import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH; +import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ; +import static com.sun.tools.javac.parser.Tokens.TokenKind.GT; +import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT; +import static com.sun.tools.javac.parser.Tokens.TokenKind.LT; +import static com.sun.tools.javac.util.ListBuffer.lb; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** The parser maps a token sequence into an abstract syntax * tree. It operates by recursive descent, with code derived @@ -757,7 +766,7 @@ public class JavacParser implements Parser { Assert.check(top == 0); t = odStack[0]; - if (t.getTag() == JCTree.PLUS) { + if (t.hasTag(JCTree.Tag.PLUS)) { StringBuffer buf = foldStrings(t); if (buf != null) { t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString())); @@ -790,7 +799,7 @@ public class JavacParser implements Parser { return null; List buf = List.nil(); while (true) { - if (tree.getTag() == JCTree.LITERAL) { + if (tree.hasTag(LITERAL)) { JCLiteral lit = (JCLiteral) tree; if (lit.typetag == TypeTags.CLASS) { StringBuffer sbuf = @@ -801,9 +810,9 @@ public class JavacParser implements Parser { } return sbuf; } - } else if (tree.getTag() == JCTree.PLUS) { + } else if (tree.hasTag(JCTree.Tag.PLUS)) { JCBinary op = (JCBinary)tree; - if (op.rhs.getTag() == JCTree.LITERAL) { + if (op.rhs.hasTag(LITERAL)) { JCLiteral lit = (JCLiteral) op.rhs; if (lit.typetag == TypeTags.CLASS) { buf = buf.prepend((String) lit.value); @@ -899,7 +908,7 @@ public class JavacParser implements Parser { t = term3(); if ((mode & TYPE) != 0 && token.kind == LT) { // Could be a cast to a parameterized type - int op = JCTree.LT; + JCTree.Tag op = JCTree.Tag.LT; int pos1 = token.pos; nextToken(); mode &= (EXPR | TYPE); @@ -1153,7 +1162,7 @@ public class JavacParser implements Parser { while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) { mode = EXPR; t = to(F.at(token.pos).Unary( - token.kind == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); + token.kind == PLUSPLUS ? POSTINC : POSTDEC, t)); nextToken(); } return toP(t); @@ -1584,7 +1593,7 @@ public class JavacParser implements Parser { break; case MONKEYS_AT: case FINAL: { - String dc = token.docComment; + String dc = token.comment(CommentStyle.JAVADOC); JCModifiers mods = modifiersOpt(); if (token.kind == INTERFACE || token.kind == CLASS || @@ -1601,21 +1610,21 @@ public class JavacParser implements Parser { break; } case ABSTRACT: case STRICTFP: { - String dc = token.docComment; + String dc = token.comment(CommentStyle.JAVADOC); JCModifiers mods = modifiersOpt(); stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); break; } case INTERFACE: case CLASS: - String dc = token.docComment; + String dc = token.comment(CommentStyle.JAVADOC); stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); break; case ENUM: case ASSERT: if (allowEnums && token.kind == ENUM) { error(token.pos, "local.enum"); - dc = token.docComment; + dc = token.comment(CommentStyle.JAVADOC); stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); break; } else if (allowAsserts && token.kind == ASSERT) { @@ -1626,7 +1635,7 @@ public class JavacParser implements Parser { default: Token prevToken = token; JCExpression t = term(EXPR | TYPE); - if (token.kind == COLON && t.getTag() == JCTree.IDENT) { + if (token.kind == COLON && t.hasTag(IDENT)) { nextToken(); JCStatement stat = parseStatement(); stats.append(F.at(pos).Labelled(prevToken.name(), stat)); @@ -1701,7 +1710,7 @@ public class JavacParser implements Parser { accept(LPAREN); List inits = token.kind == SEMI ? List.nil() : forInit(); if (inits.length() == 1 && - inits.head.getTag() == JCTree.VARDEF && + inits.head.hasTag(VARDEF) && ((JCVariableDecl) inits.head).init == null && token.kind == COLON) { checkForeach(); @@ -1834,7 +1843,7 @@ public class JavacParser implements Parser { default: Token prevToken = token; JCExpression expr = parseExpression(); - if (token.kind == COLON && expr.getTag() == JCTree.IDENT) { + if (token.kind == COLON && expr.hasTag(IDENT)) { nextToken(); JCStatement stat = parseStatement(); return F.at(pos).Labelled(prevToken.name(), stat); @@ -1991,7 +2000,7 @@ public class JavacParser implements Parser { annotations.appendList(partial.annotations); pos = partial.pos; } - if (token.deprecatedFlag) { + if (token.deprecatedFlag()) { flags |= Flags.DEPRECATED; } int lastPos = Position.NOPOS; @@ -2087,7 +2096,7 @@ public class JavacParser implements Parser { if (token.kind == IDENTIFIER) { mode = EXPR; JCExpression t1 = term1(); - if (t1.getTag() == JCTree.IDENT && token.kind == EQ) { + if (t1.hasTag(IDENT) && token.kind == EQ) { int pos = token.pos; accept(EQ); JCExpression v = annotationValue(); @@ -2271,9 +2280,9 @@ public class JavacParser implements Parser { seenImport = true; defs.append(importDeclaration()); } else { - String docComment = token.docComment; + String docComment = token.comment(CommentStyle.JAVADOC); if (firstTypeDecl && !seenImport && !seenPackage) { - docComment = firstToken.docComment; + docComment = firstToken.comment(CommentStyle.JAVADOC); consumedToplevelDoc = true; } JCTree def = typeDeclaration(mods, docComment); @@ -2288,7 +2297,7 @@ public class JavacParser implements Parser { } JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList()); if (!consumedToplevelDoc) - attach(toplevel, firstToken.docComment); + attach(toplevel, firstToken.comment(CommentStyle.JAVADOC)); if (defs.elems.isEmpty()) storeEnd(toplevel, S.prevToken().endPos); if (keepDocComments) @@ -2498,9 +2507,9 @@ public class JavacParser implements Parser { /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ] */ JCTree enumeratorDeclaration(Name enumName) { - String dc = token.docComment; + String dc = token.comment(CommentStyle.JAVADOC); int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM; - if (token.deprecatedFlag) { + if (token.deprecatedFlag()) { flags |= Flags.DEPRECATED; } int pos = token.pos; @@ -2587,7 +2596,7 @@ public class JavacParser implements Parser { nextToken(); return List.nil(); } else { - String dc = token.docComment; + String dc = token.comment(CommentStyle.JAVADOC); int pos = token.pos; JCModifiers mods = modifiersOpt(); if (token.kind == CLASS || @@ -2617,7 +2626,7 @@ public class JavacParser implements Parser { } else { type = parseType(); } - if (token.kind == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { + if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) error(pos, "invalid.meth.decl.ret.type.req"); return List.of(methodDeclaratorRest( @@ -2814,15 +2823,15 @@ public class JavacParser implements Parser { */ protected JCExpression checkExprStat(JCExpression t) { switch(t.getTag()) { - case JCTree.PREINC: case JCTree.PREDEC: - case JCTree.POSTINC: case JCTree.POSTDEC: - case JCTree.ASSIGN: - case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG: - case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG: - case JCTree.PLUS_ASG: case JCTree.MINUS_ASG: - case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG: - case JCTree.APPLY: case JCTree.NEWCLASS: - case JCTree.ERRONEOUS: + case PREINC: case PREDEC: + case POSTINC: case POSTDEC: + case ASSIGN: + case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG: + case SL_ASG: case SR_ASG: case USR_ASG: + case PLUS_ASG: case MINUS_ASG: + case MUL_ASG: case DIV_ASG: case MOD_ASG: + case APPLY: case NEWCLASS: + case ERRONEOUS: return t; default: JCExpression ret = F.at(t.pos).Erroneous(List.of(t)); @@ -2835,8 +2844,8 @@ public class JavacParser implements Parser { * -1 if token is not a binary operator. @see TreeInfo.opPrec */ static int prec(TokenKind token) { - int oc = optag(token); - return (oc >= 0) ? TreeInfo.opPrec(oc) : -1; + JCTree.Tag oc = optag(token); + return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1; } /** @@ -2852,96 +2861,96 @@ public class JavacParser implements Parser { } /** Return operation tag of binary operator represented by token, - * -1 if token is not a binary operator. + * No_TAG if token is not a binary operator. */ - static int optag(TokenKind token) { + static JCTree.Tag optag(TokenKind token) { switch (token) { case BARBAR: - return JCTree.OR; + return OR; case AMPAMP: - return JCTree.AND; + return AND; case BAR: - return JCTree.BITOR; + return BITOR; case BAREQ: - return JCTree.BITOR_ASG; + return BITOR_ASG; case CARET: - return JCTree.BITXOR; + return BITXOR; case CARETEQ: - return JCTree.BITXOR_ASG; + return BITXOR_ASG; case AMP: - return JCTree.BITAND; + return BITAND; case AMPEQ: - return JCTree.BITAND_ASG; + return BITAND_ASG; case EQEQ: - return JCTree.EQ; + return JCTree.Tag.EQ; case BANGEQ: - return JCTree.NE; + return NE; case LT: - return JCTree.LT; + return JCTree.Tag.LT; case GT: - return JCTree.GT; + return JCTree.Tag.GT; case LTEQ: - return JCTree.LE; + return LE; case GTEQ: - return JCTree.GE; + return GE; case LTLT: - return JCTree.SL; + return SL; case LTLTEQ: - return JCTree.SL_ASG; + return SL_ASG; case GTGT: - return JCTree.SR; + return SR; case GTGTEQ: - return JCTree.SR_ASG; + return SR_ASG; case GTGTGT: - return JCTree.USR; + return USR; case GTGTGTEQ: - return JCTree.USR_ASG; + return USR_ASG; case PLUS: - return JCTree.PLUS; + return JCTree.Tag.PLUS; case PLUSEQ: - return JCTree.PLUS_ASG; + return PLUS_ASG; case SUB: - return JCTree.MINUS; + return MINUS; case SUBEQ: - return JCTree.MINUS_ASG; + return MINUS_ASG; case STAR: - return JCTree.MUL; + return MUL; case STAREQ: - return JCTree.MUL_ASG; + return MUL_ASG; case SLASH: - return JCTree.DIV; + return DIV; case SLASHEQ: - return JCTree.DIV_ASG; + return DIV_ASG; case PERCENT: - return JCTree.MOD; + return MOD; case PERCENTEQ: - return JCTree.MOD_ASG; + return MOD_ASG; case INSTANCEOF: - return JCTree.TYPETEST; + return TYPETEST; default: - return -1; + return NO_TAG; } } /** Return operation tag of unary operator represented by token, - * -1 if token is not a binary operator. + * No_TAG if token is not a binary operator. */ - static int unoptag(TokenKind token) { + static JCTree.Tag unoptag(TokenKind token) { switch (token) { case PLUS: - return JCTree.POS; + return POS; case SUB: - return JCTree.NEG; + return NEG; case BANG: - return JCTree.NOT; + return NOT; case TILDE: - return JCTree.COMPL; + return COMPL; case PLUSPLUS: - return JCTree.PREINC; + return PREINC; case SUBSUB: - return JCTree.PREDEC; + return PREDEC; default: - return -1; + return NO_TAG; } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java index 680485efddb..4aac62cd109 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java @@ -25,8 +25,8 @@ package com.sun.tools.javac.parser; -import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.parser.Tokens.Token; +import com.sun.tools.javac.parser.Tokens.Comment; +import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.util.*; import java.nio.*; @@ -59,352 +59,295 @@ public class JavadocTokenizer extends JavaTokenizer { super(fac, input, inputLength); } - /** The comment input buffer, index of next chacter to be read, - * index of one past last character in buffer. - */ - private char[] buf; - private int bp; - private int buflen; - - /** The current character. - */ - private char ch; - - /** The column number position of the current character. - */ - private int col; - - /** The buffer index of the last converted Unicode character - */ - private int unicodeConversionBp = 0; - - /** - * Buffer for doc comment. - */ - private char[] docCommentBuffer = new char[1024]; - - /** - * Number of characters in doc comment buffer. - */ - private int docCommentCount; - - /** - * Translated and stripped contents of doc comment - */ - private String docComment = null; - - - /** Unconditionally expand the comment buffer. - */ - private void expandCommentBuffer() { - char[] newBuffer = new char[docCommentBuffer.length * 2]; - System.arraycopy(docCommentBuffer, 0, newBuffer, - 0, docCommentBuffer.length); - docCommentBuffer = newBuffer; + @Override + protected Comment processComment(int pos, int endPos, CommentStyle style) { + char[] buf = reader.getRawCharacters(pos, endPos); + return new JavadocComment(new ColReader(fac, buf, buf.length), style); } - /** Convert an ASCII digit from its base (8, 10, or 16) - * to its value. + /** + * This is a specialized version of UnicodeReader that keeps track of the + * column position within a given character stream (used for Javadoc processing). */ - private int digit(int base) { - char c = ch; - int result = Character.digit(c, base); - if (result >= 0 && c > 0x7f) { - ch = "0123456789abcdef".charAt(result); + static class ColReader extends UnicodeReader { + + int col; + + ColReader(ScannerFactory fac, char[] input, int inputLength) { + super(fac, input, inputLength); + } + + @Override + protected void convertUnicode() { + if (ch == '\\' && unicodeConversionBp != bp) { + bp++; ch = buf[bp]; col++; + if (ch == 'u') { + do { + bp++; ch = buf[bp]; col++; + } while (ch == 'u'); + int limit = bp + 3; + if (limit < buflen) { + int d = digit(bp, 16); + int code = d; + while (bp < limit && d >= 0) { + bp++; ch = buf[bp]; col++; + d = digit(bp, 16); + code = (code << 4) + d; + } + if (d >= 0) { + ch = (char)code; + unicodeConversionBp = bp; + return; + } + } + // "illegal.Unicode.esc", reported by base scanner + } else { + bp--; + ch = '\\'; + col--; + } + } + } + + @Override + protected void scanCommentChar() { + scanChar(); + if (ch == '\\') { + if (peekChar() == '\\' && !isUnicode()) { + putChar(ch, false); + bp++; col++; + } else { + convertUnicode(); + } + } + } + + @Override + protected void scanChar() { + bp++; + ch = buf[bp]; + switch (ch) { + case '\r': // return + col = 0; + break; + case '\n': // newline + if (bp == 0 || buf[bp-1] != '\r') { + col = 0; + } + break; + case '\t': // tab + col = (col / TabInc * TabInc) + TabInc; + break; + case '\\': // possible Unicode + col++; + convertUnicode(); + break; + default: + col++; + break; + } + } + } + + protected class JavadocComment extends JavaTokenizer.BasicComment { + + /** + * Translated and stripped contents of doc comment + */ + private String docComment = null; + + JavadocComment(ColReader comment_reader, CommentStyle cs) { + super(comment_reader, cs); } - return result; - } - /** Convert Unicode escape; bp points to initial '\' character - * (Spec 3.3). - */ - private void convertUnicode() { - if (ch == '\\' && unicodeConversionBp != bp) { - bp++; ch = buf[bp]; col++; - if (ch == 'u') { - do { - bp++; ch = buf[bp]; col++; - } while (ch == 'u'); - int limit = bp + 3; - if (limit < buflen) { - int d = digit(16); - int code = d; - while (bp < limit && d >= 0) { - bp++; ch = buf[bp]; col++; - d = digit(16); - code = (code << 4) + d; - } - if (d >= 0) { - ch = (char)code; - unicodeConversionBp = bp; - return; - } + public String getText() { + if (!scanned && cs == CommentStyle.JAVADOC) { + scanDocComment(); + } + return docComment; + } + + @Override + @SuppressWarnings("fallthrough") + protected void scanDocComment() { + try { + boolean firstLine = true; + + // Skip over first slash + comment_reader.scanCommentChar(); + // Skip over first star + comment_reader.scanCommentChar(); + + // consume any number of stars + while (comment_reader.bp < comment_reader.buflen && comment_reader.ch == '*') { + comment_reader.scanCommentChar(); + } + // is the comment in the form /**/, /***/, /****/, etc. ? + if (comment_reader.bp < comment_reader.buflen && comment_reader.ch == '/') { + docComment = ""; + return; + } + + // skip a newline on the first line of the comment. + if (comment_reader.bp < comment_reader.buflen) { + if (comment_reader.ch == LF) { + comment_reader.scanCommentChar(); + firstLine = false; + } else if (comment_reader.ch == CR) { + comment_reader.scanCommentChar(); + if (comment_reader.ch == LF) { + comment_reader.scanCommentChar(); + firstLine = false; + } + } + } + + outerLoop: + + // The outerLoop processes the doc comment, looping once + // for each line. For each line, it first strips off + // whitespace, then it consumes any stars, then it + // puts the rest of the line into our buffer. + while (comment_reader.bp < comment_reader.buflen) { + + // The wsLoop consumes whitespace from the beginning + // of each line. + wsLoop: + + while (comment_reader.bp < comment_reader.buflen) { + switch(comment_reader.ch) { + case ' ': + comment_reader.scanCommentChar(); + break; + case '\t': + comment_reader.col = ((comment_reader.col - 1) / TabInc * TabInc) + TabInc; + comment_reader.scanCommentChar(); + break; + case FF: + comment_reader.col = 0; + comment_reader.scanCommentChar(); + break; + // Treat newline at beginning of line (blank line, no star) + // as comment text. Old Javadoc compatibility requires this. + /*---------------------------------* + case CR: // (Spec 3.4) + doc_reader.scanCommentChar(); + if (ch == LF) { + col = 0; + doc_reader.scanCommentChar(); + } + break; + case LF: // (Spec 3.4) + doc_reader.scanCommentChar(); + break; + *---------------------------------*/ + default: + // we've seen something that isn't whitespace; + // jump out. + break wsLoop; + } + } + + // Are there stars here? If so, consume them all + // and check for the end of comment. + if (comment_reader.ch == '*') { + // skip all of the stars + do { + comment_reader.scanCommentChar(); + } while (comment_reader.ch == '*'); + + // check for the closing slash. + if (comment_reader.ch == '/') { + // We're done with the doc comment + // scanChar() and breakout. + break outerLoop; + } + } else if (! firstLine) { + //The current line does not begin with a '*' so we will indent it. + for (int i = 1; i < comment_reader.col; i++) { + comment_reader.putChar(' ', false); + } + } + // The textLoop processes the rest of the characters + // on the line, adding them to our buffer. + textLoop: + while (comment_reader.bp < comment_reader.buflen) { + switch (comment_reader.ch) { + case '*': + // Is this just a star? Or is this the + // end of a comment? + comment_reader.scanCommentChar(); + if (comment_reader.ch == '/') { + // This is the end of the comment, + // set ch and return our buffer. + break outerLoop; + } + // This is just an ordinary star. Add it to + // the buffer. + comment_reader.putChar('*', false); + break; + case ' ': + case '\t': + comment_reader.putChar(comment_reader.ch, false); + comment_reader.scanCommentChar(); + break; + case FF: + comment_reader.scanCommentChar(); + break textLoop; // treat as end of line + case CR: // (Spec 3.4) + comment_reader.scanCommentChar(); + if (comment_reader.ch != LF) { + // Canonicalize CR-only line terminator to LF + comment_reader.putChar((char)LF, false); + break textLoop; + } + /* fall through to LF case */ + case LF: // (Spec 3.4) + // We've seen a newline. Add it to our + // buffer and break out of this loop, + // starting fresh on a new line. + comment_reader.putChar(comment_reader.ch, false); + comment_reader.scanCommentChar(); + break textLoop; + default: + // Add the character to our buffer. + comment_reader.putChar(comment_reader.ch, false); + comment_reader.scanCommentChar(); + } + } // end textLoop + firstLine = false; + } // end outerLoop + + if (comment_reader.sp > 0) { + int i = comment_reader.sp - 1; + trailLoop: + while (i > -1) { + switch (comment_reader.sbuf[i]) { + case '*': + i--; + break; + default: + break trailLoop; + } + } + comment_reader.sp = i + 1; + + // Store the text of the doc comment + docComment = comment_reader.chars(); + } else { + docComment = ""; + } + } finally { + scanned = true; + if (docComment != null && + docComment.matches("(?sm).*^\\s*@deprecated( |$).*")) { + deprecatedFlag = true; } - // "illegal.Unicode.esc", reported by base scanner - } else { - bp--; - ch = '\\'; - col--; } } } - - /** Read next character. - */ - private void scanChar() { - bp++; - ch = buf[bp]; - switch (ch) { - case '\r': // return - col = 0; - break; - case '\n': // newline - if (bp == 0 || buf[bp-1] != '\r') { - col = 0; - } - break; - case '\t': // tab - col = (col / TabInc * TabInc) + TabInc; - break; - case '\\': // possible Unicode - col++; - convertUnicode(); - break; - default: - col++; - break; - } - } - @Override - public Token readToken() { - docComment = null; - Token tk = super.readToken(); - tk.docComment = docComment; - return tk; - } - - /** - * Read next character in doc comment, skipping over double '\' characters. - * If a double '\' is skipped, put in the buffer and update buffer count. - */ - private void scanDocCommentChar() { - scanChar(); - if (ch == '\\') { - if (buf[bp+1] == '\\' && unicodeConversionBp != bp) { - if (docCommentCount == docCommentBuffer.length) - expandCommentBuffer(); - docCommentBuffer[docCommentCount++] = ch; - bp++; col++; - } else { - convertUnicode(); - } - } - } - - /** - * Process a doc comment and make the string content available. - * Strips leading whitespace and stars. - */ - @SuppressWarnings("fallthrough") - protected void processComment(int pos, int endPos, CommentStyle style) { - if (style != CommentStyle.JAVADOC) { - return; - } - - buf = reader.getRawCharacters(pos, endPos); - buflen = buf.length; - bp = 0; - col = 0; - - docCommentCount = 0; - - boolean firstLine = true; - - // Skip over first slash - scanDocCommentChar(); - // Skip over first star - scanDocCommentChar(); - - // consume any number of stars - while (bp < buflen && ch == '*') { - scanDocCommentChar(); - } - // is the comment in the form /**/, /***/, /****/, etc. ? - if (bp < buflen && ch == '/') { - docComment = ""; - return; - } - - // skip a newline on the first line of the comment. - if (bp < buflen) { - if (ch == LF) { - scanDocCommentChar(); - firstLine = false; - } else if (ch == CR) { - scanDocCommentChar(); - if (ch == LF) { - scanDocCommentChar(); - firstLine = false; - } - } - } - - outerLoop: - - // The outerLoop processes the doc comment, looping once - // for each line. For each line, it first strips off - // whitespace, then it consumes any stars, then it - // puts the rest of the line into our buffer. - while (bp < buflen) { - - // The wsLoop consumes whitespace from the beginning - // of each line. - wsLoop: - - while (bp < buflen) { - switch(ch) { - case ' ': - scanDocCommentChar(); - break; - case '\t': - col = ((col - 1) / TabInc * TabInc) + TabInc; - scanDocCommentChar(); - break; - case FF: - col = 0; - scanDocCommentChar(); - break; -// Treat newline at beginning of line (blank line, no star) -// as comment text. Old Javadoc compatibility requires this. -/*---------------------------------* - case CR: // (Spec 3.4) - scanDocCommentChar(); - if (ch == LF) { - col = 0; - scanDocCommentChar(); - } - break; - case LF: // (Spec 3.4) - scanDocCommentChar(); - break; -*---------------------------------*/ - default: - // we've seen something that isn't whitespace; - // jump out. - break wsLoop; - } - } - - // Are there stars here? If so, consume them all - // and check for the end of comment. - if (ch == '*') { - // skip all of the stars - do { - scanDocCommentChar(); - } while (ch == '*'); - - // check for the closing slash. - if (ch == '/') { - // We're done with the doc comment - // scanChar() and breakout. - break outerLoop; - } - } else if (! firstLine) { - //The current line does not begin with a '*' so we will indent it. - for (int i = 1; i < col; i++) { - if (docCommentCount == docCommentBuffer.length) - expandCommentBuffer(); - docCommentBuffer[docCommentCount++] = ' '; - } - } - - // The textLoop processes the rest of the characters - // on the line, adding them to our buffer. - textLoop: - while (bp < buflen) { - switch (ch) { - case '*': - // Is this just a star? Or is this the - // end of a comment? - scanDocCommentChar(); - if (ch == '/') { - // This is the end of the comment, - // set ch and return our buffer. - break outerLoop; - } - // This is just an ordinary star. Add it to - // the buffer. - if (docCommentCount == docCommentBuffer.length) - expandCommentBuffer(); - docCommentBuffer[docCommentCount++] = '*'; - break; - case ' ': - case '\t': - if (docCommentCount == docCommentBuffer.length) - expandCommentBuffer(); - docCommentBuffer[docCommentCount++] = ch; - scanDocCommentChar(); - break; - case FF: - scanDocCommentChar(); - break textLoop; // treat as end of line - case CR: // (Spec 3.4) - scanDocCommentChar(); - if (ch != LF) { - // Canonicalize CR-only line terminator to LF - if (docCommentCount == docCommentBuffer.length) - expandCommentBuffer(); - docCommentBuffer[docCommentCount++] = (char)LF; - break textLoop; - } - /* fall through to LF case */ - case LF: // (Spec 3.4) - // We've seen a newline. Add it to our - // buffer and break out of this loop, - // starting fresh on a new line. - if (docCommentCount == docCommentBuffer.length) - expandCommentBuffer(); - docCommentBuffer[docCommentCount++] = ch; - scanDocCommentChar(); - break textLoop; - default: - // Add the character to our buffer. - if (docCommentCount == docCommentBuffer.length) - expandCommentBuffer(); - docCommentBuffer[docCommentCount++] = ch; - scanDocCommentChar(); - } - } // end textLoop - firstLine = false; - } // end outerLoop - - if (docCommentCount > 0) { - int i = docCommentCount - 1; - trailLoop: - while (i > -1) { - switch (docCommentBuffer[i]) { - case '*': - i--; - break; - default: - break trailLoop; - } - } - docCommentCount = i + 1; - - // Store the text of the doc comment - docComment = new String(docCommentBuffer, 0 , docCommentCount); - } else { - docComment = ""; - } - } - - /** Build a map for translating between line numbers and - * positions in the input. - * - * @return a LineMap */ public Position.LineMap getLineMap() { char[] buf = reader.getRawCharacters(); return Position.makeLineMap(buf, buf.length, true); diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java index 934dfb90520..db2e1ec3c63 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java @@ -30,8 +30,10 @@ import java.util.Locale; import com.sun.tools.javac.api.Formattable; import com.sun.tools.javac.api.Messages; import com.sun.tools.javac.parser.Tokens.Token.Tag; +import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Names; /** A class that defines codes/utilities for Java source tokens @@ -281,6 +283,19 @@ public class Tokens { } } + public interface Comment { + + enum CommentStyle { + LINE, + BLOCK, + JAVADOC, + } + + String getText(); + CommentStyle getStyle(); + boolean isDeprecated(); + } + /** * This is the class representing a javac token. Each token has several fields * that are set by the javac lexer (i.e. start/end position, string value, etc). @@ -304,18 +319,14 @@ public class Tokens { /** The end position of this token */ public final int endPos; - /** Is this token preceeded by a deprecated comment? */ - public final boolean deprecatedFlag; + /** Comment reader associated with this token */ + public final List comments; - /** Is this token preceeded by a deprecated comment? */ - public String docComment; - - Token(TokenKind kind, int pos, int endPos, - boolean deprecatedFlag) { + Token(TokenKind kind, int pos, int endPos, List comments) { this.kind = kind; this.pos = pos; this.endPos = endPos; - this.deprecatedFlag = deprecatedFlag; + this.comments = comments; checkKind(); } @@ -331,8 +342,8 @@ public class Tokens { throw new AssertionError("Cant split - bad subtokens"); } return new Token[] { - new Token(t1, pos, pos + t1.name.length(), deprecatedFlag), - new Token(t2, pos + t1.name.length(), endPos, false) + new Token(t1, pos, pos + t1.name.length(), comments), + new Token(t2, pos + t1.name.length(), endPos, null) }; } @@ -353,14 +364,52 @@ public class Tokens { public int radix() { throw new UnsupportedOperationException(); } + + /** + * Preserve classic semantics - if multiple javadocs are found on the token + * the last one is returned + */ + public String comment(Comment.CommentStyle style) { + List readers = getReaders(Comment.CommentStyle.JAVADOC); + return readers.isEmpty() ? + null : + readers.head.getText(); + } + + /** + * Preserve classic semantics - deprecated should be set if at least one + * javadoc comment attached to this token contains the '@deprecated' string + */ + public boolean deprecatedFlag() { + for (Comment r : getReaders(Comment.CommentStyle.JAVADOC)) { + if (r.isDeprecated()) { + return true; + } + } + return false; + } + + private List getReaders(Comment.CommentStyle style) { + if (comments == null) { + return List.nil(); + } else { + ListBuffer buf = ListBuffer.lb(); + for (Comment r : comments) { + if (r.getStyle() == style) { + buf.add(r); + } + } + return buf.toList(); + } + } } final static class NamedToken extends Token { /** The name of this token */ public final Name name; - public NamedToken(TokenKind kind, int pos, int endPos, Name name, boolean deprecatedFlag) { - super(kind, pos, endPos, deprecatedFlag); + public NamedToken(TokenKind kind, int pos, int endPos, Name name, List comments) { + super(kind, pos, endPos, comments); this.name = name; } @@ -380,8 +429,8 @@ public class Tokens { /** The string value of this token */ public final String stringVal; - public StringToken(TokenKind kind, int pos, int endPos, String stringVal, boolean deprecatedFlag) { - super(kind, pos, endPos, deprecatedFlag); + public StringToken(TokenKind kind, int pos, int endPos, String stringVal, List comments) { + super(kind, pos, endPos, comments); this.stringVal = stringVal; } @@ -401,8 +450,8 @@ public class Tokens { /** The 'radix' value of this token */ public final int radix; - public NumericToken(TokenKind kind, int pos, int endPos, String stringVal, int radix, boolean deprecatedFlag) { - super(kind, pos, endPos, stringVal, deprecatedFlag); + public NumericToken(TokenKind kind, int pos, int endPos, String stringVal, int radix, List comments) { + super(kind, pos, endPos, stringVal, comments); this.radix = radix; } @@ -419,5 +468,5 @@ public class Tokens { } public static final Token DUMMY = - new Token(TokenKind.ERROR, 0, 0, false); + new Token(TokenKind.ERROR, 0, 0, null); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java b/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java index c5718c6fc47..f1b6d8b12d6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java @@ -26,8 +26,12 @@ package com.sun.tools.javac.parser; import com.sun.tools.javac.file.JavacFileManager; -import java.nio.CharBuffer; import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Name; +import com.sun.tools.javac.util.Names; + +import java.nio.CharBuffer; + import static com.sun.tools.javac.util.LayoutCharacters.*; /** The char reader used by the javac lexer/tokenizer. Returns the sequence of @@ -58,6 +62,12 @@ public class UnicodeReader { protected int unicodeConversionBp = -1; protected Log log; + protected Names names; + + /** A character buffer for saved chars. + */ + protected char[] sbuf = new char[128]; + protected int sp; /** * Create a scanner from the input array. This method might @@ -76,6 +86,7 @@ public class UnicodeReader { protected UnicodeReader(ScannerFactory sf, char[] input, int inputLength) { log = sf.log; + names = sf.names; if (inputLength == input.length) { if (input.length > 0 && Character.isWhitespace(input[input.length - 1])) { inputLength--; @@ -103,6 +114,48 @@ public class UnicodeReader { } } + /** Read next character in comment, skipping over double '\' characters. + */ + protected void scanCommentChar() { + scanChar(); + if (ch == '\\') { + if (peekChar() == '\\' && !isUnicode()) { + skipChar(); + } else { + convertUnicode(); + } + } + } + + /** Append a character to sbuf. + */ + protected void putChar(char ch, boolean scan) { + if (sp == sbuf.length) { + char[] newsbuf = new char[sbuf.length * 2]; + System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); + sbuf = newsbuf; + } + sbuf[sp++] = ch; + if (scan) + scanChar(); + } + + protected void putChar(char ch) { + putChar(ch, false); + } + + protected void putChar(boolean scan) { + putChar(ch, scan); + } + + Name name() { + return names.fromChars(sbuf, 0, sp); + } + + String chars() { + return new String(sbuf, 0, sp); + } + /** Convert unicode escape; bp points to initial '\' character * (Spec 3.3). */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index ce16646eea1..e4d9de27afb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -1222,7 +1222,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea List classes = List.nil(); for (JCCompilationUnit unit : units) { for (JCTree node : unit.defs) { - if (node.getTag() == JCTree.CLASSDEF) { + if (node.hasTag(JCTree.Tag.CLASSDEF)) { ClassSymbol sym = ((JCClassDecl) node).sym; Assert.checkNonNull(sym); classes = classes.prepend(sym); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index 564e63cd30e..c23a4df458e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -42,6 +42,7 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.source.tree.*; import static com.sun.tools.javac.code.BoundKind.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** * Root class for abstract syntax tree nodes. It provides definitions @@ -79,253 +80,289 @@ import static com.sun.tools.javac.code.BoundKind.*; public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /* Tree tag values, identifying kinds of trees */ + public enum Tag{ + /** For methods that return an invalid tag if a given condition is not met + */ + NO_TAG, - /** Toplevel nodes, of type TopLevel, representing entire source files. - */ - public static final int TOPLEVEL = 1; + /** Toplevel nodes, of type TopLevel, representing entire source files. + */ + TOPLEVEL, - /** Import clauses, of type Import. - */ - public static final int IMPORT = TOPLEVEL + 1; + /** Import clauses, of type Import. + */ + IMPORT, - /** Class definitions, of type ClassDef. - */ - public static final int CLASSDEF = IMPORT + 1; + /** Class definitions, of type ClassDef. + */ + CLASSDEF, - /** Method definitions, of type MethodDef. - */ - public static final int METHODDEF = CLASSDEF + 1; + /** Method definitions, of type MethodDef. + */ + METHODDEF, - /** Variable definitions, of type VarDef. - */ - public static final int VARDEF = METHODDEF + 1; + /** Variable definitions, of type VarDef. + */ + VARDEF, - /** The no-op statement ";", of type Skip - */ - public static final int SKIP = VARDEF + 1; + /** The no-op statement ";", of type Skip + */ + SKIP, - /** Blocks, of type Block. - */ - public static final int BLOCK = SKIP + 1; + /** Blocks, of type Block. + */ + BLOCK, - /** Do-while loops, of type DoLoop. - */ - public static final int DOLOOP = BLOCK + 1; + /** Do-while loops, of type DoLoop. + */ + DOLOOP, - /** While-loops, of type WhileLoop. - */ - public static final int WHILELOOP = DOLOOP + 1; + /** While-loops, of type WhileLoop. + */ + WHILELOOP, - /** For-loops, of type ForLoop. - */ - public static final int FORLOOP = WHILELOOP + 1; + /** For-loops, of type ForLoop. + */ + FORLOOP, - /** Foreach-loops, of type ForeachLoop. - */ - public static final int FOREACHLOOP = FORLOOP + 1; + /** Foreach-loops, of type ForeachLoop. + */ + FOREACHLOOP, - /** Labelled statements, of type Labelled. - */ - public static final int LABELLED = FOREACHLOOP + 1; + /** Labelled statements, of type Labelled. + */ + LABELLED, - /** Switch statements, of type Switch. - */ - public static final int SWITCH = LABELLED + 1; + /** Switch statements, of type Switch. + */ + SWITCH, - /** Case parts in switch statements, of type Case. - */ - public static final int CASE = SWITCH + 1; + /** Case parts in switch statements, of type Case. + */ + CASE, - /** Synchronized statements, of type Synchonized. - */ - public static final int SYNCHRONIZED = CASE + 1; + /** Synchronized statements, of type Synchonized. + */ + SYNCHRONIZED, - /** Try statements, of type Try. - */ - public static final int TRY = SYNCHRONIZED + 1; + /** Try statements, of type Try. + */ + TRY, - /** Catch clauses in try statements, of type Catch. - */ - public static final int CATCH = TRY + 1; + /** Catch clauses in try statements, of type Catch. + */ + CATCH, - /** Conditional expressions, of type Conditional. - */ - public static final int CONDEXPR = CATCH + 1; + /** Conditional expressions, of type Conditional. + */ + CONDEXPR, - /** Conditional statements, of type If. - */ - public static final int IF = CONDEXPR + 1; + /** Conditional statements, of type If. + */ + IF, - /** Expression statements, of type Exec. - */ - public static final int EXEC = IF + 1; + /** Expression statements, of type Exec. + */ + EXEC, - /** Break statements, of type Break. - */ - public static final int BREAK = EXEC + 1; + /** Break statements, of type Break. + */ + BREAK, - /** Continue statements, of type Continue. - */ - public static final int CONTINUE = BREAK + 1; + /** Continue statements, of type Continue. + */ + CONTINUE, - /** Return statements, of type Return. - */ - public static final int RETURN = CONTINUE + 1; + /** Return statements, of type Return. + */ + RETURN, - /** Throw statements, of type Throw. - */ - public static final int THROW = RETURN + 1; + /** Throw statements, of type Throw. + */ + THROW, - /** Assert statements, of type Assert. - */ - public static final int ASSERT = THROW + 1; + /** Assert statements, of type Assert. + */ + ASSERT, - /** Method invocation expressions, of type Apply. - */ - public static final int APPLY = ASSERT + 1; + /** Method invocation expressions, of type Apply. + */ + APPLY, - /** Class instance creation expressions, of type NewClass. - */ - public static final int NEWCLASS = APPLY + 1; + /** Class instance creation expressions, of type NewClass. + */ + NEWCLASS, - /** Array creation expressions, of type NewArray. - */ - public static final int NEWARRAY = NEWCLASS + 1; + /** Array creation expressions, of type NewArray. + */ + NEWARRAY, - /** Parenthesized subexpressions, of type Parens. - */ - public static final int PARENS = NEWARRAY + 1; + /** Parenthesized subexpressions, of type Parens. + */ + PARENS, - /** Assignment expressions, of type Assign. - */ - public static final int ASSIGN = PARENS + 1; + /** Assignment expressions, of type Assign. + */ + ASSIGN, - /** Type cast expressions, of type TypeCast. - */ - public static final int TYPECAST = ASSIGN + 1; + /** Type cast expressions, of type TypeCast. + */ + TYPECAST, - /** Type test expressions, of type TypeTest. - */ - public static final int TYPETEST = TYPECAST + 1; + /** Type test expressions, of type TypeTest. + */ + TYPETEST, - /** Indexed array expressions, of type Indexed. - */ - public static final int INDEXED = TYPETEST + 1; + /** Indexed array expressions, of type Indexed. + */ + INDEXED, - /** Selections, of type Select. - */ - public static final int SELECT = INDEXED + 1; + /** Selections, of type Select. + */ + SELECT, - /** Simple identifiers, of type Ident. - */ - public static final int IDENT = SELECT + 1; + /** Simple identifiers, of type Ident. + */ + IDENT, - /** Literals, of type Literal. - */ - public static final int LITERAL = IDENT + 1; + /** Literals, of type Literal. + */ + LITERAL, - /** Basic type identifiers, of type TypeIdent. - */ - public static final int TYPEIDENT = LITERAL + 1; + /** Basic type identifiers, of type TypeIdent. + */ + TYPEIDENT, - /** Array types, of type TypeArray. - */ - public static final int TYPEARRAY = TYPEIDENT + 1; + /** Array types, of type TypeArray. + */ + TYPEARRAY, - /** Parameterized types, of type TypeApply. - */ - public static final int TYPEAPPLY = TYPEARRAY + 1; + /** Parameterized types, of type TypeApply. + */ + TYPEAPPLY, - /** Union types, of type TypeUnion - */ - public static final int TYPEUNION = TYPEAPPLY + 1; + /** Union types, of type TypeUnion + */ + TYPEUNION, - /** Formal type parameters, of type TypeParameter. - */ - public static final int TYPEPARAMETER = TYPEUNION + 1; + /** Formal type parameters, of type TypeParameter. + */ + TYPEPARAMETER, - /** Type argument. - */ - public static final int WILDCARD = TYPEPARAMETER + 1; + /** Type argument. + */ + WILDCARD, - /** Bound kind: extends, super, exact, or unbound - */ - public static final int TYPEBOUNDKIND = WILDCARD + 1; + /** Bound kind: extends, super, exact, or unbound + */ + TYPEBOUNDKIND, - /** metadata: Annotation. - */ - public static final int ANNOTATION = TYPEBOUNDKIND + 1; + /** metadata: Annotation. + */ + ANNOTATION, - /** metadata: Modifiers - */ - public static final int MODIFIERS = ANNOTATION + 1; + /** metadata: Modifiers + */ + MODIFIERS, - public static final int ANNOTATED_TYPE = MODIFIERS + 1; + ANNOTATED_TYPE, - /** Error trees, of type Erroneous. - */ - public static final int ERRONEOUS = ANNOTATED_TYPE + 1; + /** Error trees, of type Erroneous. + */ + ERRONEOUS, - /** Unary operators, of type Unary. - */ - public static final int POS = ERRONEOUS + 1; // + - public static final int NEG = POS + 1; // - - public static final int NOT = NEG + 1; // ! - public static final int COMPL = NOT + 1; // ~ - public static final int PREINC = COMPL + 1; // ++ _ - public static final int PREDEC = PREINC + 1; // -- _ - public static final int POSTINC = PREDEC + 1; // _ ++ - public static final int POSTDEC = POSTINC + 1; // _ -- + /** Unary operators, of type Unary. + */ + POS, // + + NEG, // - + NOT, // ! + COMPL, // ~ + PREINC, // ++ _ + PREDEC, // -- _ + POSTINC, // _ ++ + POSTDEC, // _ -- - /** unary operator for null reference checks, only used internally. - */ - public static final int NULLCHK = POSTDEC + 1; + /** unary operator for null reference checks, only used internally. + */ + NULLCHK, - /** Binary operators, of type Binary. - */ - public static final int OR = NULLCHK + 1; // || - public static final int AND = OR + 1; // && - public static final int BITOR = AND + 1; // | - public static final int BITXOR = BITOR + 1; // ^ - public static final int BITAND = BITXOR + 1; // & - public static final int EQ = BITAND + 1; // == - public static final int NE = EQ + 1; // != - public static final int LT = NE + 1; // < - public static final int GT = LT + 1; // > - public static final int LE = GT + 1; // <= - public static final int GE = LE + 1; // >= - public static final int SL = GE + 1; // << - public static final int SR = SL + 1; // >> - public static final int USR = SR + 1; // >>> - public static final int PLUS = USR + 1; // + - public static final int MINUS = PLUS + 1; // - - public static final int MUL = MINUS + 1; // * - public static final int DIV = MUL + 1; // / - public static final int MOD = DIV + 1; // % + /** Binary operators, of type Binary. + */ + OR, // || + AND, // && + BITOR, // | + BITXOR, // ^ + BITAND, // & + EQ, // == + NE, // != + LT, // < + GT, // > + LE, // <= + GE, // >= + SL, // << + SR, // >> + USR, // >>> + PLUS, // + + MINUS, // - + MUL, // * + DIV, // / + MOD, // % - /** Assignment operators, of type Assignop. - */ - public static final int BITOR_ASG = MOD + 1; // |= - public static final int BITXOR_ASG = BITOR_ASG + 1; // ^= - public static final int BITAND_ASG = BITXOR_ASG + 1; // &= + /** Assignment operators, of type Assignop. + */ + BITOR_ASG(BITOR), // |= + BITXOR_ASG(BITXOR), // ^= + BITAND_ASG(BITAND), // &= - public static final int SL_ASG = SL + BITOR_ASG - BITOR; // <<= - public static final int SR_ASG = SL_ASG + 1; // >>= - public static final int USR_ASG = SR_ASG + 1; // >>>= - public static final int PLUS_ASG = USR_ASG + 1; // += - public static final int MINUS_ASG = PLUS_ASG + 1; // -= - public static final int MUL_ASG = MINUS_ASG + 1; // *= - public static final int DIV_ASG = MUL_ASG + 1; // /= - public static final int MOD_ASG = DIV_ASG + 1; // %= + SL_ASG(SL), // <<= + SR_ASG(SR), // >>= + USR_ASG(USR), // >>>= + PLUS_ASG(PLUS), // += + MINUS_ASG(MINUS), // -= + MUL_ASG(MUL), // *= + DIV_ASG(DIV), // /= + MOD_ASG(MOD), // %= - /** A synthetic let expression, of type LetExpr. - */ - public static final int LETEXPR = MOD_ASG + 1; // ala scheme + /** A synthetic let expression, of type LetExpr. + */ + LETEXPR; // ala scheme + private Tag noAssignTag; - /** The offset between assignment operators and normal operators. - */ - public static final int ASGOffset = BITOR_ASG - BITOR; + private static int numberOfOperators = MOD.ordinal() - POS.ordinal() + 1; + + private Tag(Tag noAssignTag) { + this.noAssignTag = noAssignTag; + } + + private Tag() { } + + public static int getNumberOfOperators() { + return numberOfOperators; + } + + public Tag noAssignOp() { + if (noAssignTag != null) + return noAssignTag; + throw new AssertionError("noAssignOp() method is not available for non assignment tags"); + } + + public boolean isPostUnaryOp() { + return (this == POSTINC || this == POSTDEC); + } + + public boolean isIncOrDecUnaryOp() { + return (this == PREINC || this == PREDEC || this == POSTINC || this == POSTDEC); + } + + public boolean isAssignop() { + return noAssignTag != null; + } + + public int operatorIndex() { + return (this.ordinal() - POS.ordinal()); + } + } /* The (encoded) position in the source file. @see util.Position. */ @@ -337,7 +374,13 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /* The tag of this node -- one of the constants declared above. */ - public abstract int getTag(); + public abstract Tag getTag(); + + /* Returns true if the tag of this node is equals to tag. + */ + public boolean hasTag(Tag tag) { + return tag == getTag(); + } /** Convert a tree to a pretty-printed string. */ @Override @@ -464,10 +507,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public List getImports() { ListBuffer imports = new ListBuffer(); for (JCTree tree : defs) { - int tag = tree.getTag(); - if (tag == IMPORT) + if (tree.hasTag(IMPORT)) imports.append((JCImport)tree); - else if (tag != SKIP) + else if (!tree.hasTag(SKIP)) break; } return imports.toList(); @@ -482,7 +524,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public List getTypeDecls() { List typeDefs; for (typeDefs = defs; !typeDefs.isEmpty(); typeDefs = typeDefs.tail) - if (typeDefs.head.getTag() != IMPORT) + if (!typeDefs.head.hasTag(IMPORT)) break; return typeDefs; } @@ -492,7 +534,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return TOPLEVEL; } } @@ -521,7 +563,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return IMPORT; } } @@ -618,7 +660,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return CLASSDEF; } } @@ -690,7 +732,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return METHODDEF; } } @@ -736,7 +778,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return VARDEF; } } @@ -757,7 +799,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return SKIP; } } @@ -790,7 +832,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return BLOCK; } } @@ -817,7 +859,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return DOLOOP; } } @@ -844,7 +886,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return WHILELOOP; } } @@ -885,7 +927,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override - public int getTag() { + public Tag getTag() { return FORLOOP; } } @@ -914,7 +956,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitEnhancedForLoop(this, d); } @Override - public int getTag() { + public Tag getTag() { return FOREACHLOOP; } } @@ -939,7 +981,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitLabeledStatement(this, d); } @Override - public int getTag() { + public Tag getTag() { return LABELLED; } } @@ -965,7 +1007,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitSwitch(this, d); } @Override - public int getTag() { + public Tag getTag() { return SWITCH; } } @@ -991,7 +1033,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitCase(this, d); } @Override - public int getTag() { + public Tag getTag() { return CASE; } } @@ -1017,7 +1059,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitSynchronized(this, d); } @Override - public int getTag() { + public Tag getTag() { return SYNCHRONIZED; } } @@ -1057,7 +1099,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return resources; } @Override - public int getTag() { + public Tag getTag() { return TRY; } } @@ -1083,7 +1125,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitCatch(this, d); } @Override - public int getTag() { + public Tag getTag() { return CATCH; } } @@ -1115,7 +1157,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitConditionalExpression(this, d); } @Override - public int getTag() { + public Tag getTag() { return CONDEXPR; } } @@ -1147,7 +1189,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitIf(this, d); } @Override - public int getTag() { + public Tag getTag() { return IF; } } @@ -1172,7 +1214,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitExpressionStatement(this, d); } @Override - public int getTag() { + public Tag getTag() { return EXEC; } @@ -1212,7 +1254,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitBreak(this, d); } @Override - public int getTag() { + public Tag getTag() { return BREAK; } } @@ -1237,7 +1279,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitContinue(this, d); } @Override - public int getTag() { + public Tag getTag() { return CONTINUE; } } @@ -1260,7 +1302,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitReturn(this, d); } @Override - public int getTag() { + public Tag getTag() { return RETURN; } } @@ -1283,7 +1325,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitThrow(this, d); } @Override - public int getTag() { + public Tag getTag() { return THROW; } } @@ -1309,7 +1351,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitAssert(this, d); } @Override - public int getTag() { + public Tag getTag() { return ASSERT; } } @@ -1352,7 +1394,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return this; } @Override - public int getTag() { + public Tag getTag() { return(APPLY); } } @@ -1402,7 +1444,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitNewClass(this, d); } @Override - public int getTag() { + public Tag getTag() { return NEWCLASS; } } @@ -1438,7 +1480,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitNewArray(this, d); } @Override - public int getTag() { + public Tag getTag() { return NEWARRAY; } } @@ -1461,7 +1503,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitParenthesized(this, d); } @Override - public int getTag() { + public Tag getTag() { return PARENS; } } @@ -1487,7 +1529,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitAssignment(this, d); } @Override - public int getTag() { + public Tag getTag() { return ASSIGN; } } @@ -1496,11 +1538,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { * An assignment with "+=", "|=" ... */ public static class JCAssignOp extends JCExpression implements CompoundAssignmentTree { - private int opcode; + private Tag opcode; public JCExpression lhs; public JCExpression rhs; public Symbol operator; - protected JCAssignOp(int opcode, JCTree lhs, JCTree rhs, Symbol operator) { + protected JCAssignOp(Tag opcode, JCTree lhs, JCTree rhs, Symbol operator) { this.opcode = opcode; this.lhs = (JCExpression)lhs; this.rhs = (JCExpression)rhs; @@ -1520,7 +1562,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitCompoundAssignment(this, d); } @Override - public int getTag() { + public Tag getTag() { return opcode; } } @@ -1529,10 +1571,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { * A unary operation. */ public static class JCUnary extends JCExpression implements UnaryTree { - private int opcode; + private Tag opcode; public JCExpression arg; public Symbol operator; - protected JCUnary(int opcode, JCExpression arg) { + protected JCUnary(Tag opcode, JCExpression arg) { this.opcode = opcode; this.arg = arg; } @@ -1549,11 +1591,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitUnary(this, d); } @Override - public int getTag() { + public Tag getTag() { return opcode; } - public void setTag(int tag) { + public void setTag(Tag tag) { opcode = tag; } } @@ -1562,11 +1604,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { * A binary operation. */ public static class JCBinary extends JCExpression implements BinaryTree { - private int opcode; + private Tag opcode; public JCExpression lhs; public JCExpression rhs; public Symbol operator; - protected JCBinary(int opcode, + protected JCBinary(Tag opcode, JCExpression lhs, JCExpression rhs, Symbol operator) { @@ -1589,7 +1631,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitBinary(this, d); } @Override - public int getTag() { + public Tag getTag() { return opcode; } } @@ -1615,7 +1657,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitTypeCast(this, d); } @Override - public int getTag() { + public Tag getTag() { return TYPECAST; } } @@ -1641,7 +1683,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitInstanceOf(this, d); } @Override - public int getTag() { + public Tag getTag() { return TYPETEST; } } @@ -1667,7 +1709,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitArrayAccess(this, d); } @Override - public int getTag() { + public Tag getTag() { return INDEXED; } } @@ -1698,7 +1740,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } public Name getIdentifier() { return name; } @Override - public int getTag() { + public Tag getTag() { return SELECT; } } @@ -1724,7 +1766,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public R accept(TreeVisitor v, D d) { return v.visitIdentifier(this, d); } - public int getTag() { + @Override + public Tag getTag() { return IDENT; } } @@ -1790,7 +1833,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return this; } @Override - public int getTag() { + public Tag getTag() { return LITERAL; } } @@ -1838,7 +1881,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitPrimitiveType(this, d); } @Override - public int getTag() { + public Tag getTag() { return TYPEIDENT; } } @@ -1861,7 +1904,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitArrayType(this, d); } @Override - public int getTag() { + public Tag getTag() { return TYPEARRAY; } } @@ -1889,7 +1932,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitParameterizedType(this, d); } @Override - public int getTag() { + public Tag getTag() { return TYPEAPPLY; } } @@ -1917,7 +1960,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitUnionType(this, d); } @Override - public int getTag() { + public Tag getTag() { return TYPEUNION; } } @@ -1947,7 +1990,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitTypeParameter(this, d); } @Override - public int getTag() { + public Tag getTag() { return TYPEPARAMETER; } } @@ -1981,7 +2024,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitWildcard(this, d); } @Override - public int getTag() { + public Tag getTag() { return WILDCARD; } } @@ -2002,7 +2045,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { throw new AssertionError("TypeBoundKind is not part of a public API"); } @Override - public int getTag() { + public Tag getTag() { return TYPEBOUNDKIND; } } @@ -2027,7 +2070,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitAnnotation(this, d); } @Override - public int getTag() { + public Tag getTag() { return ANNOTATION; } } @@ -2054,7 +2097,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitModifiers(this, d); } @Override - public int getTag() { + public Tag getTag() { return MODIFIERS; } } @@ -2079,7 +2122,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { return v.visitErroneous(this, d); } @Override - public int getTag() { + public Tag getTag() { return ERRONEOUS; } } @@ -2103,7 +2146,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { throw new AssertionError("LetExpr is not part of a public API"); } @Override - public int getTag() { + public Tag getTag() { return LETEXPR; } } @@ -2175,9 +2218,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { List elems); JCParens Parens(JCExpression expr); JCAssign Assign(JCExpression lhs, JCExpression rhs); - JCAssignOp Assignop(int opcode, JCTree lhs, JCTree rhs); - JCUnary Unary(int opcode, JCExpression arg); - JCBinary Binary(int opcode, JCExpression lhs, JCExpression rhs); + JCAssignOp Assignop(Tag opcode, JCTree lhs, JCTree rhs); + JCUnary Unary(Tag opcode, JCExpression arg); + JCBinary Binary(Tag opcode, JCExpression lhs, JCExpression rhs); JCTypeCast TypeCast(JCTree expr, JCExpression type); JCInstanceOf TypeTest(JCExpression expr, JCTree clazz); JCArrayAccess Indexed(JCExpression indexed, JCExpression index); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java index a332cdeb0f8..e781fd130e6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -36,6 +36,8 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.code.Flags.ANNOTATION; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** Prints out a tree as an indented Java source program. * @@ -310,7 +312,7 @@ public class Pretty extends JCTree.Visitor { /** Is the given tree an enumerator definition? */ boolean isEnumerator(JCTree t) { - return t.getTag() == JCTree.VARDEF && (((JCVariableDecl) t).mods.flags & ENUM) != 0; + return t.hasTag(VARDEF) && (((JCVariableDecl) t).mods.flags & ENUM) != 0; } /** Print unit consisting of package clause and import statements in toplevel, @@ -331,9 +333,9 @@ public class Pretty extends JCTree.Visitor { } boolean firstImport = true; for (List l = tree.defs; - l.nonEmpty() && (cdef == null || l.head.getTag() == JCTree.IMPORT); + l.nonEmpty() && (cdef == null || l.head.hasTag(IMPORT)); l = l.tail) { - if (l.head.getTag() == JCTree.IMPORT) { + if (l.head.hasTag(IMPORT)) { JCImport imp = (JCImport)l.head; Name name = TreeInfo.name(imp.qualid); if (name == name.table.names.asterisk || @@ -484,7 +486,7 @@ public class Pretty extends JCTree.Visitor { print("/*public static final*/ "); print(tree.name); if (tree.init != null) { - if (sourceOutput && tree.init.getTag() == JCTree.NEWCLASS) { + if (sourceOutput && tree.init.hasTag(NEWCLASS)) { print(" /*enum*/ "); JCNewClass init = (JCNewClass) tree.init; if (init.args != null && init.args.nonEmpty()) { @@ -545,7 +547,7 @@ public class Pretty extends JCTree.Visitor { printStat(tree.body); align(); print(" while "); - if (tree.cond.getTag() == JCTree.PARENS) { + if (tree.cond.hasTag(PARENS)) { printExpr(tree.cond); } else { print("("); @@ -561,7 +563,7 @@ public class Pretty extends JCTree.Visitor { public void visitWhileLoop(JCWhileLoop tree) { try { print("while "); - if (tree.cond.getTag() == JCTree.PARENS) { + if (tree.cond.hasTag(PARENS)) { printExpr(tree.cond); } else { print("("); @@ -579,7 +581,7 @@ public class Pretty extends JCTree.Visitor { try { print("for ("); if (tree.init.nonEmpty()) { - if (tree.init.head.getTag() == JCTree.VARDEF) { + if (tree.init.head.hasTag(VARDEF)) { printExpr(tree.init.head); for (List l = tree.init.tail; l.nonEmpty(); l = l.tail) { JCVariableDecl vdef = (JCVariableDecl)l.head; @@ -626,7 +628,7 @@ public class Pretty extends JCTree.Visitor { public void visitSwitch(JCSwitch tree) { try { print("switch "); - if (tree.selector.getTag() == JCTree.PARENS) { + if (tree.selector.hasTag(PARENS)) { printExpr(tree.selector); } else { print("("); @@ -665,7 +667,7 @@ public class Pretty extends JCTree.Visitor { public void visitSynchronized(JCSynchronized tree) { try { print("synchronized "); - if (tree.lock.getTag() == JCTree.PARENS) { + if (tree.lock.hasTag(PARENS)) { printExpr(tree.lock); } else { print("("); @@ -736,7 +738,7 @@ public class Pretty extends JCTree.Visitor { public void visitIf(JCIf tree) { try { print("if "); - if (tree.cond.getTag() == JCTree.PARENS) { + if (tree.cond.hasTag(PARENS)) { printExpr(tree.cond); } else { print("("); @@ -823,7 +825,7 @@ public class Pretty extends JCTree.Visitor { public void visitApply(JCMethodInvocation tree) { try { if (!tree.typeargs.isEmpty()) { - if (tree.meth.getTag() == JCTree.SELECT) { + if (tree.meth.hasTag(SELECT)) { JCFieldAccess left = (JCFieldAccess)tree.meth; printExpr(left.selected); print(".<"); @@ -882,7 +884,7 @@ public class Pretty extends JCTree.Visitor { if (tree.elemtype != null) { print("new "); JCTree elem = tree.elemtype; - if (elem.getTag() == JCTree.TYPEARRAY) + if (elem.hasTag(TYPEARRAY)) printBaseElementType((JCArrayTypeTree) elem); else printExpr(elem); @@ -927,36 +929,36 @@ public class Pretty extends JCTree.Visitor { } } - public String operatorName(int tag) { + public String operatorName(JCTree.Tag tag) { switch(tag) { - case JCTree.POS: return "+"; - case JCTree.NEG: return "-"; - case JCTree.NOT: return "!"; - case JCTree.COMPL: return "~"; - case JCTree.PREINC: return "++"; - case JCTree.PREDEC: return "--"; - case JCTree.POSTINC: return "++"; - case JCTree.POSTDEC: return "--"; - case JCTree.NULLCHK: return "<*nullchk*>"; - case JCTree.OR: return "||"; - case JCTree.AND: return "&&"; - case JCTree.EQ: return "=="; - case JCTree.NE: return "!="; - case JCTree.LT: return "<"; - case JCTree.GT: return ">"; - case JCTree.LE: return "<="; - case JCTree.GE: return ">="; - case JCTree.BITOR: return "|"; - case JCTree.BITXOR: return "^"; - case JCTree.BITAND: return "&"; - case JCTree.SL: return "<<"; - case JCTree.SR: return ">>"; - case JCTree.USR: return ">>>"; - case JCTree.PLUS: return "+"; - case JCTree.MINUS: return "-"; - case JCTree.MUL: return "*"; - case JCTree.DIV: return "/"; - case JCTree.MOD: return "%"; + case POS: return "+"; + case NEG: return "-"; + case NOT: return "!"; + case COMPL: return "~"; + case PREINC: return "++"; + case PREDEC: return "--"; + case POSTINC: return "++"; + case POSTDEC: return "--"; + case NULLCHK: return "<*nullchk*>"; + case OR: return "||"; + case AND: return "&&"; + case EQ: return "=="; + case NE: return "!="; + case LT: return "<"; + case GT: return ">"; + case LE: return "<="; + case GE: return ">="; + case BITOR: return "|"; + case BITXOR: return "^"; + case BITAND: return "&"; + case SL: return "<<"; + case SR: return ">>"; + case USR: return ">>>"; + case PLUS: return "+"; + case MINUS: return "-"; + case MUL: return "*"; + case DIV: return "/"; + case MOD: return "%"; default: throw new Error(); } } @@ -965,7 +967,7 @@ public class Pretty extends JCTree.Visitor { try { open(prec, TreeInfo.assignopPrec); printExpr(tree.lhs, TreeInfo.assignopPrec + 1); - print(" " + operatorName(tree.getTag() - JCTree.ASGOffset) + "= "); + print(" " + operatorName(tree.getTag().noAssignOp()) + "= "); printExpr(tree.rhs, TreeInfo.assignopPrec); close(prec, TreeInfo.assignopPrec); } catch (IOException e) { @@ -978,7 +980,7 @@ public class Pretty extends JCTree.Visitor { int ownprec = TreeInfo.opPrec(tree.getTag()); String opname = operatorName(tree.getTag()); open(prec, ownprec); - if (tree.getTag() <= JCTree.PREDEC) { + if (!tree.getTag().isPostUnaryOp()) { print(opname); printExpr(tree.arg, ownprec); } else { @@ -1153,7 +1155,7 @@ public class Pretty extends JCTree.Visitor { while (true) { elem = tree.elemtype; print("[]"); - if (elem.getTag() != JCTree.TYPEARRAY) break; + if (!elem.hasTag(TYPEARRAY)) break; tree = (JCArrayTypeTree) elem; } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java index 4b96be6d98a..158abc4f161 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -406,7 +406,7 @@ public class TreeCopier

implements TreeVisitor { public JCTree visitOther(Tree node, P p) { JCTree tree = (JCTree) node; switch (tree.getTag()) { - case JCTree.LETEXPR: { + case LETEXPR: { LetExpr t = (LetExpr) node; List defs = copy(t.defs, p); JCTree expr = copy(t.expr, p); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java index c37a561990c..0a9aa02bc54 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -35,6 +35,9 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.code.Flags.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; +import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK; +import static com.sun.tools.javac.tree.JCTree.Tag.SYNCHRONIZED; /** Utility class containing inspector methods for trees. * @@ -56,53 +59,60 @@ public class TreeInfo { /** The names of all operators. */ - private Name[] opname = new Name[JCTree.MOD - JCTree.POS + 1]; + private Name[] opname = new Name[Tag.getNumberOfOperators()]; + + private void setOpname(Tag tag, String name, Names names) { + setOpname(tag, names.fromString(name)); + } + private void setOpname(Tag tag, Name name) { + opname[tag.operatorIndex()] = name; + } private TreeInfo(Context context) { context.put(treeInfoKey, this); Names names = Names.instance(context); - opname[JCTree.POS - JCTree.POS] = names.fromString("+"); - opname[JCTree.NEG - JCTree.POS] = names.hyphen; - opname[JCTree.NOT - JCTree.POS] = names.fromString("!"); - opname[JCTree.COMPL - JCTree.POS] = names.fromString("~"); - opname[JCTree.PREINC - JCTree.POS] = names.fromString("++"); - opname[JCTree.PREDEC - JCTree.POS] = names.fromString("--"); - opname[JCTree.POSTINC - JCTree.POS] = names.fromString("++"); - opname[JCTree.POSTDEC - JCTree.POS] = names.fromString("--"); - opname[JCTree.NULLCHK - JCTree.POS] = names.fromString("<*nullchk*>"); - opname[JCTree.OR - JCTree.POS] = names.fromString("||"); - opname[JCTree.AND - JCTree.POS] = names.fromString("&&"); - opname[JCTree.EQ - JCTree.POS] = names.fromString("=="); - opname[JCTree.NE - JCTree.POS] = names.fromString("!="); - opname[JCTree.LT - JCTree.POS] = names.fromString("<"); - opname[JCTree.GT - JCTree.POS] = names.fromString(">"); - opname[JCTree.LE - JCTree.POS] = names.fromString("<="); - opname[JCTree.GE - JCTree.POS] = names.fromString(">="); - opname[JCTree.BITOR - JCTree.POS] = names.fromString("|"); - opname[JCTree.BITXOR - JCTree.POS] = names.fromString("^"); - opname[JCTree.BITAND - JCTree.POS] = names.fromString("&"); - opname[JCTree.SL - JCTree.POS] = names.fromString("<<"); - opname[JCTree.SR - JCTree.POS] = names.fromString(">>"); - opname[JCTree.USR - JCTree.POS] = names.fromString(">>>"); - opname[JCTree.PLUS - JCTree.POS] = names.fromString("+"); - opname[JCTree.MINUS - JCTree.POS] = names.hyphen; - opname[JCTree.MUL - JCTree.POS] = names.asterisk; - opname[JCTree.DIV - JCTree.POS] = names.slash; - opname[JCTree.MOD - JCTree.POS] = names.fromString("%"); + setOpname(POS, "+", names); + setOpname(NEG, names.hyphen); + setOpname(NOT, "!", names); + setOpname(COMPL, "~", names); + setOpname(PREINC, "++", names); + setOpname(PREDEC, "--", names); + setOpname(POSTINC, "++", names); + setOpname(POSTDEC, "--", names); + setOpname(NULLCHK, "<*nullchk*>", names); + setOpname(OR, "||", names); + setOpname(AND, "&&", names); + setOpname(EQ, "==", names); + setOpname(NE, "!=", names); + setOpname(LT, "<", names); + setOpname(GT, ">", names); + setOpname(LE, "<=", names); + setOpname(GE, ">=", names); + setOpname(BITOR, "|", names); + setOpname(BITXOR, "^", names); + setOpname(BITAND, "&", names); + setOpname(SL, "<<", names); + setOpname(SR, ">>", names); + setOpname(USR, ">>>", names); + setOpname(PLUS, "+", names); + setOpname(MINUS, names.hyphen); + setOpname(MUL, names.asterisk); + setOpname(DIV, names.slash); + setOpname(MOD, "%", names); } /** Return name of operator with given tree tag. */ - public Name operatorName(int tag) { - return opname[tag - JCTree.POS]; + public Name operatorName(JCTree.Tag tag) { + return opname[tag.operatorIndex()]; } /** Is tree a constructor declaration? */ public static boolean isConstructor(JCTree tree) { - if (tree.getTag() == JCTree.METHODDEF) { + if (tree.hasTag(METHODDEF)) { Name name = ((JCMethodDecl) tree).name; return name == name.table.names.init; } else { @@ -119,17 +129,17 @@ public class TreeInfo { } public static boolean isMultiCatch(JCCatch catchClause) { - return catchClause.param.vartype.getTag() == JCTree.TYPEUNION; + return catchClause.param.vartype.hasTag(TYPEUNION); } /** Is statement an initializer for a synthetic field? */ public static boolean isSyntheticInit(JCTree stat) { - if (stat.getTag() == JCTree.EXEC) { + if (stat.hasTag(EXEC)) { JCExpressionStatement exec = (JCExpressionStatement)stat; - if (exec.expr.getTag() == JCTree.ASSIGN) { + if (exec.expr.hasTag(ASSIGN)) { JCAssign assign = (JCAssign)exec.expr; - if (assign.lhs.getTag() == JCTree.SELECT) { + if (assign.lhs.hasTag(SELECT)) { JCFieldAccess select = (JCFieldAccess)assign.lhs; if (select.sym != null && (select.sym.flags() & SYNTHETIC) != 0) { @@ -146,9 +156,9 @@ public class TreeInfo { /** If the expression is a method call, return the method name, null * otherwise. */ public static Name calledMethodName(JCTree tree) { - if (tree.getTag() == JCTree.EXEC) { + if (tree.hasTag(EXEC)) { JCExpressionStatement exec = (JCExpressionStatement)tree; - if (exec.expr.getTag() == JCTree.APPLY) { + if (exec.expr.hasTag(APPLY)) { Name mname = TreeInfo.name(((JCMethodInvocation) exec.expr).meth); return mname; } @@ -192,7 +202,7 @@ public class TreeInfo { /** Return the first call in a constructor definition. */ public static JCMethodInvocation firstConstructorCall(JCTree tree) { - if (tree.getTag() != JCTree.METHODDEF) return null; + if (!tree.hasTag(METHODDEF)) return null; JCMethodDecl md = (JCMethodDecl) tree; Names names = md.name.table.names; if (md.name != names.init) return null; @@ -202,24 +212,24 @@ public class TreeInfo { while (stats.nonEmpty() && isSyntheticInit(stats.head)) stats = stats.tail; if (stats.isEmpty()) return null; - if (stats.head.getTag() != JCTree.EXEC) return null; + if (!stats.head.hasTag(EXEC)) return null; JCExpressionStatement exec = (JCExpressionStatement) stats.head; - if (exec.expr.getTag() != JCTree.APPLY) return null; + if (!exec.expr.hasTag(APPLY)) return null; return (JCMethodInvocation)exec.expr; } /** Return true if a tree represents a diamond new expr. */ public static boolean isDiamond(JCTree tree) { switch(tree.getTag()) { - case JCTree.TYPEAPPLY: return ((JCTypeApply)tree).getTypeArguments().isEmpty(); - case JCTree.NEWCLASS: return isDiamond(((JCNewClass)tree).clazz); + case TYPEAPPLY: return ((JCTypeApply)tree).getTypeArguments().isEmpty(); + case NEWCLASS: return isDiamond(((JCNewClass)tree).clazz); default: return false; } } /** Return true if a tree represents the null literal. */ public static boolean isNull(JCTree tree) { - if (tree.getTag() != JCTree.LITERAL) + if (!tree.hasTag(LITERAL)) return false; JCLiteral lit = (JCLiteral) tree; return (lit.typetag == TypeTags.BOT); @@ -229,7 +239,7 @@ public class TreeInfo { * the block itself if it is empty. */ public static int firstStatPos(JCTree tree) { - if (tree.getTag() == JCTree.BLOCK && ((JCBlock) tree).stats.nonEmpty()) + if (tree.hasTag(BLOCK) && ((JCBlock) tree).stats.nonEmpty()) return ((JCBlock) tree).stats.head.pos; else return tree.pos; @@ -239,11 +249,11 @@ public class TreeInfo { * defined endpos. */ public static int endPos(JCTree tree) { - if (tree.getTag() == JCTree.BLOCK && ((JCBlock) tree).endpos != Position.NOPOS) + if (tree.hasTag(BLOCK) && ((JCBlock) tree).endpos != Position.NOPOS) return ((JCBlock) tree).endpos; - else if (tree.getTag() == JCTree.SYNCHRONIZED) + else if (tree.hasTag(SYNCHRONIZED)) return endPos(((JCSynchronized) tree).body); - else if (tree.getTag() == JCTree.TRY) { + else if (tree.hasTag(TRY)) { JCTry t = (JCTry) tree; return endPos((t.finalizer != null) ? t.finalizer @@ -263,73 +273,73 @@ public class TreeInfo { return Position.NOPOS; switch(tree.getTag()) { - case(JCTree.APPLY): - return getStartPos(((JCMethodInvocation) tree).meth); - case(JCTree.ASSIGN): - return getStartPos(((JCAssign) tree).lhs); - case(JCTree.BITOR_ASG): case(JCTree.BITXOR_ASG): case(JCTree.BITAND_ASG): - case(JCTree.SL_ASG): case(JCTree.SR_ASG): case(JCTree.USR_ASG): - case(JCTree.PLUS_ASG): case(JCTree.MINUS_ASG): case(JCTree.MUL_ASG): - case(JCTree.DIV_ASG): case(JCTree.MOD_ASG): - return getStartPos(((JCAssignOp) tree).lhs); - case(JCTree.OR): case(JCTree.AND): case(JCTree.BITOR): - case(JCTree.BITXOR): case(JCTree.BITAND): case(JCTree.EQ): - case(JCTree.NE): case(JCTree.LT): case(JCTree.GT): - case(JCTree.LE): case(JCTree.GE): case(JCTree.SL): - case(JCTree.SR): case(JCTree.USR): case(JCTree.PLUS): - case(JCTree.MINUS): case(JCTree.MUL): case(JCTree.DIV): - case(JCTree.MOD): - return getStartPos(((JCBinary) tree).lhs); - case(JCTree.CLASSDEF): { - JCClassDecl node = (JCClassDecl)tree; - if (node.mods.pos != Position.NOPOS) - return node.mods.pos; - break; - } - case(JCTree.CONDEXPR): - return getStartPos(((JCConditional) tree).cond); - case(JCTree.EXEC): - return getStartPos(((JCExpressionStatement) tree).expr); - case(JCTree.INDEXED): - return getStartPos(((JCArrayAccess) tree).indexed); - case(JCTree.METHODDEF): { - JCMethodDecl node = (JCMethodDecl)tree; - if (node.mods.pos != Position.NOPOS) - return node.mods.pos; - if (node.typarams.nonEmpty()) // List.nil() used for no typarams - return getStartPos(node.typarams.head); - return node.restype == null ? node.pos : getStartPos(node.restype); - } - case(JCTree.SELECT): - return getStartPos(((JCFieldAccess) tree).selected); - case(JCTree.TYPEAPPLY): - return getStartPos(((JCTypeApply) tree).clazz); - case(JCTree.TYPEARRAY): - return getStartPos(((JCArrayTypeTree) tree).elemtype); - case(JCTree.TYPETEST): - return getStartPos(((JCInstanceOf) tree).expr); - case(JCTree.POSTINC): - case(JCTree.POSTDEC): - return getStartPos(((JCUnary) tree).arg); - case(JCTree.NEWCLASS): { - JCNewClass node = (JCNewClass)tree; - if (node.encl != null) - return getStartPos(node.encl); - break; - } - case(JCTree.VARDEF): { - JCVariableDecl node = (JCVariableDecl)tree; - if (node.mods.pos != Position.NOPOS) { - return node.mods.pos; - } else { - return getStartPos(node.vartype); + case APPLY: + return getStartPos(((JCMethodInvocation) tree).meth); + case ASSIGN: + return getStartPos(((JCAssign) tree).lhs); + case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG: + case SL_ASG: case SR_ASG: case USR_ASG: + case PLUS_ASG: case MINUS_ASG: case MUL_ASG: + case DIV_ASG: case MOD_ASG: + return getStartPos(((JCAssignOp) tree).lhs); + case OR: case AND: case BITOR: + case BITXOR: case BITAND: case EQ: + case NE: case LT: case GT: + case LE: case GE: case SL: + case SR: case USR: case PLUS: + case MINUS: case MUL: case DIV: + case MOD: + return getStartPos(((JCBinary) tree).lhs); + case CLASSDEF: { + JCClassDecl node = (JCClassDecl)tree; + if (node.mods.pos != Position.NOPOS) + return node.mods.pos; + break; + } + case CONDEXPR: + return getStartPos(((JCConditional) tree).cond); + case EXEC: + return getStartPos(((JCExpressionStatement) tree).expr); + case INDEXED: + return getStartPos(((JCArrayAccess) tree).indexed); + case METHODDEF: { + JCMethodDecl node = (JCMethodDecl)tree; + if (node.mods.pos != Position.NOPOS) + return node.mods.pos; + if (node.typarams.nonEmpty()) // List.nil() used for no typarams + return getStartPos(node.typarams.head); + return node.restype == null ? node.pos : getStartPos(node.restype); + } + case SELECT: + return getStartPos(((JCFieldAccess) tree).selected); + case TYPEAPPLY: + return getStartPos(((JCTypeApply) tree).clazz); + case TYPEARRAY: + return getStartPos(((JCArrayTypeTree) tree).elemtype); + case TYPETEST: + return getStartPos(((JCInstanceOf) tree).expr); + case POSTINC: + case POSTDEC: + return getStartPos(((JCUnary) tree).arg); + case NEWCLASS: { + JCNewClass node = (JCNewClass)tree; + if (node.encl != null) + return getStartPos(node.encl); + break; + } + case VARDEF: { + JCVariableDecl node = (JCVariableDecl)tree; + if (node.mods.pos != Position.NOPOS) { + return node.mods.pos; + } else { + return getStartPos(node.vartype); + } + } + case ERRONEOUS: { + JCErroneous node = (JCErroneous)tree; + if (node.errs != null && node.errs.nonEmpty()) + return getStartPos(node.errs.head); } - } - case(JCTree.ERRONEOUS): { - JCErroneous node = (JCErroneous)tree; - if (node.errs != null && node.errs.nonEmpty()) - return getStartPos(node.errs.head); - } } return tree.pos; } @@ -350,75 +360,75 @@ public class TreeInfo { return mapPos; switch(tree.getTag()) { - case(JCTree.BITOR_ASG): case(JCTree.BITXOR_ASG): case(JCTree.BITAND_ASG): - case(JCTree.SL_ASG): case(JCTree.SR_ASG): case(JCTree.USR_ASG): - case(JCTree.PLUS_ASG): case(JCTree.MINUS_ASG): case(JCTree.MUL_ASG): - case(JCTree.DIV_ASG): case(JCTree.MOD_ASG): - return getEndPos(((JCAssignOp) tree).rhs, endPositions); - case(JCTree.OR): case(JCTree.AND): case(JCTree.BITOR): - case(JCTree.BITXOR): case(JCTree.BITAND): case(JCTree.EQ): - case(JCTree.NE): case(JCTree.LT): case(JCTree.GT): - case(JCTree.LE): case(JCTree.GE): case(JCTree.SL): - case(JCTree.SR): case(JCTree.USR): case(JCTree.PLUS): - case(JCTree.MINUS): case(JCTree.MUL): case(JCTree.DIV): - case(JCTree.MOD): - return getEndPos(((JCBinary) tree).rhs, endPositions); - case(JCTree.CASE): - return getEndPos(((JCCase) tree).stats.last(), endPositions); - case(JCTree.CATCH): - return getEndPos(((JCCatch) tree).body, endPositions); - case(JCTree.CONDEXPR): - return getEndPos(((JCConditional) tree).falsepart, endPositions); - case(JCTree.FORLOOP): - return getEndPos(((JCForLoop) tree).body, endPositions); - case(JCTree.FOREACHLOOP): - return getEndPos(((JCEnhancedForLoop) tree).body, endPositions); - case(JCTree.IF): { - JCIf node = (JCIf)tree; - if (node.elsepart == null) { - return getEndPos(node.thenpart, endPositions); - } else { - return getEndPos(node.elsepart, endPositions); + case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG: + case SL_ASG: case SR_ASG: case USR_ASG: + case PLUS_ASG: case MINUS_ASG: case MUL_ASG: + case DIV_ASG: case MOD_ASG: + return getEndPos(((JCAssignOp) tree).rhs, endPositions); + case OR: case AND: case BITOR: + case BITXOR: case BITAND: case EQ: + case NE: case LT: case GT: + case LE: case GE: case SL: + case SR: case USR: case PLUS: + case MINUS: case MUL: case DIV: + case MOD: + return getEndPos(((JCBinary) tree).rhs, endPositions); + case CASE: + return getEndPos(((JCCase) tree).stats.last(), endPositions); + case CATCH: + return getEndPos(((JCCatch) tree).body, endPositions); + case CONDEXPR: + return getEndPos(((JCConditional) tree).falsepart, endPositions); + case FORLOOP: + return getEndPos(((JCForLoop) tree).body, endPositions); + case FOREACHLOOP: + return getEndPos(((JCEnhancedForLoop) tree).body, endPositions); + case IF: { + JCIf node = (JCIf)tree; + if (node.elsepart == null) { + return getEndPos(node.thenpart, endPositions); + } else { + return getEndPos(node.elsepart, endPositions); + } } - } - case(JCTree.LABELLED): - return getEndPos(((JCLabeledStatement) tree).body, endPositions); - case(JCTree.MODIFIERS): - return getEndPos(((JCModifiers) tree).annotations.last(), endPositions); - case(JCTree.SYNCHRONIZED): - return getEndPos(((JCSynchronized) tree).body, endPositions); - case(JCTree.TOPLEVEL): - return getEndPos(((JCCompilationUnit) tree).defs.last(), endPositions); - case(JCTree.TRY): { - JCTry node = (JCTry)tree; - if (node.finalizer != null) { - return getEndPos(node.finalizer, endPositions); - } else if (!node.catchers.isEmpty()) { - return getEndPos(node.catchers.last(), endPositions); - } else { - return getEndPos(node.body, endPositions); + case LABELLED: + return getEndPos(((JCLabeledStatement) tree).body, endPositions); + case MODIFIERS: + return getEndPos(((JCModifiers) tree).annotations.last(), endPositions); + case SYNCHRONIZED: + return getEndPos(((JCSynchronized) tree).body, endPositions); + case TOPLEVEL: + return getEndPos(((JCCompilationUnit) tree).defs.last(), endPositions); + case TRY: { + JCTry node = (JCTry)tree; + if (node.finalizer != null) { + return getEndPos(node.finalizer, endPositions); + } else if (!node.catchers.isEmpty()) { + return getEndPos(node.catchers.last(), endPositions); + } else { + return getEndPos(node.body, endPositions); + } + } + case WILDCARD: + return getEndPos(((JCWildcard) tree).inner, endPositions); + case TYPECAST: + return getEndPos(((JCTypeCast) tree).expr, endPositions); + case TYPETEST: + return getEndPos(((JCInstanceOf) tree).clazz, endPositions); + case POS: + case NEG: + case NOT: + case COMPL: + case PREINC: + case PREDEC: + return getEndPos(((JCUnary) tree).arg, endPositions); + case WHILELOOP: + return getEndPos(((JCWhileLoop) tree).body, endPositions); + case ERRONEOUS: { + JCErroneous node = (JCErroneous)tree; + if (node.errs != null && node.errs.nonEmpty()) + return getEndPos(node.errs.last(), endPositions); } - } - case(JCTree.WILDCARD): - return getEndPos(((JCWildcard) tree).inner, endPositions); - case(JCTree.TYPECAST): - return getEndPos(((JCTypeCast) tree).expr, endPositions); - case(JCTree.TYPETEST): - return getEndPos(((JCInstanceOf) tree).clazz, endPositions); - case(JCTree.POS): - case(JCTree.NEG): - case(JCTree.NOT): - case(JCTree.COMPL): - case(JCTree.PREINC): - case(JCTree.PREDEC): - return getEndPos(((JCUnary) tree).arg, endPositions); - case(JCTree.WHILELOOP): - return getEndPos(((JCWhileLoop) tree).body, endPositions); - case(JCTree.ERRONEOUS): { - JCErroneous node = (JCErroneous)tree; - if (node.errs != null && node.errs.nonEmpty()) - return getEndPos(node.errs.last(), endPositions); - } } return Position.NOPOS; } @@ -443,11 +453,11 @@ public class TreeInfo { /** The position of the finalizer of given try/synchronized statement. */ public static int finalizerPos(JCTree tree) { - if (tree.getTag() == JCTree.TRY) { + if (tree.hasTag(TRY)) { JCTry t = (JCTry) tree; Assert.checkNonNull(t.finalizer); return firstStatPos(t.finalizer); - } else if (tree.getTag() == JCTree.SYNCHRONIZED) { + } else if (tree.hasTag(SYNCHRONIZED)) { return endPos(((JCSynchronized) tree).body); } else { throw new AssertionError(); @@ -547,9 +557,9 @@ public class TreeInfo { public static JCTree referencedStatement(JCLabeledStatement tree) { JCTree t = tree; do t = ((JCLabeledStatement) t).body; - while (t.getTag() == JCTree.LABELLED); + while (t.hasTag(LABELLED)); switch (t.getTag()) { - case JCTree.DOLOOP: case JCTree.WHILELOOP: case JCTree.FORLOOP: case JCTree.FOREACHLOOP: case JCTree.SWITCH: + case DOLOOP: case WHILELOOP: case FORLOOP: case FOREACHLOOP: case SWITCH: return t; default: return tree; @@ -559,7 +569,7 @@ public class TreeInfo { /** Skip parens and return the enclosed expression */ public static JCExpression skipParens(JCExpression tree) { - while (tree.getTag() == JCTree.PARENS) { + while (tree.hasTag(PARENS)) { tree = ((JCParens) tree).expr; } return tree; @@ -568,7 +578,7 @@ public class TreeInfo { /** Skip parens and return the enclosed expression */ public static JCTree skipParens(JCTree tree) { - if (tree.getTag() == JCTree.PARENS) + if (tree.hasTag(PARENS)) return skipParens((JCParens)tree); else return tree; @@ -588,11 +598,11 @@ public class TreeInfo { */ public static Name name(JCTree tree) { switch (tree.getTag()) { - case JCTree.IDENT: + case IDENT: return ((JCIdent) tree).name; - case JCTree.SELECT: + case SELECT: return ((JCFieldAccess) tree).name; - case JCTree.TYPEAPPLY: + case TYPEAPPLY: return name(((JCTypeApply) tree).clazz); default: return null; @@ -605,9 +615,9 @@ public class TreeInfo { public static Name fullName(JCTree tree) { tree = skipParens(tree); switch (tree.getTag()) { - case JCTree.IDENT: + case IDENT: return ((JCIdent) tree).name; - case JCTree.SELECT: + case SELECT: Name sname = fullName(((JCFieldAccess) tree).selected); return sname == null ? null : sname.append('.', name(tree)); default: @@ -618,11 +628,11 @@ public class TreeInfo { public static Symbol symbolFor(JCTree node) { node = skipParens(node); switch (node.getTag()) { - case JCTree.CLASSDEF: + case CLASSDEF: return ((JCClassDecl) node).sym; - case JCTree.METHODDEF: + case METHODDEF: return ((JCMethodDecl) node).sym; - case JCTree.VARDEF: + case VARDEF: return ((JCVariableDecl) node).sym; default: return null; @@ -632,9 +642,9 @@ public class TreeInfo { public static boolean isDeclaration(JCTree node) { node = skipParens(node); switch (node.getTag()) { - case JCTree.CLASSDEF: - case JCTree.METHODDEF: - case JCTree.VARDEF: + case CLASSDEF: + case METHODDEF: + case VARDEF: return true; default: return false; @@ -647,11 +657,11 @@ public class TreeInfo { public static Symbol symbol(JCTree tree) { tree = skipParens(tree); switch (tree.getTag()) { - case JCTree.IDENT: + case IDENT: return ((JCIdent) tree).sym; - case JCTree.SELECT: + case SELECT: return ((JCFieldAccess) tree).sym; - case JCTree.TYPEAPPLY: + case TYPEAPPLY: return symbol(((JCTypeApply) tree).clazz); default: return null; @@ -661,7 +671,7 @@ public class TreeInfo { /** Return true if this is a nonstatic selection. */ public static boolean nonstaticSelect(JCTree tree) { tree = skipParens(tree); - if (tree.getTag() != JCTree.SELECT) return false; + if (!tree.hasTag(SELECT)) return false; JCFieldAccess s = (JCFieldAccess) tree; Symbol e = symbol(s.selected); return e == null || (e.kind != Kinds.PCK && e.kind != Kinds.TYP); @@ -672,9 +682,9 @@ public class TreeInfo { public static void setSymbol(JCTree tree, Symbol sym) { tree = skipParens(tree); switch (tree.getTag()) { - case JCTree.IDENT: + case IDENT: ((JCIdent) tree).sym = sym; break; - case JCTree.SELECT: + case SELECT: ((JCFieldAccess) tree).sym = sym; break; default: } @@ -685,13 +695,13 @@ public class TreeInfo { */ public static long flags(JCTree tree) { switch (tree.getTag()) { - case JCTree.VARDEF: + case VARDEF: return ((JCVariableDecl) tree).mods.flags; - case JCTree.METHODDEF: + case METHODDEF: return ((JCMethodDecl) tree).mods.flags; - case JCTree.CLASSDEF: + case CLASSDEF: return ((JCClassDecl) tree).mods.flags; - case JCTree.BLOCK: + case BLOCK: return ((JCBlock) tree).flags; default: return 0; @@ -739,155 +749,155 @@ public class TreeInfo { /** Map operators to their precedence levels. */ - public static int opPrec(int op) { + public static int opPrec(JCTree.Tag op) { switch(op) { - case JCTree.POS: - case JCTree.NEG: - case JCTree.NOT: - case JCTree.COMPL: - case JCTree.PREINC: - case JCTree.PREDEC: return prefixPrec; - case JCTree.POSTINC: - case JCTree.POSTDEC: - case JCTree.NULLCHK: return postfixPrec; - case JCTree.ASSIGN: return assignPrec; - case JCTree.BITOR_ASG: - case JCTree.BITXOR_ASG: - case JCTree.BITAND_ASG: - case JCTree.SL_ASG: - case JCTree.SR_ASG: - case JCTree.USR_ASG: - case JCTree.PLUS_ASG: - case JCTree.MINUS_ASG: - case JCTree.MUL_ASG: - case JCTree.DIV_ASG: - case JCTree.MOD_ASG: return assignopPrec; - case JCTree.OR: return orPrec; - case JCTree.AND: return andPrec; - case JCTree.EQ: - case JCTree.NE: return eqPrec; - case JCTree.LT: - case JCTree.GT: - case JCTree.LE: - case JCTree.GE: return ordPrec; - case JCTree.BITOR: return bitorPrec; - case JCTree.BITXOR: return bitxorPrec; - case JCTree.BITAND: return bitandPrec; - case JCTree.SL: - case JCTree.SR: - case JCTree.USR: return shiftPrec; - case JCTree.PLUS: - case JCTree.MINUS: return addPrec; - case JCTree.MUL: - case JCTree.DIV: - case JCTree.MOD: return mulPrec; - case JCTree.TYPETEST: return ordPrec; + case POS: + case NEG: + case NOT: + case COMPL: + case PREINC: + case PREDEC: return prefixPrec; + case POSTINC: + case POSTDEC: + case NULLCHK: return postfixPrec; + case ASSIGN: return assignPrec; + case BITOR_ASG: + case BITXOR_ASG: + case BITAND_ASG: + case SL_ASG: + case SR_ASG: + case USR_ASG: + case PLUS_ASG: + case MINUS_ASG: + case MUL_ASG: + case DIV_ASG: + case MOD_ASG: return assignopPrec; + case OR: return orPrec; + case AND: return andPrec; + case EQ: + case NE: return eqPrec; + case LT: + case GT: + case LE: + case GE: return ordPrec; + case BITOR: return bitorPrec; + case BITXOR: return bitxorPrec; + case BITAND: return bitandPrec; + case SL: + case SR: + case USR: return shiftPrec; + case PLUS: + case MINUS: return addPrec; + case MUL: + case DIV: + case MOD: return mulPrec; + case TYPETEST: return ordPrec; default: throw new AssertionError(); } } - static Tree.Kind tagToKind(int tag) { + static Tree.Kind tagToKind(JCTree.Tag tag) { switch (tag) { // Postfix expressions - case JCTree.POSTINC: // _ ++ + case POSTINC: // _ ++ return Tree.Kind.POSTFIX_INCREMENT; - case JCTree.POSTDEC: // _ -- + case POSTDEC: // _ -- return Tree.Kind.POSTFIX_DECREMENT; // Unary operators - case JCTree.PREINC: // ++ _ + case PREINC: // ++ _ return Tree.Kind.PREFIX_INCREMENT; - case JCTree.PREDEC: // -- _ + case PREDEC: // -- _ return Tree.Kind.PREFIX_DECREMENT; - case JCTree.POS: // + + case POS: // + return Tree.Kind.UNARY_PLUS; - case JCTree.NEG: // - + case NEG: // - return Tree.Kind.UNARY_MINUS; - case JCTree.COMPL: // ~ + case COMPL: // ~ return Tree.Kind.BITWISE_COMPLEMENT; - case JCTree.NOT: // ! + case NOT: // ! return Tree.Kind.LOGICAL_COMPLEMENT; // Binary operators // Multiplicative operators - case JCTree.MUL: // * + case MUL: // * return Tree.Kind.MULTIPLY; - case JCTree.DIV: // / + case DIV: // / return Tree.Kind.DIVIDE; - case JCTree.MOD: // % + case MOD: // % return Tree.Kind.REMAINDER; // Additive operators - case JCTree.PLUS: // + + case PLUS: // + return Tree.Kind.PLUS; - case JCTree.MINUS: // - + case MINUS: // - return Tree.Kind.MINUS; // Shift operators - case JCTree.SL: // << + case SL: // << return Tree.Kind.LEFT_SHIFT; - case JCTree.SR: // >> + case SR: // >> return Tree.Kind.RIGHT_SHIFT; - case JCTree.USR: // >>> + case USR: // >>> return Tree.Kind.UNSIGNED_RIGHT_SHIFT; // Relational operators - case JCTree.LT: // < + case LT: // < return Tree.Kind.LESS_THAN; - case JCTree.GT: // > + case GT: // > return Tree.Kind.GREATER_THAN; - case JCTree.LE: // <= + case LE: // <= return Tree.Kind.LESS_THAN_EQUAL; - case JCTree.GE: // >= + case GE: // >= return Tree.Kind.GREATER_THAN_EQUAL; // Equality operators - case JCTree.EQ: // == + case EQ: // == return Tree.Kind.EQUAL_TO; - case JCTree.NE: // != + case NE: // != return Tree.Kind.NOT_EQUAL_TO; // Bitwise and logical operators - case JCTree.BITAND: // & + case BITAND: // & return Tree.Kind.AND; - case JCTree.BITXOR: // ^ + case BITXOR: // ^ return Tree.Kind.XOR; - case JCTree.BITOR: // | + case BITOR: // | return Tree.Kind.OR; // Conditional operators - case JCTree.AND: // && + case AND: // && return Tree.Kind.CONDITIONAL_AND; - case JCTree.OR: // || + case OR: // || return Tree.Kind.CONDITIONAL_OR; // Assignment operators - case JCTree.MUL_ASG: // *= + case MUL_ASG: // *= return Tree.Kind.MULTIPLY_ASSIGNMENT; - case JCTree.DIV_ASG: // /= + case DIV_ASG: // /= return Tree.Kind.DIVIDE_ASSIGNMENT; - case JCTree.MOD_ASG: // %= + case MOD_ASG: // %= return Tree.Kind.REMAINDER_ASSIGNMENT; - case JCTree.PLUS_ASG: // += + case PLUS_ASG: // += return Tree.Kind.PLUS_ASSIGNMENT; - case JCTree.MINUS_ASG: // -= + case MINUS_ASG: // -= return Tree.Kind.MINUS_ASSIGNMENT; - case JCTree.SL_ASG: // <<= + case SL_ASG: // <<= return Tree.Kind.LEFT_SHIFT_ASSIGNMENT; - case JCTree.SR_ASG: // >>= + case SR_ASG: // >>= return Tree.Kind.RIGHT_SHIFT_ASSIGNMENT; - case JCTree.USR_ASG: // >>>= + case USR_ASG: // >>>= return Tree.Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT; - case JCTree.BITAND_ASG: // &= + case BITAND_ASG: // &= return Tree.Kind.AND_ASSIGNMENT; - case JCTree.BITXOR_ASG: // ^= + case BITXOR_ASG: // ^= return Tree.Kind.XOR_ASSIGNMENT; - case JCTree.BITOR_ASG: // |= + case BITOR_ASG: // |= return Tree.Kind.OR_ASSIGNMENT; // Null check (implementation detail), for example, __.getClass() - case JCTree.NULLCHK: + case NULLCHK: return Tree.Kind.OTHER; default: @@ -901,13 +911,13 @@ public class TreeInfo { */ public static JCExpression typeIn(JCExpression tree) { switch (tree.getTag()) { - case JCTree.IDENT: /* simple names */ - case JCTree.TYPEIDENT: /* primitive name */ - case JCTree.SELECT: /* qualified name */ - case JCTree.TYPEARRAY: /* array types */ - case JCTree.WILDCARD: /* wild cards */ - case JCTree.TYPEPARAMETER: /* type parameters */ - case JCTree.TYPEAPPLY: /* parameterized types */ + case IDENT: /* simple names */ + case TYPEIDENT: /* primitive name */ + case SELECT: /* qualified name */ + case TYPEARRAY: /* array types */ + case WILDCARD: /* wild cards */ + case TYPEPARAMETER: /* type parameters */ + case TYPEAPPLY: /* parameterized types */ return tree; default: throw new AssertionError("Unexpected type tree: " + tree); @@ -916,9 +926,9 @@ public class TreeInfo { public static JCTree innermostType(JCTree type) { switch (type.getTag()) { - case JCTree.TYPEARRAY: + case TYPEARRAY: return innermostType(((JCArrayTypeTree)type).elemtype); - case JCTree.WILDCARD: + case WILDCARD: return innermostType(((JCWildcard)type).inner); default: return type; diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index e3f18a08043..7f673023def 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -363,19 +363,19 @@ public class TreeMaker implements JCTree.Factory { return tree; } - public JCAssignOp Assignop(int opcode, JCTree lhs, JCTree rhs) { + public JCAssignOp Assignop(JCTree.Tag opcode, JCTree lhs, JCTree rhs) { JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null); tree.pos = pos; return tree; } - public JCUnary Unary(int opcode, JCExpression arg) { + public JCUnary Unary(JCTree.Tag opcode, JCExpression arg) { JCUnary tree = new JCUnary(opcode, arg); tree.pos = pos; return tree; } - public JCBinary Binary(int opcode, JCExpression lhs, JCExpression rhs) { + public JCBinary Binary(JCTree.Tag opcode, JCExpression lhs, JCExpression rhs) { JCBinary tree = new JCBinary(opcode, lhs, rhs, null); tree.pos = pos; return tree; diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java index 592d0beb6e5..a5fed4b059c 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java @@ -65,6 +65,7 @@ import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Position; import static com.sun.tools.javac.code.Kinds.*; +import static com.sun.tools.javac.tree.JCTree.Tag.*; /** * Represents a java class and provides access to information @@ -1083,7 +1084,7 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc { Name asterisk = tsym.name.table.names.asterisk; for (JCTree t : compenv.toplevel.defs) { - if (t.getTag() == JCTree.IMPORT) { + if (t.hasTag(IMPORT)) { JCTree imp = ((JCImport) t).qualid; if ((TreeInfo.name(imp) != asterisk) && (imp.type.tsym.kind & Kinds.TYP) != 0) { @@ -1124,7 +1125,7 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc { if (compenv == null) return new PackageDocImpl[0]; for (JCTree t : compenv.toplevel.defs) { - if (t.getTag() == JCTree.IMPORT) { + if (t.hasTag(IMPORT)) { JCTree imp = ((JCImport) t).qualid; if (TreeInfo.name(imp) == names.asterisk) { JCFieldAccess sel = (JCFieldAccess)imp; diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java index a5592acf8ad..81bcdbd3008 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java @@ -419,7 +419,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { ListBuffer result = new ListBuffer(); for (JCCompilationUnit t : trees) { for (JCTree def : t.defs) { - if (def.getTag() == JCTree.CLASSDEF) + if (def.hasTag(JCTree.Tag.CLASSDEF)) result.append((JCClassDecl)def); } } diff --git a/langtools/test/Makefile b/langtools/test/Makefile index 7f6435f037c..8964a006ffb 100644 --- a/langtools/test/Makefile +++ b/langtools/test/Makefile @@ -19,6 +19,7 @@ # Get OS/ARCH specifics OSNAME = $(shell uname -s) ifeq ($(OSNAME), SunOS) + SLASH_JAVA = /java PLATFORM = solaris JT_PLATFORM = solaris ARCH = $(shell uname -p) @@ -27,6 +28,7 @@ ifeq ($(OSNAME), SunOS) endif endif ifeq ($(OSNAME), Linux) + SLASH_JAVA = /java PLATFORM = linux JT_PLATFORM = linux ARCH = $(shell uname -m) @@ -35,7 +37,16 @@ ifeq ($(OSNAME), Linux) endif endif ifeq ($(OSNAME), Windows_NT) + # MKS + PLATFORM=windows +endif +ifeq ($(PLATFORM),) PLATFORM = windows + CYGPATH = | cygpath -m -s -f - +endif + +ifeq ($(PLATFORM), windows) + SLASH_JAVA = J: JT_PLATFORM = win32 ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64) ARCH=ia64 @@ -54,7 +65,7 @@ ifeq ($(OSNAME), Windows_NT) endif # Root of this test area (important to use full paths in some places) -TEST_ROOT := $(shell pwd) +TEST_ROOT := $(shell pwd $(CYGPATH) ) # Default bundle of all test results (passed or not) (JPRT only) ifdef JPRT_JOB_ID @@ -72,7 +83,7 @@ endif ifdef JPRT_JTREG_HOME JTREG_HOME = $(JPRT_JTREG_HOME) else - JTREG_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg + JTREG_HOME = $(SLASH_JAVA)/re/jtreg/4.1/promoted/latest/binaries/jtreg endif JTREG = $(JTREG_HOME)/$(JT_PLATFORM)/bin/jtreg JTDIFF = $(JTREG_HOME)/$(JT_PLATFORM)/bin/jtdiff @@ -81,7 +92,7 @@ JTDIFF = $(JTREG_HOME)/$(JT_PLATFORM)/bin/jtdiff ifdef JPRT_JCK_HOME JCK_HOME = $(JPRT_JCK_HOME) else - JCK_HOME = $(SLASH_JAVA)/re/jck/7/promoted/latest/binaries + JCK_HOME = $(SLASH_JAVA)/re/jck/8/promoted/latest/binaries endif # Default JDK for JTREG and JCK @@ -93,7 +104,7 @@ endif ifdef JPRT_JAVA_HOME JT_JAVA = $(JPRT_JAVA_HOME) else - JT_JAVA = $(SLASH_JAVA)/re/jdk/1.6.0/archive/fcs/binaries/$(PLATFORM)-$(ARCH) + JT_JAVA = $(SLASH_JAVA)/re/jdk/1.7.0/archive/fcs/binaries/$(PLATFORM)-$(ARCH) endif # Default JDK to test @@ -195,7 +206,7 @@ TEST_OUTPUT_DIR = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)/test/langtools ABS_TEST_OUTPUT_DIR := \ $(shell mkdir -p $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)/test/langtools; \ cd $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)/test/langtools; \ - pwd ) + pwd $(CYGPATH)) # Subdirectories for different test runs JTREG_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jtreg JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler @@ -272,15 +283,17 @@ jtreg-summary: FRC fi # Check to make sure these directories exist -check-jtreg: $(JT_HOME) $(PRODUCT_HOME) $(JTREG) +check-jtreg: $(PRODUCT_HOME) $(JTREG) # Run JCK-compiler tests # # JCK_HOME # Installed location of JCK: should include JCK-compiler, and JCK-extras +# Default is JCK 8. # JT_JAVA # Version of java used to run JCK. Should normally be the same as TESTJAVA +# Default is JDK 7 # TESTJAVA # Version of java to be tested. # JCK_COMPILER_OPTIONS @@ -297,7 +310,7 @@ jck-compiler-tests: check-jck FRC $(JCK_COMPILER_OUTPUT_DIR)/diff.html $(JCK_COMPILER_OUTPUT_DIR)/status.txt @mkdir -p $(JCK_COMPILER_OUTPUT_DIR) $(JT_JAVA)/bin/java -XX:MaxPermSize=256m -Xmx512m \ - -jar $(JCK_HOME)/JCK-compiler-7/lib/jtjck.jar \ + -jar $(JCK_HOME)/JCK-compiler-8/lib/jtjck.jar \ -v:non-pass \ -r:$(JCK_COMPILER_OUTPUT_DIR)/report \ -w:$(JCK_COMPILER_OUTPUT_DIR)/work \ @@ -346,7 +359,7 @@ jck-runtime-tests: check-jck FRC $(JCK_RUNTIME_OUTPUT_DIR)/diff.html $(JCK_RUNTIME_OUTPUT_DIR)/status.txt @mkdir -p $(JCK_RUNTIME_OUTPUT_DIR) $(JT_JAVA)/bin/java -XX:MaxPermSize=256m -Xmx512m \ - -jar $(JCK_HOME)/JCK-runtime-7/lib/jtjck.jar \ + -jar $(JCK_HOME)/JCK-runtime-8/lib/jtjck.jar \ -v:non-pass \ -r:$(JCK_RUNTIME_OUTPUT_DIR)/report \ -w:$(JCK_RUNTIME_OUTPUT_DIR)/work \ @@ -373,7 +386,7 @@ jck-runtime-summary: FRC fi # Check to make sure these directories exist -check-jck: $(JT_HOME) $(JCK_HOME) $(PRODUCT_HOME) +check-jck: $(JCK_HOME) $(PRODUCT_HOME) all-summary: FRC if [ -n "`find $(TEST_OUTPUT_DIR) -name status.txt`" ]; then diff --git a/langtools/test/tools/javac/depDocComment/DeprecatedDocComment4.java b/langtools/test/tools/javac/depDocComment/DeprecatedDocComment4.java new file mode 100644 index 00000000000..9e7d93662e3 --- /dev/null +++ b/langtools/test/tools/javac/depDocComment/DeprecatedDocComment4.java @@ -0,0 +1,20 @@ +/** + * @test /nodynamiccopyright/ + * @bug 7104201 + * @summary Refactor DocCommentScanner + * @compile/fail/ref=DeprecatedDocComment4.out -XDrawDiagnostics -Werror -Xlint:dep-ann DeprecatedDocComment4.java + */ + +class DeprecatedDocComment4 { + /** @deprecated **/ + /* block */ + void test1() {}; + + /** @deprecated **/ + /** double javadoc */ + void test2() {}; + + /** @deprecated **/ + //line comment + void test3() {}; +} diff --git a/langtools/test/tools/javac/depDocComment/DeprecatedDocComment4.out b/langtools/test/tools/javac/depDocComment/DeprecatedDocComment4.out new file mode 100644 index 00000000000..88622ac0015 --- /dev/null +++ b/langtools/test/tools/javac/depDocComment/DeprecatedDocComment4.out @@ -0,0 +1,6 @@ +DeprecatedDocComment4.java:11:10: compiler.warn.missing.deprecated.annotation +DeprecatedDocComment4.java:15:10: compiler.warn.missing.deprecated.annotation +DeprecatedDocComment4.java:19:10: compiler.warn.missing.deprecated.annotation +- compiler.err.warnings.and.werror +1 error +3 warnings diff --git a/langtools/test/tools/javac/failover/CheckAttributedTree.java b/langtools/test/tools/javac/failover/CheckAttributedTree.java index e249689a41a..a134c8ac4e2 100644 --- a/langtools/test/tools/javac/failover/CheckAttributedTree.java +++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,6 +85,8 @@ import java.util.HashSet; import java.util.Set; import javax.lang.model.element.Element; +import static com.sun.tools.javac.tree.JCTree.Tag.*; + /** * Utility and test program to check validity of tree positions for tree nodes. * The program can be run standalone, or as a jtreg test. In standalone mode, @@ -289,7 +291,7 @@ public class CheckAttributedTree { for (CompilationUnitTree t : trees) { JCCompilationUnit cu = (JCCompilationUnit)t; for (JCTree def : cu.defs) { - if (def.getTag() == JCTree.CLASSDEF && + if (def.hasTag(CLASSDEF) && analyzedElems.contains(((JCTree.JCClassDecl)def).sym)) { //System.out.println("Adding pair..."); res.add(new Pair<>(cu, def)); @@ -373,9 +375,9 @@ public class CheckAttributedTree { private boolean mandatoryType(JCTree that) { return that instanceof JCTree.JCExpression || - that.getTag() == JCTree.VARDEF || - that.getTag() == JCTree.METHODDEF || - that.getTag() == JCTree.CLASSDEF; + that.hasTag(VARDEF) || + that.hasTag(METHODDEF) || + that.hasTag(CLASSDEF); } private final List excludedFields = Arrays.asList("varargsElement"); @@ -429,7 +431,7 @@ public class CheckAttributedTree { private class Info { Info() { tree = null; - tag = JCTree.ERRONEOUS; + tag = ERRONEOUS; start = 0; pos = 0; end = Integer.MAX_VALUE; @@ -449,7 +451,7 @@ public class CheckAttributedTree { } final JCTree tree; - final int tag; + final JCTree.Tag tag; final int start; final int pos; final int end; @@ -457,27 +459,10 @@ public class CheckAttributedTree { /** * Names for tree tags. - * javac does not provide an API to convert tag values to strings, so this class uses - * reflection to determine names of public static final int values in JCTree. */ private static class TreeUtil { - String nameFromTag(int tag) { - if (names == null) { - names = new HashMap(); - Class c = JCTree.class; - for (Field f : c.getDeclaredFields()) { - if (f.getType().equals(int.class)) { - int mods = f.getModifiers(); - if (Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) { - try { - names.put(f.getInt(null), f.getName()); - } catch (IllegalAccessException e) { - } - } - } - } - } - String name = names.get(tag); + String nameFromTag(JCTree.Tag tag) { + String name = tag.name(); return (name == null) ? "??" : name; } @@ -496,8 +481,6 @@ public class CheckAttributedTree { } return buf; } - - private Map names; } /** diff --git a/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java b/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java index b0fe687fdff..1d5ec84716f 100644 --- a/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java +++ b/langtools/test/tools/javac/tree/AbstractTreeScannerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -274,7 +274,7 @@ public abstract class AbstractTreeScannerTest { return fields; } // where - Map> map = new HashMap>(); + Map> map = new HashMap>(); /** Get the line number for the primary position for a tree. * The code is intended to be simple, although not necessarily efficient. diff --git a/langtools/test/tools/javac/tree/TreePosTest.java b/langtools/test/tools/javac/tree/TreePosTest.java index bb6e466b557..d32e5f0d990 100644 --- a/langtools/test/tools/javac/tree/TreePosTest.java +++ b/langtools/test/tools/javac/tree/TreePosTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,6 +80,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; +import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.util.Position.NOPOS; /** @@ -291,6 +292,14 @@ public class TreePosTest { errors++; } + /** + * Names for tree tags. + */ + private static String getTagName(JCTree.Tag tag) { + String name = tag.name(); + return (name == null) ? "??" : name; + } + /** Number of files that have been analyzed. */ int fileCount; /** Number of errors reported. */ @@ -312,8 +321,6 @@ public class TreePosTest { Set excludeFiles = new HashSet(); /** Set of tag names to be excluded from analysis. */ Set excludeTags = new HashSet(); - /** Table of printable names for tree tag values. */ - TagNames tagNames = new TagNames(); /** * Main class for testing assertions concerning tree positions for tree nodes. @@ -337,7 +344,7 @@ public class TreePosTest { // there is no corresponding source text. // Redundant semicolons in a class definition can cause empty // initializer blocks with no positions. - if ((self.tag == JCTree.MODIFIERS || self.tag == JCTree.BLOCK) + if ((self.tag == MODIFIERS || self.tag == BLOCK) && self.pos == NOPOS) { // If pos is NOPOS, so should be the start and end positions check("start == NOPOS", encl, self, self.start == NOPOS); @@ -359,15 +366,15 @@ public class TreePosTest { // e.g. int[][] a = new int[2][]; check("encl.start <= start", encl, self, encl.start <= self.start); check("start <= pos", encl, self, self.start <= self.pos); - if (!(self.tag == JCTree.TYPEARRAY - && (encl.tag == JCTree.VARDEF || - encl.tag == JCTree.METHODDEF || - encl.tag == JCTree.TYPEARRAY))) { + if (!(self.tag == TYPEARRAY + && (encl.tag == VARDEF || + encl.tag == METHODDEF || + encl.tag == TYPEARRAY))) { check("encl.pos <= start || end <= encl.pos", encl, self, encl.pos <= self.start || self.end <= encl.pos); } check("pos <= end", encl, self, self.pos <= self.end); - if (!(self.tag == JCTree.TYPEARRAY && encl.tag == JCTree.TYPEARRAY)) { + if (!(self.tag == TYPEARRAY && encl.tag == TYPEARRAY)) { check("end <= encl.end", encl, self, self.end <= encl.end); } } @@ -388,7 +395,7 @@ public class TreePosTest { if ((tree.mods.flags & Flags.ENUM) != 0) { scan(tree.mods); if (tree.init != null) { - if (tree.init.getTag() == JCTree.NEWCLASS) { + if (tree.init.hasTag(NEWCLASS)) { JCNewClass init = (JCNewClass) tree.init; if (init.args != null && init.args.nonEmpty()) { scan(init.args); @@ -404,11 +411,11 @@ public class TreePosTest { boolean check(Info encl, Info self) { if (excludeTags.size() > 0) { - if (encl != null && excludeTags.contains(tagNames.get(encl.tag)) - || excludeTags.contains(tagNames.get(self.tag))) + if (encl != null && excludeTags.contains(getTagName(encl.tag)) + || excludeTags.contains(getTagName(self.tag))) return false; } - return tags.size() == 0 || tags.contains(tagNames.get(self.tag)); + return tags.size() == 0 || tags.contains(getTagName(self.tag)); } void check(String label, Info encl, Info self, boolean ok) { @@ -439,7 +446,7 @@ public class TreePosTest { private class Info { Info() { tree = null; - tag = JCTree.ERRONEOUS; + tag = ERRONEOUS; start = 0; pos = 0; end = Integer.MAX_VALUE; @@ -455,45 +462,16 @@ public class TreePosTest { @Override public String toString() { - return tagNames.get(tree.getTag()) + "[start:" + start + ",pos:" + pos + ",end:" + end + "]"; + return getTagName(tree.getTag()) + "[start:" + start + ",pos:" + pos + ",end:" + end + "]"; } final JCTree tree; - final int tag; + final JCTree.Tag tag; final int start; final int pos; final int end; } - /** - * Names for tree tags. - * javac does not provide an API to convert tag values to strings, so this class uses - * reflection to determine names of public static final int values in JCTree. - */ - private static class TagNames { - String get(int tag) { - if (map == null) { - map = new HashMap(); - Class c = JCTree.class; - for (Field f : c.getDeclaredFields()) { - if (f.getType().equals(int.class)) { - int mods = f.getModifiers(); - if (Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods)) { - try { - map.put(f.getInt(null), f.getName()); - } catch (IllegalAccessException e) { - } - } - } - } - } - String name = map.get(tag); - return (name == null) ? "??" : name; - } - - private Map map; - } - /** * Thrown when errors are found parsing a java file. */ @@ -719,7 +697,7 @@ public class TreePosTest { void setInfo(Info info) { this.info = info; - tagName.setText(tagNames.get(info.tag)); + tagName.setText(getTagName(info.tag)); start.setText(String.valueOf(info.start)); pos.setText(String.valueOf(info.pos)); end.setText(String.valueOf(info.end));