mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-04 13:10:15 +00:00
Merge
This commit is contained in:
commit
a06ab4d4e1
@ -3,7 +3,7 @@ The GNU General Public License (GPL)
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license
|
||||
document, but changing it is not allowed.
|
||||
@ -287,8 +287,8 @@ pointer to where the full notice is found.
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
|
||||
@ -1332,7 +1332,9 @@ public class TypeAnnotations {
|
||||
|
||||
scan(tree.encl);
|
||||
scan(tree.typeargs);
|
||||
scan(tree.clazz);
|
||||
if (tree.def == null) {
|
||||
scan(tree.clazz);
|
||||
} // else super type will already have been scanned in the context of the anonymous class.
|
||||
scan(tree.args);
|
||||
|
||||
// The class body will already be scanned.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, 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
|
||||
@ -509,9 +509,9 @@ public class Types {
|
||||
|
||||
//merge thrown types - form the intersection of all the thrown types in
|
||||
//all the signatures in the list
|
||||
boolean toErase = !bestSoFar.type.hasTag(FORALL);
|
||||
List<Type> thrown = null;
|
||||
Type mt1 = memberType(origin.type, bestSoFar);
|
||||
boolean toErase = !mt1.hasTag(FORALL);
|
||||
for (Symbol msym2 : methodSyms) {
|
||||
Type mt2 = memberType(origin.type, msym2);
|
||||
List<Type> thrown_mt2 = mt2.getThrownTypes();
|
||||
|
||||
@ -3469,7 +3469,6 @@ public class Attr extends JCTree.Visitor {
|
||||
} else {
|
||||
// Check if type-qualified fields or methods are static (JLS)
|
||||
if ((sym.flags() & STATIC) == 0 &&
|
||||
!env.next.tree.hasTag(REFERENCE) &&
|
||||
sym.name != names._super &&
|
||||
(sym.kind == VAR || sym.kind == MTH)) {
|
||||
rs.accessBase(rs.new StaticError(sym),
|
||||
|
||||
@ -1724,7 +1724,7 @@ public class Infer {
|
||||
|
||||
@Override
|
||||
public GraphUtils.DependencyKind[] getSupportedDependencyKinds() {
|
||||
return DependencyKind.values();
|
||||
return new GraphUtils.DependencyKind[] { DependencyKind.BOUND };
|
||||
}
|
||||
|
||||
public Iterable<? extends Node> getAllDependencies() {
|
||||
|
||||
@ -68,6 +68,7 @@ import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
import com.sun.tools.javac.jvm.ClassWriter;
|
||||
import com.sun.tools.javac.jvm.JNIWriter;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
@ -123,6 +124,7 @@ public class Modules extends JCTree.Visitor {
|
||||
private final Symtab syms;
|
||||
private final Attr attr;
|
||||
private final TypeEnvs typeEnvs;
|
||||
private final Types types;
|
||||
private final JavaFileManager fileManager;
|
||||
private final ModuleFinder moduleFinder;
|
||||
private final boolean allowModules;
|
||||
@ -160,6 +162,7 @@ public class Modules extends JCTree.Visitor {
|
||||
attr = Attr.instance(context);
|
||||
typeEnvs = TypeEnvs.instance(context);
|
||||
moduleFinder = ModuleFinder.instance(context);
|
||||
types = Types.instance(context);
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
allowModules = Source.instance(context).allowModules();
|
||||
Options options = Options.instance(context);
|
||||
@ -713,9 +716,12 @@ public class Modules extends JCTree.Visitor {
|
||||
@Override
|
||||
public void visitProvides(JCProvides tree) {
|
||||
Type st = attr.attribType(tree.serviceName, env, syms.objectType);
|
||||
Type it = attr.attribType(tree.implName, env, st);
|
||||
Type it = attr.attribType(tree.implName, env, syms.objectType);
|
||||
ClassSymbol service = (ClassSymbol) st.tsym;
|
||||
ClassSymbol impl = (ClassSymbol) it.tsym;
|
||||
if (!types.isSubtype(it, st)) {
|
||||
log.error(tree.implName.pos(), Errors.ServiceImplementationMustBeSubtypeOfServiceInterface);
|
||||
}
|
||||
if ((impl.flags() & ABSTRACT) != 0) {
|
||||
log.error(tree.implName.pos(), Errors.ServiceImplementationIsAbstract(impl));
|
||||
} else if (impl.isInner()) {
|
||||
|
||||
@ -2715,6 +2715,9 @@ compiler.err.duplicate.uses=\
|
||||
compiler.err.service.implementation.is.abstract=\
|
||||
the service implementation is an abstract class: {0}
|
||||
|
||||
compiler.err.service.implementation.must.be.subtype.of.service.interface=\
|
||||
the service implementation type must be a subtype of the service interface type
|
||||
|
||||
# 0: symbol
|
||||
compiler.err.service.implementation.is.inner=\
|
||||
the service implementation is an inner class: {0}
|
||||
|
||||
@ -28,17 +28,18 @@ import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import java.util.List;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
|
||||
/**
|
||||
* Tracks the state of a class.
|
||||
*/
|
||||
class ClassTracker {
|
||||
|
||||
private final JDIEnv jdiEnv;
|
||||
private final VirtualMachine vm;
|
||||
private final HashMap<String, ClassInfo> map;
|
||||
|
||||
ClassTracker(JDIEnv jdiEnv) {
|
||||
this.jdiEnv = jdiEnv;
|
||||
ClassTracker(VirtualMachine vm) {
|
||||
this.vm = vm;
|
||||
this.map = new HashMap<>();
|
||||
}
|
||||
|
||||
@ -96,7 +97,7 @@ class ClassTracker {
|
||||
}
|
||||
|
||||
private ReferenceType nameToRef(String name) {
|
||||
List<ReferenceType> rtl = jdiEnv.vm().classesByName(name);
|
||||
List<ReferenceType> rtl = vm.classesByName(name);
|
||||
if (rtl.size() != 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 jdk.internal.jshell.jdi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import jdk.internal.jshell.debug.InternalDebugControl;
|
||||
import jdk.jshell.JShellException;
|
||||
import jdk.jshell.spi.ExecutionControl;
|
||||
import jdk.jshell.spi.ExecutionEnv;
|
||||
|
||||
/**
|
||||
* A meta implementation of ExecutionControl which cycles through the specified
|
||||
* ExecutionControl instances until it finds one that starts.
|
||||
*/
|
||||
public class FailOverExecutionControl implements ExecutionControl {
|
||||
|
||||
private final List<ExecutionControl> ecl = new ArrayList<>();
|
||||
private ExecutionControl active = null;
|
||||
private final List<Exception> thrown = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create the ExecutionControl instance with at least one actual
|
||||
* ExecutionControl instance.
|
||||
*
|
||||
* @param ec0 the first instance to try
|
||||
* @param ecs the second and on instance to try
|
||||
*/
|
||||
public FailOverExecutionControl(ExecutionControl ec0, ExecutionControl... ecs) {
|
||||
ecl.add(ec0);
|
||||
for (ExecutionControl ec : ecs) {
|
||||
ecl.add(ec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(ExecutionEnv env) throws Exception {
|
||||
for (ExecutionControl ec : ecl) {
|
||||
try {
|
||||
ec.start(env);
|
||||
// Success! This is our active ExecutionControl
|
||||
active = ec;
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
thrown.add(ex);
|
||||
} catch (Throwable ex) {
|
||||
thrown.add(new RuntimeException(ex));
|
||||
}
|
||||
InternalDebugControl.debug(env.state(), env.userErr(),
|
||||
thrown.get(thrown.size() - 1), "failed one in FailOverExecutionControl");
|
||||
}
|
||||
// They have all failed -- rethrow the first exception we encountered
|
||||
throw thrown.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
active.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToClasspath(String path) {
|
||||
return active.addToClasspath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String invoke(String classname, String methodname) throws JShellException {
|
||||
return active.invoke(classname, methodname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(Collection<String> classes) {
|
||||
return active.load(classes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean redefine(Collection<String> classes) {
|
||||
return active.redefine(classes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassStatus getClassStatus(String classname) {
|
||||
return active.getClassStatus(classname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
active.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String varValue(String classname, String varname) {
|
||||
return active.varValue(classname, varname);
|
||||
}
|
||||
|
||||
}
|
||||
@ -49,6 +49,8 @@ import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
|
||||
*/
|
||||
class JDIConnection {
|
||||
|
||||
private static final String REMOTE_AGENT = "jdk.internal.jshell.remote.RemoteAgent";
|
||||
|
||||
private VirtualMachine vm;
|
||||
private boolean active = true;
|
||||
private Process process = null;
|
||||
@ -59,12 +61,12 @@ class JDIConnection {
|
||||
private final Map<String, com.sun.jdi.connect.Connector.Argument> connectorArgs;
|
||||
private final int traceFlags;
|
||||
|
||||
synchronized void notifyOutputComplete() {
|
||||
private synchronized void notifyOutputComplete() {
|
||||
outputCompleteCount++;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
synchronized void waitOutputComplete() {
|
||||
private synchronized void waitOutputComplete() {
|
||||
// Wait for stderr and stdout
|
||||
if (process != null) {
|
||||
while (outputCompleteCount < 2) {
|
||||
@ -102,61 +104,72 @@ class JDIConnection {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* The JShell specific Connector args for the LaunchingConnector.
|
||||
*
|
||||
* @param portthe socket port for (non-JDI) commands
|
||||
* @param remoteVMOptions any user requested VM options
|
||||
* @return the argument map
|
||||
*/
|
||||
private static Map<String, String> launchArgs(int port, String remoteVMOptions) {
|
||||
Map<String, String> argumentName2Value = new HashMap<>();
|
||||
argumentName2Value.put("main", REMOTE_AGENT + " " + port);
|
||||
argumentName2Value.put("options", remoteVMOptions);
|
||||
return argumentName2Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the remote agent and establish a JDI connection to it.
|
||||
*
|
||||
* @param ec the execution control instance
|
||||
* @param port the socket port for (non-JDI) commands
|
||||
* @param remoteVMOptions any user requested VM options
|
||||
* @param isLaunch does JDI do the launch? That is, LaunchingConnector,
|
||||
* otherwise we start explicitly and use ListeningConnector
|
||||
*/
|
||||
JDIConnection(JDIExecutionControl ec, int port, List<String> remoteVMOptions, boolean isLaunch) {
|
||||
this(ec,
|
||||
isLaunch
|
||||
? "com.sun.jdi.CommandLineLaunch"
|
||||
: "com.sun.jdi.SocketListen",
|
||||
isLaunch
|
||||
? launchArgs(port, String.join(" ", remoteVMOptions))
|
||||
: new HashMap<>(),
|
||||
0);
|
||||
if (isLaunch) {
|
||||
vm = launchTarget();
|
||||
} else {
|
||||
vm = listenTarget(port, remoteVMOptions);
|
||||
}
|
||||
|
||||
if (isOpen() && vm().canBeModified()) {
|
||||
/*
|
||||
* Connection opened on startup.
|
||||
*/
|
||||
new JDIEventHandler(vm(), (b) -> ec.handleVMExit())
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base constructor -- set-up a JDI connection.
|
||||
*
|
||||
* @param ec the execution control instance
|
||||
* @param connectorName the standardized name of the connector
|
||||
* @param argumentName2Value the argument map
|
||||
* @param traceFlags should we trace JDI behavior
|
||||
*/
|
||||
JDIConnection(JDIExecutionControl ec, String connectorName, Map<String, String> argumentName2Value, int traceFlags) {
|
||||
this.ec = ec;
|
||||
this.connector = findConnector(connectorName);
|
||||
|
||||
if (connector == null) {
|
||||
throw new IllegalArgumentException("No connector named: " + connectorName);
|
||||
}
|
||||
|
||||
connectorArgs = mergeConnectorArgs(connector, argumentName2Value);
|
||||
this.traceFlags = traceFlags;
|
||||
}
|
||||
|
||||
synchronized VirtualMachine open() {
|
||||
if (connector instanceof LaunchingConnector) {
|
||||
vm = launchTarget();
|
||||
} else if (connector instanceof AttachingConnector) {
|
||||
vm = attachTarget();
|
||||
} else if (connector instanceof ListeningConnector) {
|
||||
vm = listenTarget();
|
||||
} else {
|
||||
throw new InternalError("Invalid connect type");
|
||||
}
|
||||
vm.setDebugTraceMode(traceFlags);
|
||||
// Uncomment here and below to enable event requests
|
||||
// installEventRequests(vm);
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
synchronized boolean setConnectorArg(String name, String value) {
|
||||
/*
|
||||
* Too late if the connection already made
|
||||
*/
|
||||
if (vm != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Connector.Argument argument = connectorArgs.get(name);
|
||||
if (argument == null) {
|
||||
return false;
|
||||
}
|
||||
argument.setValue(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
String connectorArg(String name) {
|
||||
Connector.Argument argument = connectorArgs.get(name);
|
||||
if (argument == null) {
|
||||
return "";
|
||||
}
|
||||
return argument.value();
|
||||
}
|
||||
|
||||
public synchronized VirtualMachine vm() {
|
||||
final synchronized VirtualMachine vm() {
|
||||
if (vm == null) {
|
||||
throw new JDINotConnectedException();
|
||||
} else {
|
||||
@ -164,14 +177,10 @@ class JDIConnection {
|
||||
}
|
||||
}
|
||||
|
||||
synchronized boolean isOpen() {
|
||||
private synchronized boolean isOpen() {
|
||||
return (vm != null);
|
||||
}
|
||||
|
||||
boolean isLaunch() {
|
||||
return (connector instanceof LaunchingConnector);
|
||||
}
|
||||
|
||||
synchronized boolean isRunning() {
|
||||
return process != null && process.isAlive();
|
||||
}
|
||||
@ -181,7 +190,7 @@ class JDIConnection {
|
||||
active = false;
|
||||
}
|
||||
|
||||
public synchronized void disposeVM() {
|
||||
synchronized void disposeVM() {
|
||||
try {
|
||||
if (vm != null) {
|
||||
vm.dispose(); // This could NPE, so it is caught below
|
||||
@ -189,6 +198,8 @@ class JDIConnection {
|
||||
}
|
||||
} catch (VMDisconnectedException ex) {
|
||||
// Ignore if already closed
|
||||
} catch (Throwable e) {
|
||||
ec.debug(DBG_GEN, null, "disposeVM threw: " + e);
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
@ -198,41 +209,6 @@ class JDIConnection {
|
||||
}
|
||||
}
|
||||
|
||||
/*** Preserved for possible future support of event requests
|
||||
|
||||
private void installEventRequests(VirtualMachine vm) {
|
||||
if (vm.canBeModified()){
|
||||
setEventRequests(vm);
|
||||
resolveEventRequests();
|
||||
}
|
||||
}
|
||||
|
||||
private void setEventRequests(VirtualMachine vm) {
|
||||
EventRequestManager erm = vm.eventRequestManager();
|
||||
|
||||
// Normally, we want all uncaught exceptions. We request them
|
||||
// via the same mechanism as Commands.commandCatchException()
|
||||
// so the user can ignore them later if they are not
|
||||
// interested.
|
||||
// FIXME: this works but generates spurious messages on stdout
|
||||
// during startup:
|
||||
// Set uncaught java.lang.Throwable
|
||||
// Set deferred uncaught java.lang.Throwable
|
||||
Commands evaluator = new Commands();
|
||||
evaluator.commandCatchException
|
||||
(new StringTokenizer("uncaught java.lang.Throwable"));
|
||||
|
||||
ThreadStartRequest tsr = erm.createThreadStartRequest();
|
||||
tsr.enable();
|
||||
ThreadDeathRequest tdr = erm.createThreadDeathRequest();
|
||||
tdr.enable();
|
||||
}
|
||||
|
||||
private void resolveEventRequests() {
|
||||
Env.specList.resolveAll();
|
||||
}
|
||||
***/
|
||||
|
||||
private void dumpStream(InputStream inStream, final PrintStream pStream) throws IOException {
|
||||
BufferedReader in =
|
||||
new BufferedReader(new InputStreamReader(inStream));
|
||||
@ -270,7 +246,7 @@ class JDIConnection {
|
||||
dumpStream(inStream, pStream);
|
||||
} catch (IOException ex) {
|
||||
ec.debug(ex, "Failed reading output");
|
||||
ec.jdiEnv.shutdown();
|
||||
ec.handleVMExit();
|
||||
} finally {
|
||||
notifyOutputComplete();
|
||||
}
|
||||
@ -297,7 +273,7 @@ class JDIConnection {
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ec.debug(ex, "Failed reading output");
|
||||
ec.jdiEnv.shutdown();
|
||||
ec.handleVMExit();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -305,15 +281,19 @@ class JDIConnection {
|
||||
thr.start();
|
||||
}
|
||||
|
||||
private void forwardIO() {
|
||||
displayRemoteOutput(process.getErrorStream(), ec.execEnv.userErr());
|
||||
displayRemoteOutput(process.getInputStream(), ec.execEnv.userOut());
|
||||
readRemoteInput(process.getOutputStream(), ec.execEnv.userIn());
|
||||
}
|
||||
|
||||
/* launch child target vm */
|
||||
private VirtualMachine launchTarget() {
|
||||
LaunchingConnector launcher = (LaunchingConnector)connector;
|
||||
try {
|
||||
VirtualMachine new_vm = launcher.launch(connectorArgs);
|
||||
process = new_vm.process();
|
||||
displayRemoteOutput(process.getErrorStream(), ec.execEnv.userErr());
|
||||
displayRemoteOutput(process.getInputStream(), ec.execEnv.userOut());
|
||||
readRemoteInput(process.getOutputStream(), ec.execEnv.userIn());
|
||||
forwardIO();
|
||||
return new_vm;
|
||||
} catch (Exception ex) {
|
||||
reportLaunchFail(ex, "launch");
|
||||
@ -321,25 +301,35 @@ class JDIConnection {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* JShell currently uses only launch, preserved for futures: */
|
||||
/* attach to running target vm */
|
||||
private VirtualMachine attachTarget() {
|
||||
AttachingConnector attacher = (AttachingConnector)connector;
|
||||
/**
|
||||
* Directly launch the remote agent and connect JDI to it with a
|
||||
* ListeningConnector.
|
||||
*/
|
||||
private VirtualMachine listenTarget(int port, List<String> remoteVMOptions) {
|
||||
ListeningConnector listener = (ListeningConnector) connector;
|
||||
try {
|
||||
return attacher.attach(connectorArgs);
|
||||
} catch (Exception ex) {
|
||||
reportLaunchFail(ex, "attach");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Start listening, get the JDI connection address
|
||||
String addr = listener.startListening(connectorArgs);
|
||||
ec.debug(DBG_GEN, "Listening at address: " + addr);
|
||||
|
||||
/* JShell currently uses only launch, preserved for futures: */
|
||||
/* listen for connection from target vm */
|
||||
private VirtualMachine listenTarget() {
|
||||
ListeningConnector listener = (ListeningConnector)connector;
|
||||
try {
|
||||
String retAddress = listener.startListening(connectorArgs);
|
||||
ec.debug(DBG_GEN, "Listening at address: " + retAddress);
|
||||
// Launch the RemoteAgent requesting a connection on that address
|
||||
String javaHome = System.getProperty("java.home");
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add(javaHome == null
|
||||
? "java"
|
||||
: javaHome + File.separator + "bin" + File.separator + "java");
|
||||
args.add("-agentlib:jdwp=transport=" + connector.transport().name() +
|
||||
",address=" + addr);
|
||||
args.addAll(remoteVMOptions);
|
||||
args.add(REMOTE_AGENT);
|
||||
args.add("" + port);
|
||||
ProcessBuilder pb = new ProcessBuilder(args);
|
||||
process = pb.start();
|
||||
|
||||
// Forward out, err, and in
|
||||
forwardIO();
|
||||
|
||||
// Accept the connection from the remote agent
|
||||
vm = listener.accept(connectorArgs);
|
||||
listener.stopListening(connectorArgs);
|
||||
return vm;
|
||||
@ -353,4 +343,4 @@ class JDIConnection {
|
||||
throw new InternalError("Failed remote " + context + ": " + connector +
|
||||
" -- " + connectorArgs, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, 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 jdk.internal.jshell.jdi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
|
||||
|
||||
/**
|
||||
* Representation of a Java Debug Interface environment
|
||||
* Select methods extracted from jdb Env; shutdown() adapted to JShell shutdown.
|
||||
*/
|
||||
class JDIEnv {
|
||||
|
||||
private JDIConnection connection;
|
||||
private final JDIExecutionControl ec;
|
||||
|
||||
JDIEnv(JDIExecutionControl ec) {
|
||||
this.ec = ec;
|
||||
}
|
||||
|
||||
void init(String connectorName, Map<String, String> argumentName2Value, boolean openNow, int flags) {
|
||||
connection = new JDIConnection(ec, connectorName, argumentName2Value, flags);
|
||||
if (!connection.isLaunch() || openNow) {
|
||||
connection.open();
|
||||
}
|
||||
}
|
||||
|
||||
JDIConnection connection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
VirtualMachine vm() {
|
||||
return connection.vm();
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.disposeVM();
|
||||
} catch (VMDisconnectedException e) {
|
||||
// Shutting down after the VM has gone away. This is
|
||||
// not an error, and we just ignore it.
|
||||
} catch (Throwable e) {
|
||||
ec.debug(DBG_GEN, null, "disposeVM threw: " + e);
|
||||
}
|
||||
}
|
||||
if (ec.execEnv.state() != null) { // If state has been set-up
|
||||
try {
|
||||
ec.execEnv.closeDown();
|
||||
} catch (Throwable e) {
|
||||
ec.debug(DBG_GEN, null, "state().closeDown() threw: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package jdk.internal.jshell.jdi;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
|
||||
@ -34,16 +35,20 @@ import com.sun.jdi.event.*;
|
||||
*/
|
||||
class JDIEventHandler implements Runnable {
|
||||
|
||||
Thread thread;
|
||||
volatile boolean connected = true;
|
||||
boolean completed = false;
|
||||
String shutdownMessageKey;
|
||||
final JDIEnv env;
|
||||
private final Thread thread;
|
||||
private volatile boolean connected = true;
|
||||
private boolean completed = false;
|
||||
private final VirtualMachine vm;
|
||||
private final Consumer<Boolean> reportVMExit;
|
||||
|
||||
JDIEventHandler(JDIEnv env) {
|
||||
this.env = env;
|
||||
JDIEventHandler(VirtualMachine vm, Consumer<Boolean> reportVMExit) {
|
||||
this.vm = vm;
|
||||
this.reportVMExit = reportVMExit;
|
||||
this.thread = new Thread(this, "event-handler");
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
void start() {
|
||||
thread.start();
|
||||
}
|
||||
|
||||
synchronized void shutdown() {
|
||||
@ -56,7 +61,7 @@ class JDIEventHandler implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
EventQueue queue = env.vm().eventQueue();
|
||||
EventQueue queue = vm.eventQueue();
|
||||
while (connected) {
|
||||
try {
|
||||
EventSet eventSet = queue.remove();
|
||||
@ -111,27 +116,23 @@ class JDIEventHandler implements Runnable {
|
||||
private void handleExitEvent(Event event) {
|
||||
if (event instanceof VMDeathEvent) {
|
||||
vmDied = true;
|
||||
shutdownMessageKey = "The application exited";
|
||||
} else if (event instanceof VMDisconnectEvent) {
|
||||
connected = false;
|
||||
if (!vmDied) {
|
||||
shutdownMessageKey = "The application has been disconnected";
|
||||
}
|
||||
} else {
|
||||
throw new InternalError("Unexpected event type: " +
|
||||
event.getClass());
|
||||
}
|
||||
env.shutdown();
|
||||
reportVMExit.accept(vmDied);
|
||||
}
|
||||
|
||||
synchronized void handleDisconnectedException() {
|
||||
private synchronized void handleDisconnectedException() {
|
||||
/*
|
||||
* A VMDisconnectedException has happened while dealing with
|
||||
* another event. We need to flush the event queue, dealing only
|
||||
* with exit events (VMDeath, VMDisconnect) so that we terminate
|
||||
* correctly.
|
||||
*/
|
||||
EventQueue queue = env.vm().eventQueue();
|
||||
EventQueue queue = vm.eventQueue();
|
||||
while (connected) {
|
||||
try {
|
||||
EventSet eventSet = queue.remove();
|
||||
|
||||
@ -34,13 +34,20 @@ import java.io.ObjectOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import com.sun.jdi.*;
|
||||
import java.io.EOFException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.sun.jdi.BooleanValue;
|
||||
import com.sun.jdi.ClassNotLoadedException;
|
||||
import com.sun.jdi.IncompatibleThreadStateException;
|
||||
import com.sun.jdi.InvalidTypeException;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import com.sun.jdi.StackFrame;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import jdk.jshell.JShellException;
|
||||
import jdk.jshell.spi.ExecutionControl;
|
||||
@ -59,13 +66,28 @@ import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
|
||||
public class JDIExecutionControl implements ExecutionControl {
|
||||
|
||||
ExecutionEnv execEnv;
|
||||
JDIEnv jdiEnv;
|
||||
private ClassTracker tracker;
|
||||
private JDIEventHandler handler;
|
||||
private final boolean isLaunch;
|
||||
private JDIConnection connection;
|
||||
private ClassTracker classTracker;
|
||||
private Socket socket;
|
||||
private ObjectInputStream remoteIn;
|
||||
private ObjectOutputStream remoteOut;
|
||||
private String remoteVMOptions;
|
||||
|
||||
/**
|
||||
* Creates an ExecutionControl instance based on JDI.
|
||||
*
|
||||
* @param isLaunch true for LaunchingConnector; false for ListeningConnector
|
||||
*/
|
||||
public JDIExecutionControl(boolean isLaunch) {
|
||||
this.isLaunch = isLaunch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ExecutionControl instance based on a JDI LaunchingConnector.
|
||||
*/
|
||||
public JDIExecutionControl() {
|
||||
this.isLaunch = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the launching JDI execution engine. Initialize JDI and use it
|
||||
@ -79,20 +101,12 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
@Override
|
||||
public void start(ExecutionEnv execEnv) throws IOException {
|
||||
this.execEnv = execEnv;
|
||||
this.jdiEnv = new JDIEnv(this);
|
||||
this.tracker = new ClassTracker(jdiEnv);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
execEnv.extraRemoteVMOptions().stream()
|
||||
.forEach(s -> {
|
||||
sb.append(" ");
|
||||
sb.append(s);
|
||||
});
|
||||
this.remoteVMOptions = sb.toString();
|
||||
try (ServerSocket listener = new ServerSocket(0)) {
|
||||
// timeout after 60 seconds
|
||||
listener.setSoTimeout(60000);
|
||||
int port = listener.getLocalPort();
|
||||
jdiGo(port);
|
||||
connection = new JDIConnection(this, port, execEnv.extraRemoteVMOptions(), isLaunch);
|
||||
this.socket = listener.accept();
|
||||
// out before in -- match remote creation so we don't hang
|
||||
this.remoteOut = new ObjectOutputStream(socket.getOutputStream());
|
||||
@ -109,16 +123,15 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
JDIConnection c = jdiEnv.connection();
|
||||
if (c != null) {
|
||||
c.beginShutdown();
|
||||
if (connection != null) {
|
||||
connection.beginShutdown();
|
||||
}
|
||||
if (remoteOut != null) {
|
||||
remoteOut.writeInt(CMD_EXIT);
|
||||
remoteOut.flush();
|
||||
}
|
||||
if (c != null) {
|
||||
c.disposeVM();
|
||||
if (connection != null) {
|
||||
connection.disposeVM();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
debug(DBG_GEN, "Exception on JDI exit: %s\n", ex);
|
||||
@ -185,9 +198,9 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
return result;
|
||||
}
|
||||
} catch (IOException | RuntimeException ex) {
|
||||
if (!jdiEnv.connection().isRunning()) {
|
||||
if (!connection.isRunning()) {
|
||||
// The JDI connection is no longer live, shutdown.
|
||||
jdiEnv.shutdown();
|
||||
handleVMExit();
|
||||
} else {
|
||||
debug(DBG_GEN, "Exception on remote invoke: %s\n", ex);
|
||||
return "Execution failure: " + ex.getMessage();
|
||||
@ -221,7 +234,7 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
return result;
|
||||
}
|
||||
} catch (EOFException ex) {
|
||||
jdiEnv.shutdown();
|
||||
handleVMExit();
|
||||
} catch (IOException ex) {
|
||||
debug(DBG_GEN, "Exception on remote var value: %s\n", ex);
|
||||
return "Execution failure: " + ex.getMessage();
|
||||
@ -273,7 +286,7 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
ci -> ci.getReferenceTypeOrNull(),
|
||||
ci -> ci.getBytes()));
|
||||
// Attempt redefine. Throws exceptions on failure.
|
||||
jdiEnv.vm().redefineClasses(rmp);
|
||||
connection.vm().redefineClasses(rmp);
|
||||
// Successful: mark the bytes as loaded.
|
||||
infos.stream()
|
||||
.forEach(ci -> ci.markLoaded());
|
||||
@ -287,6 +300,24 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
}
|
||||
}
|
||||
|
||||
// the VM has gone down in flames or because user evaled System.exit() or the like
|
||||
void handleVMExit() {
|
||||
if (connection != null) {
|
||||
// If there is anything left dispose of it
|
||||
connection.disposeVM();
|
||||
}
|
||||
// Tell JShell-core that the VM has died
|
||||
execEnv.closeDown();
|
||||
}
|
||||
|
||||
// Lazy init class tracker
|
||||
private ClassTracker classTracker() {
|
||||
if (classTracker == null) {
|
||||
classTracker = new ClassTracker(connection.vm());
|
||||
}
|
||||
return classTracker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a collection of class names into ClassInfo instances associated
|
||||
* with the most recently compiled class bytes.
|
||||
@ -296,7 +327,7 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
*/
|
||||
private List<ClassInfo> withBytes(Collection<String> classes) {
|
||||
return classes.stream()
|
||||
.map(cn -> tracker.classInfo(cn, execEnv.getClassBytes(cn)))
|
||||
.map(cn -> classTracker().classInfo(cn, execEnv.getClassBytes(cn)))
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
@ -310,7 +341,7 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
*/
|
||||
@Override
|
||||
public ClassStatus getClassStatus(String classname) {
|
||||
ClassInfo ci = tracker.get(classname);
|
||||
ClassInfo ci = classTracker().get(classname);
|
||||
if (ci.getReferenceTypeOrNull() == null) {
|
||||
// If the class does not have a JDI ReferenceType it has not been loaded
|
||||
return ClassStatus.UNKNOWN;
|
||||
@ -403,37 +434,6 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
return elems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the remote agent as a JDI connection.
|
||||
*
|
||||
* @param port the socket port for (non-JDI) commands
|
||||
*/
|
||||
private void jdiGo(int port) {
|
||||
//MessageOutput.textResources = ResourceBundle.getBundle("impl.TTYResources",
|
||||
// Locale.getDefault());
|
||||
|
||||
// Set-up for a fresh launch of a remote agent with any user-specified VM options.
|
||||
String connectorName = "com.sun.jdi.CommandLineLaunch";
|
||||
Map<String, String> argumentName2Value = new HashMap<>();
|
||||
argumentName2Value.put("main", "jdk.internal.jshell.remote.RemoteAgent " + port);
|
||||
argumentName2Value.put("options", remoteVMOptions);
|
||||
|
||||
boolean launchImmediately = true;
|
||||
int traceFlags = 0;// VirtualMachine.TRACE_SENDS | VirtualMachine.TRACE_EVENTS;
|
||||
|
||||
// Launch.
|
||||
jdiEnv.init(connectorName, argumentName2Value, launchImmediately, traceFlags);
|
||||
|
||||
if (jdiEnv.connection().isOpen() && jdiEnv.vm().canBeModified()) {
|
||||
/*
|
||||
* Connection opened on startup. Start event handler
|
||||
* immediately, telling it (through arg 2) to stop on the
|
||||
* VM start event.
|
||||
*/
|
||||
handler = new JDIEventHandler(jdiEnv);
|
||||
}
|
||||
}
|
||||
|
||||
private final Object STOP_LOCK = new Object();
|
||||
private boolean userCodeRunning = false;
|
||||
|
||||
@ -447,7 +447,7 @@ public class JDIExecutionControl implements ExecutionControl {
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualMachine vm = handler.env.vm();
|
||||
VirtualMachine vm = connection.vm();
|
||||
vm.suspend();
|
||||
try {
|
||||
OUTER:
|
||||
|
||||
@ -73,8 +73,8 @@ public class ExternalEditor {
|
||||
*/
|
||||
private void setupWatch(String initialText) throws IOException {
|
||||
this.watcher = FileSystems.getDefault().newWatchService();
|
||||
this.dir = Files.createTempDirectory("REPL");
|
||||
this.tmpfile = Files.createTempFile(dir, null, ".repl");
|
||||
this.dir = Files.createTempDirectory("jshelltemp");
|
||||
this.tmpfile = Files.createTempFile(dir, null, ".edit");
|
||||
Files.write(tmpfile, initialText.getBytes(Charset.forName("UTF-8")));
|
||||
dir.register(watcher,
|
||||
ENTRY_CREATE,
|
||||
@ -86,12 +86,17 @@ public class ExternalEditor {
|
||||
try {
|
||||
key = watcher.take();
|
||||
} catch (ClosedWatchServiceException ex) {
|
||||
// The watch service has been closed, we are done
|
||||
break;
|
||||
} catch (InterruptedException ex) {
|
||||
continue; // tolerate an intrupt
|
||||
// tolerate an interrupt
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!key.pollEvents().isEmpty()) {
|
||||
// Changes have occurred in temp edit directory,
|
||||
// transfer the new sources to JShell (unless the editor is
|
||||
// running directly in JShell's window -- don't make a mess)
|
||||
if (!input.terminalEditorRunning()) {
|
||||
saveFile();
|
||||
}
|
||||
@ -99,7 +104,7 @@ public class ExternalEditor {
|
||||
|
||||
boolean valid = key.reset();
|
||||
if (!valid) {
|
||||
errorHandler.accept("Invalid key");
|
||||
// The watch service has been closed, we are done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import jdk.internal.jshell.debug.InternalDebugControl;
|
||||
import jdk.internal.jshell.jdi.FailOverExecutionControl;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static jdk.jshell.Util.expunge;
|
||||
@ -112,7 +113,9 @@ public class JShell implements AutoCloseable {
|
||||
this.idGenerator = b.idGenerator;
|
||||
this.extraRemoteVMOptions = b.extraRemoteVMOptions;
|
||||
this.executionControl = b.executionControl==null
|
||||
? new JDIExecutionControl()
|
||||
? new FailOverExecutionControl(
|
||||
new JDIExecutionControl(),
|
||||
new JDIExecutionControl(false))
|
||||
: b.executionControl;
|
||||
|
||||
this.maps = new SnippetMaps(this);
|
||||
@ -759,7 +762,11 @@ public class JShell implements AutoCloseable {
|
||||
if (!closed) {
|
||||
// Send only once
|
||||
closed = true;
|
||||
notifyShutdownEvent(this);
|
||||
try {
|
||||
notifyShutdownEvent(this);
|
||||
} catch (Throwable thr) {
|
||||
// Don't care about dying exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,35 +40,52 @@ class MaskCommentsAndModifiers {
|
||||
Stream.of( "public", "protected", "private", "static", "final" )
|
||||
.collect( Collectors.toSet() );
|
||||
|
||||
// Builder to accumulate non-masked characters
|
||||
private final StringBuilder sbCleared = new StringBuilder();
|
||||
|
||||
// Builder to accumulate masked characters
|
||||
private final StringBuilder sbMask = new StringBuilder();
|
||||
|
||||
// The input string
|
||||
private final String str;
|
||||
|
||||
// Entire input string length
|
||||
private final int length;
|
||||
|
||||
// Should leading modifiers be masked away
|
||||
private final boolean maskModifiers;
|
||||
|
||||
// The next character
|
||||
private int next = 0;
|
||||
private boolean wasMasked = false;
|
||||
|
||||
// We have past any point where a top-level modifier could be
|
||||
private boolean inside = false;
|
||||
|
||||
// Does the string end with an unclosed '/*' style comment?
|
||||
private boolean openComment = false;
|
||||
|
||||
@SuppressWarnings("empty-statement")
|
||||
public MaskCommentsAndModifiers(String s, boolean maskModifiers) {
|
||||
MaskCommentsAndModifiers(String s, boolean maskModifiers) {
|
||||
this.str = s;
|
||||
this.length = s.length();
|
||||
this.maskModifiers = maskModifiers;
|
||||
do { } while (next());
|
||||
}
|
||||
|
||||
public String cleared() {
|
||||
String cleared() {
|
||||
return sbCleared.toString();
|
||||
}
|
||||
|
||||
public String mask() {
|
||||
String mask() {
|
||||
return sbMask.toString();
|
||||
}
|
||||
|
||||
public boolean wasMasked() {
|
||||
return wasMasked;
|
||||
boolean endsWithOpenComment() {
|
||||
return openComment;
|
||||
}
|
||||
|
||||
/****** private implementation methods ******/
|
||||
|
||||
/**
|
||||
* Read the next character
|
||||
*/
|
||||
@ -89,7 +106,6 @@ class MaskCommentsAndModifiers {
|
||||
}
|
||||
|
||||
private void writeMask(int ch) {
|
||||
wasMasked = true;
|
||||
write(sbMask, ch);
|
||||
write(sbCleared, Character.isWhitespace(ch) ? ch : ' ');
|
||||
}
|
||||
@ -147,6 +163,7 @@ class MaskCommentsAndModifiers {
|
||||
int prevc = 0;
|
||||
while ((c = read()) != '/' || prevc != '*') {
|
||||
if (c < 0) {
|
||||
openComment = true;
|
||||
return false;
|
||||
}
|
||||
writeMask(c);
|
||||
|
||||
@ -130,6 +130,7 @@ import javax.tools.ToolProvider;
|
||||
|
||||
import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE;
|
||||
|
||||
/**
|
||||
* The concrete implementation of SourceCodeAnalysis.
|
||||
@ -165,6 +166,10 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
||||
@Override
|
||||
public CompletionInfo analyzeCompletion(String srcInput) {
|
||||
MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
|
||||
if (mcm.endsWithOpenComment()) {
|
||||
proc.debug(DBG_COMPA, "Incomplete (open comment): %s\n", srcInput);
|
||||
return new CompletionInfo(DEFINITELY_INCOMPLETE, srcInput.length(), null, srcInput + '\n');
|
||||
}
|
||||
String cleared = mcm.cleared();
|
||||
String trimmedInput = Util.trimEnd(cleared);
|
||||
if (trimmedInput.isEmpty()) {
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8149524
|
||||
* @bug 8149524 8131024
|
||||
* @summary Test SourceCodeAnalysis
|
||||
* @build KullaTesting TestingInputStream
|
||||
* @run testng CompletenessTest
|
||||
@ -285,6 +285,11 @@ public class CompletenessTest extends KullaTesting {
|
||||
assertStatus("\"abc\\", UNKNOWN, "\"abc\\");
|
||||
}
|
||||
|
||||
public void testOpenComment() {
|
||||
assertStatus("int xx; /* hello", DEFINITELY_INCOMPLETE, null);
|
||||
assertStatus("/** test", DEFINITELY_INCOMPLETE, null);
|
||||
}
|
||||
|
||||
public void testMiscSource() {
|
||||
assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
|
||||
assertStatus("int m() {} dfd", COMPLETE, "int m() {}");
|
||||
|
||||
@ -21,40 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8156101
|
||||
* @summary Tests for ExecutionControl SPI
|
||||
* @build KullaTesting LocalExecutionControl
|
||||
* @run testng ExecutionControlTest
|
||||
*/
|
||||
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import jdk.jshell.VarSnippet;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static jdk.jshell.Snippet.Status.VALID;
|
||||
import static jdk.jshell.Snippet.SubKind.*;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
@Test
|
||||
public class ExecutionControlTest extends KullaTesting {
|
||||
|
||||
@BeforeMethod
|
||||
@Override
|
||||
public void setUp() {
|
||||
setUp(new LocalExecutionControl());
|
||||
}
|
||||
|
||||
public void verifyLocal() throws ClassNotFoundException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
|
||||
System.setProperty("LOCAL_CHECK", "TBD");
|
||||
assertEquals(System.getProperty("LOCAL_CHECK"), "TBD");
|
||||
assertEval("System.setProperty(\"LOCAL_CHECK\", \"local\")");
|
||||
assertEquals(System.getProperty("LOCAL_CHECK"), "local");
|
||||
}
|
||||
public class ExecutionControlTestBase extends KullaTesting {
|
||||
|
||||
public void classesDeclaration() {
|
||||
assertEval("interface A { }");
|
||||
@ -71,7 +45,6 @@ public class ExecutionControlTest extends KullaTesting {
|
||||
assertActiveKeys();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interfaceTest() {
|
||||
String interfaceSource
|
||||
= "interface A {\n"
|
||||
@ -24,8 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Testing external editor.
|
||||
* @bug 8080843 8143955
|
||||
* @ignore 8080843
|
||||
* @bug 8143955 8080843
|
||||
* @modules jdk.jshell/jdk.internal.jshell.tool
|
||||
* @build ReplToolTesting CustomEditor EditorTestBase
|
||||
* @run testng ExternalEditorTest
|
||||
@ -197,22 +196,22 @@ public class ExternalEditorTest extends EditorTestBase {
|
||||
a -> assertCommand(a, "/set editor", "| The '/set editor' command requires a path argument"),
|
||||
a -> assertCommand(a, "/set editor UNKNOWN", "| Editor set to: UNKNOWN"),
|
||||
a -> assertCommand(a, "int a;", null),
|
||||
a -> assertCommand(a, "/ed 1",
|
||||
"| Edit Error: process IO failure: Cannot run program \"UNKNOWN\": error=2, No such file or directory")
|
||||
a -> assertCommandOutputStartsWith(a, "/ed 1",
|
||||
"| Edit Error:")
|
||||
);
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
@Test
|
||||
public void testRemoveTempFile() {
|
||||
test(new String[]{"-nostartup"},
|
||||
a -> assertCommandCheckOutput(a, "/set editor " + executionScript,
|
||||
assertStartsWith("| Editor set to: " + executionScript)),
|
||||
a -> assertVariable(a, "int", "a", "0", "0"),
|
||||
a -> assertEditOutput(a, "/e 1", assertStartsWith("| Edit Error: Failure read edit file:"), () -> {
|
||||
a -> assertEditOutput(a, "/ed 1", assertStartsWith("| Edit Error: Failure in read edit file:"), () -> {
|
||||
sendCode(CustomEditor.REMOVE_CODE);
|
||||
exit();
|
||||
}),
|
||||
a -> assertCommandCheckOutput(a, "/v", assertVariables())
|
||||
a -> assertCommandCheckOutput(a, "/vars", assertVariables())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
104
langtools/test/jdk/jshell/FailOverExecutionControlTest.java
Normal file
104
langtools/test/jdk/jshell/FailOverExecutionControlTest.java
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8131029
|
||||
* @summary Test that fail-over works for FailOverExecutionControl
|
||||
* @modules jdk.jshell/jdk.internal.jshell.jdi
|
||||
* jdk.jshell/jdk.jshell.spi
|
||||
* @build KullaTesting ExecutionControlTestBase
|
||||
* @run testng FailOverExecutionControlTest
|
||||
*/
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import jdk.internal.jshell.jdi.FailOverExecutionControl;
|
||||
import jdk.internal.jshell.jdi.JDIExecutionControl;
|
||||
import jdk.jshell.JShellException;
|
||||
import jdk.jshell.spi.ExecutionControl;
|
||||
import jdk.jshell.spi.ExecutionEnv;
|
||||
|
||||
@Test
|
||||
public class FailOverExecutionControlTest extends ExecutionControlTestBase {
|
||||
|
||||
@BeforeMethod
|
||||
@Override
|
||||
public void setUp() {
|
||||
setUp(new FailOverExecutionControl(
|
||||
new AlwaysFailingExecutionControl(),
|
||||
new AlwaysFailingExecutionControl(),
|
||||
new JDIExecutionControl()));
|
||||
}
|
||||
|
||||
class AlwaysFailingExecutionControl implements ExecutionControl {
|
||||
|
||||
@Override
|
||||
public void start(ExecutionEnv env) throws Exception {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToClasspath(String path) {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String invoke(String classname, String methodname) throws JShellException {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(Collection<String> classes) {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean redefine(Collection<String> classes) {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassStatus getClassStatus(String classname) {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String varValue(String classname, String varname) {
|
||||
throw new UnsupportedOperationException("This operation intentionally broken.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8131029
|
||||
* @summary Tests for alternate JDI connector -- listening
|
||||
* @modules jdk.jshell/jdk.internal.jshell.jdi
|
||||
* @build KullaTesting ExecutionControlTestBase
|
||||
* @run testng JDIListeningExecutionControlTest
|
||||
*/
|
||||
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import jdk.internal.jshell.jdi.JDIExecutionControl;
|
||||
|
||||
@Test
|
||||
public class JDIListeningExecutionControlTest extends ExecutionControlTestBase {
|
||||
|
||||
@BeforeMethod
|
||||
@Override
|
||||
public void setUp() {
|
||||
setUp(new JDIExecutionControl(false));
|
||||
}
|
||||
}
|
||||
@ -560,6 +560,7 @@ public class ToolBasicTest extends ReplToolTesting {
|
||||
);
|
||||
}
|
||||
|
||||
@Test(enabled = false) // TODO 8158197
|
||||
public void testHeadlessEditPad() {
|
||||
String prevHeadless = System.getProperty("java.awt.headless");
|
||||
try {
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8153716 8143955 8151754 8150382 8153920 8156910
|
||||
* @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024
|
||||
* @summary Simple jshell tool tests
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
@ -61,6 +61,16 @@ public class ToolSimpleTest extends ReplToolTesting {
|
||||
);
|
||||
}
|
||||
|
||||
public void testOpenComment() {
|
||||
test(
|
||||
(a) -> assertCommand(a, "int z = /* blah", ""),
|
||||
(a) -> assertCommand(a, "baz */ 5", "z ==> 5"),
|
||||
(a) -> assertCommand(a, "/** hoge ", ""),
|
||||
(a) -> assertCommand(a, "baz **/", ""),
|
||||
(a) -> assertCommand(a, "int v", "v ==> 0")
|
||||
);
|
||||
}
|
||||
|
||||
public void oneLineOfError() {
|
||||
test(
|
||||
(a) -> assertCommand(a, "12+", null),
|
||||
|
||||
53
langtools/test/jdk/jshell/UserExecutionControlTest.java
Normal file
53
langtools/test/jdk/jshell/UserExecutionControlTest.java
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8156101
|
||||
* @summary Tests for ExecutionControl SPI
|
||||
* @build KullaTesting LocalExecutionControl ExecutionControlTestBase
|
||||
* @run testng UserExecutionControlTest
|
||||
*/
|
||||
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
@Test
|
||||
public class UserExecutionControlTest extends ExecutionControlTestBase {
|
||||
|
||||
@BeforeMethod
|
||||
@Override
|
||||
public void setUp() {
|
||||
setUp(new LocalExecutionControl());
|
||||
}
|
||||
|
||||
public void verifyLocal() throws ClassNotFoundException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
|
||||
System.setProperty("LOCAL_CHECK", "TBD");
|
||||
assertEquals(System.getProperty("LOCAL_CHECK"), "TBD");
|
||||
assertEval("System.setProperty(\"LOCAL_CHECK\", \"local\")");
|
||||
assertEquals(System.getProperty("LOCAL_CHECK"), "local");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8037947
|
||||
* @summary functional interface causes ClassCastException when extending raw superinterface
|
||||
* @modules jdk.compiler/com.sun.tools.javac.util
|
||||
* @compile CCEForFunctionalInterExtedingRawSuperInterTest.java
|
||||
*/
|
||||
|
||||
public class CCEForFunctionalInterExtedingRawSuperInterTest {
|
||||
interface X<A> { <T extends A> void execute(int a); }
|
||||
interface Y<B> { <S extends B> void execute(int a); }
|
||||
|
||||
@FunctionalInterface
|
||||
interface Exec<A> extends Y, X<A> { }
|
||||
}
|
||||
29
langtools/test/tools/javac/annotations/8145489/T8145489.java
Normal file
29
langtools/test/tools/javac/annotations/8145489/T8145489.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8145489
|
||||
* @summary NPE while compiling annotations with qualified names in package-info.java
|
||||
* @compile foo/package-info.java
|
||||
*/
|
||||
30
langtools/test/tools/javac/annotations/8145489/foo/Anno.java
Normal file
30
langtools/test/tools/javac/annotations/8145489/foo/Anno.java
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 foo;
|
||||
|
||||
public @interface Anno {
|
||||
Class<?> clazz();
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 foo;
|
||||
|
||||
public class Status {
|
||||
public class Inner { }
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*/
|
||||
|
||||
@Anno(clazz = Status.Inner.class)
|
||||
package foo;
|
||||
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8146167
|
||||
* @summary Anonymous type declarations drop supertype type parameter annotations
|
||||
* @run main AnonymousExtendsTest
|
||||
*/
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.AnnotatedParameterizedType;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({ "javadoc", "serial" })
|
||||
public class AnonymousExtendsTest {
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TA {
|
||||
int value();
|
||||
}
|
||||
|
||||
public class TestClass extends @TA(1) ArrayList<@TA(2) List<Number>> {
|
||||
}
|
||||
|
||||
public void testIt() {
|
||||
checkAnnotations(TestClass.class.getAnnotatedSuperclass(),
|
||||
"[@AnonymousExtendsTest$TA(value=1)],[@AnonymousExtendsTest$TA(value=2)]");
|
||||
checkAnnotations(new @TA(3) ArrayList<@TA(4) List<Number>>() {
|
||||
}.getClass().getAnnotatedSuperclass(),
|
||||
"[@AnonymousExtendsTest$TA(value=3)],[@AnonymousExtendsTest$TA(value=4)]");
|
||||
}
|
||||
|
||||
public void checkAnnotations(AnnotatedType type, String expected) {
|
||||
String actual = Arrays.asList(((AnnotatedParameterizedType) type)
|
||||
.getAnnotations())
|
||||
.toString()
|
||||
+ "," +
|
||||
Arrays.asList(((AnnotatedParameterizedType) type)
|
||||
.getAnnotatedActualTypeArguments()[0].getAnnotations())
|
||||
.toString();
|
||||
|
||||
if (!actual.equals(expected))
|
||||
throw new AssertionError("Unexpected annotations" + actual);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new AnonymousExtendsTest().testIt();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*/
|
||||
|
||||
// key: compiler.err.service.implementation.must.be.subtype.of.service.interface
|
||||
// key: compiler.err.service.implementation.not.in.right.module
|
||||
|
||||
module ServiceImplMustBeSubtypeOfServiceIntf {
|
||||
provides java.lang.String with java.io.File;
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8158355
|
||||
* @summary Inference graph dot support broken
|
||||
* @compile -XDdumpInferenceGraphsTo=. T8158355.java
|
||||
*/
|
||||
import java.util.List;
|
||||
|
||||
class T8158355 {
|
||||
<Z> List<Z> m() { return null; }
|
||||
|
||||
void test() {
|
||||
List<String> ls = m();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8152062
|
||||
* @summary obscure error message for bad 'provides'
|
||||
* @library /tools/lib
|
||||
* @modules
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
|
||||
* @run main ObscureMessageForBadProvidesTest
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import toolbox.JavacTask;
|
||||
import toolbox.Task;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
public class ObscureMessageForBadProvidesTest extends ModuleTestBase {
|
||||
public static void main(String... args) throws Exception {
|
||||
new ObscureMessageForBadProvidesTest().runTests();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void theTest(Path base) throws Exception {
|
||||
Path mod = base.resolve("mod");
|
||||
tb.writeJavaFiles(mod, "module mod { provides java.lang.String with java.io.File; }");
|
||||
Path classes = base.resolve("classes");
|
||||
tb.createDirectories(classes);
|
||||
String log = new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics")
|
||||
.outdir(classes)
|
||||
.files(findJavaFiles(mod))
|
||||
.run(Task.Expect.FAIL)
|
||||
.writeAll()
|
||||
.getOutput(Task.OutputKind.DIRECT);
|
||||
|
||||
if (!log.startsWith("module-info.java:1:52: compiler.err.service.implementation.must.be.subtype.of.service.interface"))
|
||||
throw new Exception("expected output not found");
|
||||
}
|
||||
}
|
||||
@ -143,8 +143,7 @@ public class ProvidesTest extends ModuleTestBase {
|
||||
List<String> expected = Arrays.asList(
|
||||
"C.java:1:36: compiler.err.cant.resolve.location: kindname.class, Missing, , , (compiler.misc.location: kindname.package, p, null)",
|
||||
"module-info.java:1:22: compiler.err.cant.resolve.location: kindname.class, Missing, , , (compiler.misc.location: kindname.package, p, null)",
|
||||
"module-info.java:1:37: compiler.err.service.implementation.doesnt.have.a.no.args.constructor: <any>",
|
||||
"3 errors");
|
||||
"2 errors");
|
||||
if (!output.containsAll(expected)) {
|
||||
throw new Exception("Expected output not found");
|
||||
}
|
||||
@ -192,8 +191,11 @@ public class ProvidesTest extends ModuleTestBase {
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
List<String> expected = Arrays.asList("module-info.java:1:31: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: p.B, p.A)",
|
||||
"1 error");
|
||||
List<String> expected = Arrays.asList(
|
||||
"module-info.java:1:31: compiler.err.service.implementation.must.be.subtype.of.service.interface",
|
||||
"module-info.java:1:12: compiler.warn.service.provided.but.not.exported.or.used: p.A",
|
||||
"1 error",
|
||||
"1 warning");
|
||||
if (!output.containsAll(expected)) {
|
||||
throw new Exception("Expected output not found");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user