8154485: JShell: infrastructure for multi-Snippet class wrappers
Reviewed-by: jlahoda
This commit is contained in:
parent
e85033c628
commit
f49817d6cd
@ -262,9 +262,14 @@ class RemoteAgent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expunge internal info from string
|
||||||
|
* @param s string to process
|
||||||
|
* @return string the display, JShell package and wrapper class names removed
|
||||||
|
*/
|
||||||
static String expunge(String s) {
|
static String expunge(String s) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (String comp : prefixPattern.split(s)) {
|
for (String comp : PREFIX_PATTERN.split(s)) {
|
||||||
sb.append(comp);
|
sb.append(comp);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -47,8 +47,12 @@ public class RemoteCodes {
|
|||||||
public static final int RESULT_CORRALLED = 103;
|
public static final int RESULT_CORRALLED = 103;
|
||||||
public static final int RESULT_KILLED = 104;
|
public static final int RESULT_KILLED = 104;
|
||||||
|
|
||||||
|
// String constants
|
||||||
|
public static final String REPL_PACKAGE = "REPL";
|
||||||
|
public static final String REPL_CLASS_PREFIX = "$JShell$";
|
||||||
public static final String DOIT_METHOD_NAME = "do_it$";
|
public static final String DOIT_METHOD_NAME = "do_it$";
|
||||||
public static final String replClass = "\\$REPL(?<num>\\d+)[A-Z]*";
|
public static final Pattern PREFIX_PATTERN = Pattern.compile(
|
||||||
public static final Pattern prefixPattern = Pattern.compile("(REPL\\.)?" + replClass + "[\\$\\.]?");
|
"(" + REPL_PACKAGE + "\\.)?" +
|
||||||
|
"(?<class>" + Pattern.quote(REPL_CLASS_PREFIX) +
|
||||||
|
"\\w+" + ")" + "[\\$\\.]?");
|
||||||
}
|
}
|
||||||
|
@ -512,7 +512,7 @@ startup.feedback = \
|
|||||||
/set format verbose errorpre '| ' \n\
|
/set format verbose errorpre '| ' \n\
|
||||||
/set format verbose errorpost '%n' \n\
|
/set format verbose errorpost '%n' \n\
|
||||||
\n\
|
\n\
|
||||||
/set format verbose errorline '{pre} {err}' \n\
|
/set format verbose errorline '{post}{pre} {err}' \n\
|
||||||
\n\
|
\n\
|
||||||
/set format verbose action 'created' added-primary \n\
|
/set format verbose action 'created' added-primary \n\
|
||||||
/set format verbose action 'modified' modified-primary \n\
|
/set format verbose action 'modified' modified-primary \n\
|
||||||
|
@ -27,6 +27,7 @@ package jdk.jshell;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
import com.sun.jdi.ReferenceType;
|
import com.sun.jdi.ReferenceType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,6 +83,17 @@ class ClassTracker {
|
|||||||
}
|
}
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof ClassInfo &&
|
||||||
|
((ClassInfo) o).className.equals(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(this.className);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassInfo classInfo(String className, byte[] bytes) {
|
ClassInfo classInfo(String className, byte[] bytes) {
|
||||||
@ -93,5 +105,4 @@ class ClassTracker {
|
|||||||
ClassInfo get(String className) {
|
ClassInfo get(String className) {
|
||||||
return map.get(className);
|
return map.get(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,6 @@ public abstract class DeclarationSnippet extends PersistentSnippet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
String importLine(JShell state) {
|
String importLine(JShell state) {
|
||||||
return "import static " + state.maps.classFullName(this) + "." + name() + ";\n";
|
return "import static " + classFullName() + "." + name() + ";\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,10 +100,12 @@ public abstract class Diag {
|
|||||||
// *** Internal support ***
|
// *** Internal support ***
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal: If this is from a compile, extract the compilation Unit.
|
* Internal: If this is from a compile/analyze wrapped in an outer class, extract the snippet.
|
||||||
* Otherwise null.
|
* Otherwise null.
|
||||||
*/
|
*/
|
||||||
abstract Unit unitOrNull();
|
Snippet snippetOrNull() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an unreachable-statement error
|
* This is an unreachable-statement error
|
||||||
@ -124,6 +126,7 @@ public abstract class Diag {
|
|||||||
*/
|
*/
|
||||||
boolean isResolutionError() {
|
boolean isResolutionError() {
|
||||||
//TODO: try javac RESOLVE_ERROR flag
|
//TODO: try javac RESOLVE_ERROR flag
|
||||||
return getCode().startsWith("compiler.err.cant.resolve");
|
return getCode().startsWith("compiler.err.cant.resolve")
|
||||||
|
|| getCode().equals("compiler.err.cant.apply.symbol");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,10 @@ final class DiagList extends ArrayList<Diag> {
|
|||||||
|
|
||||||
DiagList ofUnit(Unit u) {
|
DiagList ofUnit(Unit u) {
|
||||||
return this.stream()
|
return this.stream()
|
||||||
.filter(d -> d.unitOrNull() == u)
|
.filter(d -> {
|
||||||
|
Snippet snn = d.snippetOrNull();
|
||||||
|
return snn == u.snippet();
|
||||||
|
})
|
||||||
.collect(Collectors.toCollection(() -> new DiagList()));
|
.collect(Collectors.toCollection(() -> new DiagList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,7 +22,6 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdk.jshell;
|
package jdk.jshell;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -50,7 +49,6 @@ import java.io.StringWriter;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import com.sun.tools.javac.util.Context;
|
|
||||||
import jdk.jshell.ClassTracker.ClassInfo;
|
import jdk.jshell.ClassTracker.ClassInfo;
|
||||||
import jdk.jshell.Key.ErroneousKey;
|
import jdk.jshell.Key.ErroneousKey;
|
||||||
import jdk.jshell.Key.MethodKey;
|
import jdk.jshell.Key.MethodKey;
|
||||||
@ -68,7 +66,7 @@ import static java.util.stream.Collectors.toSet;
|
|||||||
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
|
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
|
||||||
import static jdk.jshell.Util.*;
|
import static jdk.jshell.Util.*;
|
||||||
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
|
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
|
||||||
import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
|
import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
|
||||||
import static jdk.jshell.Snippet.SubKind.SINGLE_TYPE_IMPORT_SUBKIND;
|
import static jdk.jshell.Snippet.SubKind.SINGLE_TYPE_IMPORT_SUBKIND;
|
||||||
import static jdk.jshell.Snippet.SubKind.SINGLE_STATIC_IMPORT_SUBKIND;
|
import static jdk.jshell.Snippet.SubKind.SINGLE_STATIC_IMPORT_SUBKIND;
|
||||||
import static jdk.jshell.Snippet.SubKind.TYPE_IMPORT_ON_DEMAND_SUBKIND;
|
import static jdk.jshell.Snippet.SubKind.TYPE_IMPORT_ON_DEMAND_SUBKIND;
|
||||||
@ -339,18 +337,8 @@ class Eval {
|
|||||||
return declare(snip);
|
return declare(snip);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OuterWrap wrapInClass(String className, Set<Key> except, String userSource, Wrap guts, Collection<Snippet> plus) {
|
|
||||||
String imports = state.maps.packageAndImportsExcept(except, plus);
|
|
||||||
return OuterWrap.wrapInClass(state.maps.packageName(), className, imports, userSource, guts);
|
|
||||||
}
|
|
||||||
|
|
||||||
OuterWrap wrapInClass(Snippet snip, Set<Key> except, Wrap guts, Collection<Snippet> plus) {
|
|
||||||
return wrapInClass(snip.className(), except, snip.source(), guts, plus);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AnalyzeTask trialCompile(Wrap guts) {
|
private AnalyzeTask trialCompile(Wrap guts) {
|
||||||
OuterWrap outer = wrapInClass(REPL_DOESNOTMATTER_CLASS_NAME,
|
OuterWrap outer = state.outerMap.wrapInTrialClass(guts);
|
||||||
Collections.emptySet(), "", guts, null);
|
|
||||||
return state.taskFactory.new AnalyzeTask(outer);
|
return state.taskFactory.new AnalyzeTask(outer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,7 +456,7 @@ class Eval {
|
|||||||
if (si.status().isDefined) {
|
if (si.status().isDefined) {
|
||||||
if (si.isExecutable()) {
|
if (si.isExecutable()) {
|
||||||
try {
|
try {
|
||||||
value = state.executionControl().commandInvoke(state.maps.classFullName(si));
|
value = state.executionControl().commandInvoke(si.classFullName());
|
||||||
value = si.subKind().hasValue()
|
value = si.subKind().hasValue()
|
||||||
? expunge(value)
|
? expunge(value)
|
||||||
: "";
|
: "";
|
||||||
@ -504,37 +492,54 @@ class Eval {
|
|||||||
return events(c, outs, value, exception);
|
return events(c, outs, value, exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean interestingEvent(SnippetEvent e) {
|
||||||
|
return e.isSignatureChange()
|
||||||
|
|| e.causeSnippet() == null
|
||||||
|
|| e.status() != e.previousStatus()
|
||||||
|
|| e.exception() != null;
|
||||||
|
}
|
||||||
|
|
||||||
private List<SnippetEvent> events(Unit c, Collection<Unit> outs, String value, Exception exception) {
|
private List<SnippetEvent> events(Unit c, Collection<Unit> outs, String value, Exception exception) {
|
||||||
List<SnippetEvent> events = new ArrayList<>();
|
List<SnippetEvent> events = new ArrayList<>();
|
||||||
events.add(c.event(value, exception));
|
events.add(c.event(value, exception));
|
||||||
events.addAll(outs.stream()
|
events.addAll(outs.stream()
|
||||||
.filter(u -> u != c)
|
.filter(u -> u != c)
|
||||||
.map(u -> u.event(null, null))
|
.map(u -> u.event(null, null))
|
||||||
|
.filter(this::interestingEvent)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
events.addAll(outs.stream()
|
events.addAll(outs.stream()
|
||||||
.flatMap(u -> u.secondaryEvents().stream())
|
.flatMap(u -> u.secondaryEvents().stream())
|
||||||
|
.filter(this::interestingEvent)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
//System.err.printf("Events: %s\n", events);
|
//System.err.printf("Events: %s\n", events);
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<OuterWrap> outerWrapSet(Collection<Unit> units) {
|
||||||
|
return units.stream()
|
||||||
|
.map(u -> u.snippet().outerWrap())
|
||||||
|
.collect(toSet());
|
||||||
|
}
|
||||||
|
|
||||||
private Set<Unit> compileAndLoad(Set<Unit> ins) {
|
private Set<Unit> compileAndLoad(Set<Unit> ins) {
|
||||||
if (ins.isEmpty()) {
|
if (ins.isEmpty()) {
|
||||||
return ins;
|
return ins;
|
||||||
}
|
}
|
||||||
Set<Unit> replaced = new LinkedHashSet<>();
|
Set<Unit> replaced = new LinkedHashSet<>();
|
||||||
|
// Loop until dependencies and errors are stable
|
||||||
while (true) {
|
while (true) {
|
||||||
state.debug(DBG_GEN, "compileAndLoad %s\n", ins);
|
state.debug(DBG_GEN, "compileAndLoad %s\n", ins);
|
||||||
|
|
||||||
ins.stream().forEach(u -> u.initialize(ins));
|
ins.stream().forEach(u -> u.initialize());
|
||||||
AnalyzeTask at = state.taskFactory.new AnalyzeTask(ins);
|
ins.stream().forEach(u -> u.setWrap(ins, ins));
|
||||||
|
AnalyzeTask at = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
|
||||||
ins.stream().forEach(u -> u.setDiagnostics(at));
|
ins.stream().forEach(u -> u.setDiagnostics(at));
|
||||||
|
|
||||||
// corral any Snippets that need it
|
// corral any Snippets that need it
|
||||||
AnalyzeTask cat;
|
AnalyzeTask cat;
|
||||||
if (ins.stream().anyMatch(u -> u.corralIfNeeded(ins))) {
|
if (ins.stream().anyMatch(u -> u.corralIfNeeded(ins))) {
|
||||||
// if any were corralled, re-analyze everything
|
// if any were corralled, re-analyze everything
|
||||||
cat = state.taskFactory.new AnalyzeTask(ins);
|
cat = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
|
||||||
ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
|
ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
|
||||||
} else {
|
} else {
|
||||||
cat = at;
|
cat = at;
|
||||||
@ -556,7 +561,7 @@ class Eval {
|
|||||||
legit.stream().forEach(u -> u.setWrap(ins, legit));
|
legit.stream().forEach(u -> u.setWrap(ins, legit));
|
||||||
|
|
||||||
// generate class files for those capable
|
// generate class files for those capable
|
||||||
CompileTask ct = state.taskFactory.new CompileTask(legit);
|
CompileTask ct = state.taskFactory.new CompileTask(outerWrapSet(legit));
|
||||||
if (!ct.compile()) {
|
if (!ct.compile()) {
|
||||||
// oy! compile failed because of recursive new unresolved
|
// oy! compile failed because of recursive new unresolved
|
||||||
if (legit.stream()
|
if (legit.stream()
|
||||||
@ -572,8 +577,8 @@ class Eval {
|
|||||||
|
|
||||||
// load all new classes
|
// load all new classes
|
||||||
load(legit.stream()
|
load(legit.stream()
|
||||||
.flatMap(u -> u.classesToLoad(ct.classInfoList(u)))
|
.flatMap(u -> u.classesToLoad(ct.classInfoList(u.snippet().outerWrap())))
|
||||||
.collect(toList()));
|
.collect(toSet()));
|
||||||
// attempt to redefine the remaining classes
|
// attempt to redefine the remaining classes
|
||||||
List<Unit> toReplace = legit.stream()
|
List<Unit> toReplace = legit.stream()
|
||||||
.filter(u -> !u.doRedefines())
|
.filter(u -> !u.doRedefines())
|
||||||
@ -607,7 +612,7 @@ class Eval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(List<ClassInfo> cil) {
|
private void load(Set<ClassInfo> cil) {
|
||||||
if (!cil.isEmpty()) {
|
if (!cil.isEmpty()) {
|
||||||
state.executionControl().commandLoad(cil);
|
state.executionControl().commandLoad(cil);
|
||||||
}
|
}
|
||||||
@ -625,20 +630,14 @@ class Eval {
|
|||||||
StackTraceElement[] elems = new StackTraceElement[last + 1];
|
StackTraceElement[] elems = new StackTraceElement[last + 1];
|
||||||
for (int i = 0; i <= last; ++i) {
|
for (int i = 0; i <= last; ++i) {
|
||||||
StackTraceElement r = raw[i];
|
StackTraceElement r = raw[i];
|
||||||
String rawKlass = r.getClassName();
|
OuterSnippetsClassWrap outer = state.outerMap.getOuter(r.getClassName());
|
||||||
Matcher matcher = prefixPattern.matcher(rawKlass);
|
if (outer != null) {
|
||||||
String num;
|
String klass = expunge(r.getClassName());
|
||||||
if (matcher.find() && (num = matcher.group("num")) != null) {
|
|
||||||
int end = matcher.end();
|
|
||||||
if (rawKlass.charAt(end - 1) == '$') {
|
|
||||||
--end;
|
|
||||||
}
|
|
||||||
int id = Integer.parseInt(num);
|
|
||||||
Snippet si = state.maps.getSnippet(id);
|
|
||||||
String klass = expunge(rawKlass);
|
|
||||||
String method = r.getMethodName().equals(DOIT_METHOD_NAME) ? "" : r.getMethodName();
|
String method = r.getMethodName().equals(DOIT_METHOD_NAME) ? "" : r.getMethodName();
|
||||||
String file = "#" + id;
|
int wln = r.getLineNumber() - 1;
|
||||||
int line = si.outerWrap().wrapLineToSnippetLine(r.getLineNumber() - 1) + 1;
|
int line = outer.wrapLineToSnippetLine(wln) + 1;
|
||||||
|
Snippet sn = outer.wrapLineToSnippet(wln);
|
||||||
|
String file = "#" + sn.id();
|
||||||
elems[i] = new StackTraceElement(klass, method, file, line);
|
elems[i] = new StackTraceElement(klass, method, file, line);
|
||||||
} else if (r.getFileName().equals("<none>")) {
|
} else if (r.getFileName().equals("<none>")) {
|
||||||
elems[i] = new StackTraceElement(r.getClassName(), r.getMethodName(), null, r.getLineNumber());
|
elems[i] = new StackTraceElement(r.getClassName(), r.getMethodName(), null, r.getLineNumber());
|
||||||
@ -654,7 +653,7 @@ class Eval {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWrap(StackTraceElement ste) {
|
private boolean isWrap(StackTraceElement ste) {
|
||||||
return prefixPattern.matcher(ste.getClassName()).find();
|
return PREFIX_PATTERN.matcher(ste.getClassName()).find();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiagList modifierDiagnostics(ModifiersTree modtree,
|
private DiagList modifierDiagnostics(ModifiersTree modtree,
|
||||||
@ -714,11 +713,6 @@ class Eval {
|
|||||||
public String getMessage(Locale locale) {
|
public String getMessage(Locale locale) {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Unit unitOrNull() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Modifier> list = new ArrayList<>();
|
List<Modifier> list = new ArrayList<>();
|
||||||
|
@ -36,6 +36,7 @@ import java.net.ServerSocket;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import com.sun.jdi.*;
|
import com.sun.jdi.*;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -94,7 +95,7 @@ class ExecutionControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean commandLoad(List<ClassInfo> cil) {
|
boolean commandLoad(Collection<ClassInfo> cil) {
|
||||||
try {
|
try {
|
||||||
out.writeInt(CMD_LOAD);
|
out.writeInt(CMD_LOAD);
|
||||||
out.writeInt(cil.size());
|
out.writeInt(cil.size());
|
||||||
@ -122,7 +123,7 @@ class ExecutionControl {
|
|||||||
String result = in.readUTF();
|
String result = in.readUTF();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} catch (IOException | ClassNotFoundException ex) {
|
} catch (IOException | RuntimeException ex) {
|
||||||
if (!env.connection().isRunning()) {
|
if (!env.connection().isRunning()) {
|
||||||
env.shutdown();
|
env.shutdown();
|
||||||
} else {
|
} else {
|
||||||
@ -204,7 +205,7 @@ class ExecutionControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean readAndReportExecutionResult() throws IOException, ClassNotFoundException, EvalException, UnresolvedReferenceException {
|
private boolean readAndReportExecutionResult() throws IOException, EvalException, UnresolvedReferenceException {
|
||||||
int ok = in.readInt();
|
int ok = in.readInt();
|
||||||
switch (ok) {
|
switch (ok) {
|
||||||
case RESULT_SUCCESS:
|
case RESULT_SUCCESS:
|
||||||
@ -224,7 +225,7 @@ class ExecutionControl {
|
|||||||
case RESULT_CORRALLED: {
|
case RESULT_CORRALLED: {
|
||||||
int id = in.readInt();
|
int id = in.readInt();
|
||||||
StackTraceElement[] elems = readStackTrace();
|
StackTraceElement[] elems = readStackTrace();
|
||||||
Snippet si = maps.getSnippet(id);
|
Snippet si = maps.getSnippetDeadOrAlive(id);
|
||||||
throw new UnresolvedReferenceException((DeclarationSnippet) si, elems);
|
throw new UnresolvedReferenceException((DeclarationSnippet) si, elems);
|
||||||
}
|
}
|
||||||
case RESULT_KILLED: {
|
case RESULT_KILLED: {
|
||||||
|
@ -77,6 +77,7 @@ public class JShell implements AutoCloseable {
|
|||||||
|
|
||||||
final SnippetMaps maps;
|
final SnippetMaps maps;
|
||||||
final KeyMap keyMap;
|
final KeyMap keyMap;
|
||||||
|
final OuterWrapMap outerMap;
|
||||||
final TaskFactory taskFactory;
|
final TaskFactory taskFactory;
|
||||||
final InputStream in;
|
final InputStream in;
|
||||||
final PrintStream out;
|
final PrintStream out;
|
||||||
@ -106,8 +107,8 @@ public class JShell implements AutoCloseable {
|
|||||||
this.idGenerator = b.idGenerator;
|
this.idGenerator = b.idGenerator;
|
||||||
|
|
||||||
this.maps = new SnippetMaps(this);
|
this.maps = new SnippetMaps(this);
|
||||||
maps.setPackageName("REPL");
|
|
||||||
this.keyMap = new KeyMap(this);
|
this.keyMap = new KeyMap(this);
|
||||||
|
this.outerMap = new OuterWrapMap(this);
|
||||||
this.taskFactory = new TaskFactory(this);
|
this.taskFactory = new TaskFactory(this);
|
||||||
this.eval = new Eval(this);
|
this.eval = new Eval(this);
|
||||||
this.classTracker = new ClassTracker(this);
|
this.classTracker = new ClassTracker(this);
|
||||||
@ -563,7 +564,7 @@ public class JShell implements AutoCloseable {
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
messageFormat("jshell.exc.var.not.valid", snippet, snippet.status()));
|
messageFormat("jshell.exc.var.not.valid", snippet, snippet.status()));
|
||||||
}
|
}
|
||||||
String value = executionControl().commandVarValue(maps.classFullName(snippet), snippet.name());
|
String value = executionControl().commandVarValue(snippet.classFullName(), snippet.name());
|
||||||
return expunge(value);
|
return expunge(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.jshell;
|
||||||
|
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The outer wrap for a set of snippets wrapped in a generated class
|
||||||
|
* @author Robert Field
|
||||||
|
*/
|
||||||
|
public class OuterImportSnippetWrap extends OuterWrap {
|
||||||
|
|
||||||
|
private final Snippet snippet;
|
||||||
|
|
||||||
|
OuterImportSnippetWrap(Wrap wrap, Snippet snippet) {
|
||||||
|
super(wrap);
|
||||||
|
this.snippet = snippet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
|
||||||
|
return new WrappedDiagnostic(d) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Snippet snippetOrNull() {
|
||||||
|
return snippet;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OISW(" + w + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* 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.jshell;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import jdk.jshell.Wrap.CompoundWrap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The outer wrap for a set of snippets wrapped in a generated class
|
||||||
|
* @author Robert Field
|
||||||
|
*/
|
||||||
|
public class OuterSnippetsClassWrap extends OuterWrap {
|
||||||
|
|
||||||
|
private final String className;
|
||||||
|
private final LinkedHashMap<Wrap, Snippet> wrapToSnippet;
|
||||||
|
|
||||||
|
OuterSnippetsClassWrap(String className, CompoundWrap w, List<Snippet> snippets, List<Wrap> wraps) {
|
||||||
|
super(w);
|
||||||
|
assert snippets == null || snippets.size() == wraps.size();
|
||||||
|
this.className = className;
|
||||||
|
wrapToSnippet = new LinkedHashMap<>();
|
||||||
|
for (int i = 0; i < snippets.size(); ++i) {
|
||||||
|
wrapToSnippet.put(wraps.get(i), snippets.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Snippet wrapLineToSnippet(int wline) {
|
||||||
|
Wrap wrap = ((CompoundWrap)w).wrapLineToWrap(wline);
|
||||||
|
return wrapToSnippet.get(wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
|
||||||
|
return new WrappedDiagnostic(d) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Snippet snippetOrNull() {
|
||||||
|
Wrap wrap = ((CompoundWrap) w).wrapIndexToWrap(diag.getPosition());
|
||||||
|
Snippet sn = wrapToSnippet.get(wrap);
|
||||||
|
if (sn != null) {
|
||||||
|
return sn;
|
||||||
|
} else {
|
||||||
|
return super.snippetOrNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int ordinal(Snippet sn) {
|
||||||
|
int i = 0;
|
||||||
|
for (Snippet si : wrapToSnippet.values()) {
|
||||||
|
if (si == sn) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className() {
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OSCW(" + className + ":" + w + ")";
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015-2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,47 +25,23 @@
|
|||||||
|
|
||||||
package jdk.jshell;
|
package jdk.jshell;
|
||||||
|
|
||||||
import jdk.jshell.Wrap.CompoundWrap;
|
|
||||||
import static jdk.jshell.Util.*;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
|
import jdk.internal.jshell.remote.RemoteCodes;
|
||||||
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
|
import static jdk.jshell.Util.*;
|
||||||
|
import static jdk.internal.jshell.remote.RemoteCodes.REPL_PACKAGE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Robert Field
|
* @author Robert Field
|
||||||
*/
|
*/
|
||||||
final class OuterWrap implements GeneralWrap {
|
class OuterWrap implements GeneralWrap {
|
||||||
|
|
||||||
private final String packageName;
|
protected final Wrap w;
|
||||||
private final String className;
|
|
||||||
private final String userSource;
|
|
||||||
private final GeneralWrap w;
|
|
||||||
private final Wrap guts;
|
|
||||||
|
|
||||||
public static OuterWrap wrapInClass(String packageName, String className,
|
OuterWrap(Wrap wrap) {
|
||||||
String imports, String userSource, Wrap guts) {
|
this.w = wrap;
|
||||||
GeneralWrap kw = new CompoundWrap(
|
|
||||||
imports
|
|
||||||
+ "class " + className + " {\n",
|
|
||||||
guts,
|
|
||||||
"}\n");
|
|
||||||
return new OuterWrap(packageName, className, userSource, kw, guts);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OuterWrap wrapImport(String userSource, Wrap guts) {
|
|
||||||
return new OuterWrap("", "", userSource, guts, guts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private OuterWrap(String packageName, String className, String userSource,
|
|
||||||
GeneralWrap w, Wrap guts) {
|
|
||||||
this.packageName = packageName;
|
|
||||||
this.className = className;
|
|
||||||
this.userSource = userSource;
|
|
||||||
this.w = w;
|
|
||||||
this.guts = guts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -114,19 +90,28 @@ final class OuterWrap implements GeneralWrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String className() {
|
public String className() {
|
||||||
return className;
|
return REPL_DOESNOTMATTER_CLASS_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String classFullName() {
|
public String classFullName() {
|
||||||
return packageName + "." + className;
|
return REPL_PACKAGE + "." + className();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserSource() {
|
@Override
|
||||||
return userSource;
|
public int hashCode() {
|
||||||
|
return className().hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
Wrap guts() {
|
@Override
|
||||||
return guts;
|
public boolean equals(Object o) {
|
||||||
|
return (o instanceof OuterWrap)
|
||||||
|
? className().equals(((OuterWrap) o).className())
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OW(" + w + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
|
Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
|
||||||
@ -135,7 +120,7 @@ final class OuterWrap implements GeneralWrap {
|
|||||||
|
|
||||||
class WrappedDiagnostic extends Diag {
|
class WrappedDiagnostic extends Diag {
|
||||||
|
|
||||||
private final Diagnostic<? extends JavaFileObject> diag;
|
final Diagnostic<? extends JavaFileObject> diag;
|
||||||
|
|
||||||
WrappedDiagnostic(Diagnostic<? extends JavaFileObject> diag) {
|
WrappedDiagnostic(Diagnostic<? extends JavaFileObject> diag) {
|
||||||
this.diag = diag;
|
this.diag = diag;
|
||||||
@ -171,18 +156,6 @@ final class OuterWrap implements GeneralWrap {
|
|||||||
return expunge(diag.getMessage(locale));
|
return expunge(diag.getMessage(locale));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Unit unitOrNull() {
|
|
||||||
JavaFileObject fo = diag.getSource();
|
|
||||||
if (fo instanceof SourceMemoryJavaFileObject) {
|
|
||||||
SourceMemoryJavaFileObject sfo = (SourceMemoryJavaFileObject) fo;
|
|
||||||
if (sfo.getOrigin() instanceof Unit) {
|
|
||||||
return (Unit) sfo.getOrigin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isResolutionError() {
|
boolean isResolutionError() {
|
||||||
if (!super.isResolutionError()) {
|
if (!super.isResolutionError()) {
|
||||||
@ -190,7 +163,7 @@ final class OuterWrap implements GeneralWrap {
|
|||||||
}
|
}
|
||||||
for (String line : diag.getMessage(PARSED_LOCALE).split("\\r?\\n")) {
|
for (String line : diag.getMessage(PARSED_LOCALE).split("\\r?\\n")) {
|
||||||
if (line.trim().startsWith("location:")) {
|
if (line.trim().startsWith("location:")) {
|
||||||
if (!line.contains(REPL_CLASS_PREFIX)) {
|
if (!line.contains(RemoteCodes.REPL_CLASS_PREFIX)) {
|
||||||
// Resolution error must occur within a REPL class or it is not resolvable
|
// Resolution error must occur within a REPL class or it is not resolvable
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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.jshell;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import jdk.jshell.Wrap.CompoundWrap;
|
||||||
|
import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
|
||||||
|
import static jdk.internal.jshell.remote.RemoteCodes.REPL_CLASS_PREFIX;
|
||||||
|
import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
|
||||||
|
import static jdk.jshell.Util.asLetters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Robert Field
|
||||||
|
*/
|
||||||
|
public class OuterWrapMap {
|
||||||
|
|
||||||
|
private final JShell state;
|
||||||
|
private final Map<String,OuterSnippetsClassWrap> classOuters = new HashMap<>();
|
||||||
|
|
||||||
|
OuterWrapMap(JShell state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
OuterSnippetsClassWrap getOuter(String className) {
|
||||||
|
Matcher matcher = PREFIX_PATTERN.matcher(className);
|
||||||
|
String cn;
|
||||||
|
if (matcher.find() && (cn = matcher.group("class")) != null) {
|
||||||
|
return classOuters.get(cn);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompoundWrap wrappedInClass(String className, String imports, List<Wrap> wraps) {
|
||||||
|
List<Object> elems = new ArrayList<>(wraps.size() + 2);
|
||||||
|
elems.add(imports +
|
||||||
|
"class " + className + " {\n");
|
||||||
|
elems.addAll(wraps);
|
||||||
|
elems.add("}\n");
|
||||||
|
return new CompoundWrap(elems.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
OuterWrap wrapInClass(Set<Key> except, Collection<Snippet> plus,
|
||||||
|
List<Snippet> snippets, List<Wrap> wraps) {
|
||||||
|
String imports = state.maps.packageAndImportsExcept(except, plus);
|
||||||
|
// className is unique to the set of snippets and their version (seq)
|
||||||
|
String className = REPL_CLASS_PREFIX + snippets.stream()
|
||||||
|
.sorted((sn1, sn2) -> sn1.key().index() - sn2.key().index())
|
||||||
|
.map(sn -> "" + sn.key().index() + asLetters(sn.sequenceNumber()))
|
||||||
|
.collect(Collectors.joining("_"));
|
||||||
|
CompoundWrap w = wrappedInClass(className, imports, wraps);
|
||||||
|
OuterSnippetsClassWrap now = new OuterSnippetsClassWrap(className, w, snippets, wraps);
|
||||||
|
classOuters.put(className, now);
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
OuterWrap wrapInTrialClass(Wrap wrap) {
|
||||||
|
String imports = state.maps.packageAndImportsExcept(null, null);
|
||||||
|
CompoundWrap w = wrappedInClass(REPL_DOESNOTMATTER_CLASS_NAME, imports,
|
||||||
|
Collections.singletonList(wrap));
|
||||||
|
return new OuterWrap(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
OuterWrap wrapImport(Wrap guts, Snippet sn) {
|
||||||
|
return new OuterImportSnippetWrap(guts, sn);
|
||||||
|
}
|
||||||
|
}
|
@ -28,8 +28,6 @@ package jdk.jshell;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import static jdk.jshell.Util.REPL_CLASS_PREFIX;
|
|
||||||
import static jdk.jshell.Util.asLetters;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Snippet represents a snippet of Java source code as passed to
|
* A Snippet represents a snippet of Java source code as passed to
|
||||||
@ -503,7 +501,6 @@ public abstract class Snippet {
|
|||||||
private final SubKind subkind;
|
private final SubKind subkind;
|
||||||
|
|
||||||
private int seq;
|
private int seq;
|
||||||
private String className;
|
|
||||||
private String id;
|
private String id;
|
||||||
private OuterWrap outer;
|
private OuterWrap outer;
|
||||||
private Status status;
|
private Status status;
|
||||||
@ -615,7 +612,6 @@ public abstract class Snippet {
|
|||||||
|
|
||||||
final void setSequenceNumber(int seq) {
|
final void setSequenceNumber(int seq) {
|
||||||
this.seq = seq;
|
this.seq = seq;
|
||||||
this.className = REPL_CLASS_PREFIX + key().index() + asLetters(seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOuterWrap(OuterWrap outer) {
|
void setOuterWrap(OuterWrap outer) {
|
||||||
@ -653,7 +649,11 @@ public abstract class Snippet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String className() {
|
String className() {
|
||||||
return className;
|
return outer.className();
|
||||||
|
}
|
||||||
|
|
||||||
|
String classFullName() {
|
||||||
|
return outer.classFullName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,8 +38,9 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
|
import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
|
||||||
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_DEP;
|
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_DEP;
|
||||||
|
import static jdk.internal.jshell.remote.RemoteCodes.REPL_PACKAGE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintain relationships between the significant entities: Snippets,
|
* Maintain relationships between the significant entities: Snippets,
|
||||||
@ -48,7 +49,6 @@ import static jdk.internal.jshell.debug.InternalDebugControl.DBG_DEP;
|
|||||||
*/
|
*/
|
||||||
final class SnippetMaps {
|
final class SnippetMaps {
|
||||||
|
|
||||||
private String packageName;
|
|
||||||
private final List<Snippet> keyIndexToSnippet = new ArrayList<>();
|
private final List<Snippet> keyIndexToSnippet = new ArrayList<>();
|
||||||
private final Set<Snippet> snippets = new LinkedHashSet<>();
|
private final Set<Snippet> snippets = new LinkedHashSet<>();
|
||||||
private final Map<String, Set<Integer>> dependencies = new HashMap<>();
|
private final Map<String, Set<Integer>> dependencies = new HashMap<>();
|
||||||
@ -81,6 +81,13 @@ final class SnippetMaps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Snippet getSnippet(int ki) {
|
Snippet getSnippet(int ki) {
|
||||||
|
Snippet sn = getSnippetDeadOrAlive(ki);
|
||||||
|
return (sn != null && !sn.status().isActive)
|
||||||
|
? null
|
||||||
|
: sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
Snippet getSnippetDeadOrAlive(int ki) {
|
||||||
if (ki >= keyIndexToSnippet.size()) {
|
if (ki >= keyIndexToSnippet.size()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -91,21 +98,9 @@ final class SnippetMaps {
|
|||||||
return new ArrayList<>(snippets);
|
return new ArrayList<>(snippets);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPackageName(String n) {
|
|
||||||
packageName = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
String packageName() {
|
|
||||||
return packageName;
|
|
||||||
}
|
|
||||||
|
|
||||||
String classFullName(Snippet sn) {
|
|
||||||
return packageName + "." + sn.className();
|
|
||||||
}
|
|
||||||
|
|
||||||
String packageAndImportsExcept(Set<Key> except, Collection<Snippet> plus) {
|
String packageAndImportsExcept(Set<Key> except, Collection<Snippet> plus) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("package ").append(packageName()).append(";\n");
|
sb.append("package ").append(REPL_PACKAGE).append(";\n");
|
||||||
for (Snippet si : keyIndexToSnippet) {
|
for (Snippet si : keyIndexToSnippet) {
|
||||||
if (si != null && si.status().isDefined && (except == null || !except.contains(si.key()))) {
|
if (si != null && si.status().isDefined && (except == null || !except.contains(si.key()))) {
|
||||||
sb.append(si.importLine(state));
|
sb.append(si.importLine(state));
|
||||||
@ -137,7 +132,7 @@ final class SnippetMaps {
|
|||||||
}
|
}
|
||||||
List<Snippet> deps = new ArrayList<>();
|
List<Snippet> deps = new ArrayList<>();
|
||||||
for (Integer dss : depset) {
|
for (Integer dss : depset) {
|
||||||
Snippet dep = getSnippet(dss);
|
Snippet dep = getSnippetDeadOrAlive(dss);
|
||||||
if (dep != null) {
|
if (dep != null) {
|
||||||
deps.add(dep);
|
deps.add(dep);
|
||||||
state.debug(DBG_DEP, "Found dependency %s -> %s\n", snip.name(), dep.name());
|
state.debug(DBG_DEP, "Found dependency %s -> %s\n", snip.name(), dep.name());
|
||||||
@ -161,7 +156,7 @@ final class SnippetMaps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String fullClassNameAndPackageToClass(String full, String pkg) {
|
String fullClassNameAndPackageToClass(String full, String pkg) {
|
||||||
Matcher mat = prefixPattern.matcher(full);
|
Matcher mat = PREFIX_PATTERN.matcher(full);
|
||||||
if (mat.lookingAt()) {
|
if (mat.lookingAt()) {
|
||||||
return full.substring(mat.end());
|
return full.substring(mat.end());
|
||||||
}
|
}
|
||||||
@ -195,6 +190,6 @@ final class SnippetMaps {
|
|||||||
private Stream<ImportSnippet> importSnippets() {
|
private Stream<ImportSnippet> importSnippets() {
|
||||||
return state.keyMap.importKeys()
|
return state.keyMap.importKeys()
|
||||||
.map(key -> (ImportSnippet)getSnippet(key))
|
.map(key -> (ImportSnippet)getSnippet(key))
|
||||||
.filter(sn -> state.status(sn).isDefined);
|
.filter(sn -> sn != null && state.status(sn).isDefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,11 +211,6 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
throw new InternalError();
|
throw new InternalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
private OuterWrap wrapInClass(Wrap guts) {
|
|
||||||
String imports = proc.maps.packageAndImportsExcept(null, null);
|
|
||||||
return OuterWrap.wrapInClass(proc.maps.packageName(), REPL_DOESNOTMATTER_CLASS_NAME, imports, "", guts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tree.Kind guessKind(String code) {
|
private Tree.Kind guessKind(String code) {
|
||||||
ParseTask pt = proc.taskFactory.new ParseTask(code);
|
ParseTask pt = proc.taskFactory.new ParseTask(code);
|
||||||
List<? extends Tree> units = pt.units();
|
List<? extends Tree> units = pt.units();
|
||||||
@ -258,13 +253,13 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
OuterWrap codeWrap;
|
OuterWrap codeWrap;
|
||||||
switch (guessKind(code)) {
|
switch (guessKind(code)) {
|
||||||
case IMPORT:
|
case IMPORT:
|
||||||
codeWrap = OuterWrap.wrapImport(null, Wrap.simpleWrap(code + "any.any"));
|
codeWrap = proc.outerMap.wrapImport(Wrap.simpleWrap(code + "any.any"), null);
|
||||||
break;
|
break;
|
||||||
case METHOD:
|
case METHOD:
|
||||||
codeWrap = wrapInClass(Wrap.classMemberWrap(code));
|
codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(code));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
codeWrap = wrapInClass(Wrap.methodWrap(code));
|
codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
String requiredPrefix = identifier;
|
String requiredPrefix = identifier;
|
||||||
@ -946,7 +941,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
if (guessKind(code) == Kind.IMPORT)
|
if (guessKind(code) == Kind.IMPORT)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
OuterWrap codeWrap = wrapInClass(Wrap.methodWrap(code));
|
OuterWrap codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
|
||||||
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
|
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
|
||||||
SourcePositions sp = at.trees().getSourcePositions();
|
SourcePositions sp = at.trees().getSourcePositions();
|
||||||
CompilationUnitTree topLevel = at.firstCuTree();
|
CompilationUnitTree topLevel = at.firstCuTree();
|
||||||
@ -1064,7 +1059,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
case INTERFACE: case ANNOTATION_TYPE: case VARIABLE:
|
case INTERFACE: case ANNOTATION_TYPE: case VARIABLE:
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
codeWrap = wrapInClass(Wrap.methodWrap(code));
|
codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
|
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
|
||||||
@ -1104,10 +1099,10 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
|||||||
case IMPORT:
|
case IMPORT:
|
||||||
return new QualifiedNames(Collections.emptyList(), -1, true, false);
|
return new QualifiedNames(Collections.emptyList(), -1, true, false);
|
||||||
case METHOD:
|
case METHOD:
|
||||||
codeWrap = wrapInClass(Wrap.classMemberWrap(code));
|
codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(code));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
codeWrap = wrapInClass(Wrap.methodWrap(code));
|
codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
|
AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -148,48 +148,22 @@ class TaskFactory {
|
|||||||
public String getMessage(Locale locale) {
|
public String getMessage(Locale locale) {
|
||||||
return expunge(d.getMessage(locale));
|
return expunge(d.getMessage(locale));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Unit unitOrNull() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WrapSourceHandler implements SourceHandler<OuterWrap> {
|
private class WrapSourceHandler implements SourceHandler<OuterWrap> {
|
||||||
|
|
||||||
final OuterWrap wrap;
|
|
||||||
|
|
||||||
WrapSourceHandler(OuterWrap wrap) {
|
|
||||||
this.wrap = wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JavaFileObject sourceToFileObject(MemoryFileManager fm, OuterWrap w) {
|
public JavaFileObject sourceToFileObject(MemoryFileManager fm, OuterWrap w) {
|
||||||
return fm.createSourceFileObject(w, w.classFullName(), w.wrapped());
|
return fm.createSourceFileObject(w, w.classFullName(), w.wrapped());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Diag diag(Diagnostic<? extends JavaFileObject> d) {
|
|
||||||
return wrap.wrapDiag(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UnitSourceHandler implements SourceHandler<Unit> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JavaFileObject sourceToFileObject(MemoryFileManager fm, Unit u) {
|
|
||||||
return fm.createSourceFileObject(u,
|
|
||||||
state.maps.classFullName(u.snippet()),
|
|
||||||
u.snippet().outerWrap().wrapped());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Diag diag(Diagnostic<? extends JavaFileObject> d) {
|
public Diag diag(Diagnostic<? extends JavaFileObject> d) {
|
||||||
SourceMemoryJavaFileObject smjfo = (SourceMemoryJavaFileObject) d.getSource();
|
SourceMemoryJavaFileObject smjfo = (SourceMemoryJavaFileObject) d.getSource();
|
||||||
Unit u = (Unit) smjfo.getOrigin();
|
OuterWrap w = (OuterWrap) smjfo.getOrigin();
|
||||||
return u.snippet().outerWrap().wrapDiag(d);
|
return w.wrapDiag(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,13 +216,12 @@ class TaskFactory {
|
|||||||
private final Iterable<? extends CompilationUnitTree> cuts;
|
private final Iterable<? extends CompilationUnitTree> cuts;
|
||||||
|
|
||||||
AnalyzeTask(final OuterWrap wrap) {
|
AnalyzeTask(final OuterWrap wrap) {
|
||||||
this(Stream.of(wrap),
|
this(Collections.singletonList(wrap));
|
||||||
new WrapSourceHandler(wrap),
|
|
||||||
"-XDshouldStopPolicy=FLOW", "-proc:none");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalyzeTask(final Collection<Unit> units) {
|
AnalyzeTask(final Collection<OuterWrap> wraps) {
|
||||||
this(units.stream(), new UnitSourceHandler(),
|
this(wraps.stream(),
|
||||||
|
new WrapSourceHandler(),
|
||||||
"-XDshouldStopPolicy=FLOW", "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
|
"-XDshouldStopPolicy=FLOW", "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,10 +260,10 @@ class TaskFactory {
|
|||||||
*/
|
*/
|
||||||
class CompileTask extends BaseTask {
|
class CompileTask extends BaseTask {
|
||||||
|
|
||||||
private final Map<Unit, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
|
private final Map<OuterWrap, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
|
||||||
|
|
||||||
CompileTask(Collection<Unit> units) {
|
CompileTask(final Collection<OuterWrap> wraps) {
|
||||||
super(units.stream(), new UnitSourceHandler(),
|
super(wraps.stream(), new WrapSourceHandler(),
|
||||||
"-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
|
"-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,8 +275,8 @@ class TaskFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<ClassInfo> classInfoList(Unit u) {
|
List<ClassInfo> classInfoList(OuterWrap w) {
|
||||||
List<OutputMemoryJavaFileObject> l = classObjs.get(u);
|
List<OutputMemoryJavaFileObject> l = classObjs.get(w);
|
||||||
if (l == null) return Collections.emptyList();
|
if (l == null) return Collections.emptyList();
|
||||||
return l.stream()
|
return l.stream()
|
||||||
.map(fo -> state.classTracker.classInfo(fo.getName(), fo.getBytes()))
|
.map(fo -> state.classTracker.classInfo(fo.getName(), fo.getBytes()))
|
||||||
@ -315,11 +288,11 @@ class TaskFactory {
|
|||||||
//debug("listenForNewClassFile %s loc=%s kind=%s\n", className, location, kind);
|
//debug("listenForNewClassFile %s loc=%s kind=%s\n", className, location, kind);
|
||||||
if (location == CLASS_OUTPUT) {
|
if (location == CLASS_OUTPUT) {
|
||||||
state.debug(DBG_GEN, "Compiler generating class %s\n", className);
|
state.debug(DBG_GEN, "Compiler generating class %s\n", className);
|
||||||
Unit u = ((sibling instanceof SourceMemoryJavaFileObject)
|
OuterWrap w = ((sibling instanceof SourceMemoryJavaFileObject)
|
||||||
&& (((SourceMemoryJavaFileObject) sibling).getOrigin() instanceof Unit))
|
&& (((SourceMemoryJavaFileObject) sibling).getOrigin() instanceof OuterWrap))
|
||||||
? (Unit) ((SourceMemoryJavaFileObject) sibling).getOrigin()
|
? (OuterWrap) ((SourceMemoryJavaFileObject) sibling).getOrigin()
|
||||||
: null;
|
: null;
|
||||||
classObjs.compute(u, (k, v) -> (v == null)? new ArrayList<>() : v)
|
classObjs.compute(w, (k, v) -> (v == null)? new ArrayList<>() : v)
|
||||||
.add(jfo);
|
.add(jfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,18 +162,28 @@ class TreeDissector {
|
|||||||
return new Range(start, end);
|
return new Range(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree firstClassMember() {
|
MethodTree method(MethodSnippet msn) {
|
||||||
if (targetClass != null) {
|
if (targetClass == null) {
|
||||||
//TODO: missing classes
|
return null;
|
||||||
for (Tree mem : targetClass.getMembers()) {
|
}
|
||||||
if (mem.getKind() == Tree.Kind.VARIABLE) {
|
OuterWrap ow = msn.outerWrap();
|
||||||
return mem;
|
if (!(ow instanceof OuterSnippetsClassWrap)) {
|
||||||
}
|
return null;
|
||||||
if (mem.getKind() == Tree.Kind.METHOD) {
|
}
|
||||||
MethodTree mt = (MethodTree) mem;
|
int ordinal = ((OuterSnippetsClassWrap) ow).ordinal(msn);
|
||||||
if (!isDoIt(mt.getName()) && !mt.getName().toString().equals("<init>")) {
|
if (ordinal < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
String name = msn.name();
|
||||||
|
for (Tree mem : targetClass.getMembers()) {
|
||||||
|
if (mem.getKind() == Tree.Kind.METHOD) {
|
||||||
|
MethodTree mt = (MethodTree) mem;
|
||||||
|
if (mt.getName().toString().equals(name)) {
|
||||||
|
if (count == ordinal) {
|
||||||
return mt;
|
return mt;
|
||||||
}
|
}
|
||||||
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,8 +254,8 @@ class TreeDissector {
|
|||||||
return ei;
|
return ei;
|
||||||
}
|
}
|
||||||
|
|
||||||
String typeOfMethod() {
|
String typeOfMethod(MethodSnippet msn) {
|
||||||
Tree unitTree = firstClassMember();
|
Tree unitTree = method(msn);
|
||||||
if (unitTree instanceof JCMethodDecl) {
|
if (unitTree instanceof JCMethodDecl) {
|
||||||
JCMethodDecl mtree = (JCMethodDecl) unitTree;
|
JCMethodDecl mtree = (JCMethodDecl) unitTree;
|
||||||
Type mt = types().erasure(mtree.type);
|
Type mt = types().erasure(mtree.type);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -68,7 +68,7 @@ final class Unit {
|
|||||||
private final DiagList generatedDiagnostics;
|
private final DiagList generatedDiagnostics;
|
||||||
|
|
||||||
private int seq;
|
private int seq;
|
||||||
private int seqInitial;
|
private String classNameInitial;
|
||||||
private Wrap activeGuts;
|
private Wrap activeGuts;
|
||||||
private Status status;
|
private Status status;
|
||||||
private Status prevStatus;
|
private Status prevStatus;
|
||||||
@ -95,7 +95,7 @@ final class Unit {
|
|||||||
this.generatedDiagnostics = generatedDiagnostics;
|
this.generatedDiagnostics = generatedDiagnostics;
|
||||||
|
|
||||||
this.seq = isNew? 0 : siOld.sequenceNumber();
|
this.seq = isNew? 0 : siOld.sequenceNumber();
|
||||||
this.seqInitial = seq;
|
this.classNameInitial = isNew? "<none>" : siOld.className();
|
||||||
this.prevStatus = (isNew || isDependency)
|
this.prevStatus = (isNew || isDependency)
|
||||||
? si.status()
|
? si.status()
|
||||||
: siOld.status();
|
: siOld.status();
|
||||||
@ -136,28 +136,50 @@ final class Unit {
|
|||||||
return isDependency;
|
return isDependency;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isNew() {
|
void initialize() {
|
||||||
return isNew;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initialize(Collection<Unit> working) {
|
|
||||||
isAttemptingCorral = false;
|
isAttemptingCorral = false;
|
||||||
dependenciesNeeded = false;
|
dependenciesNeeded = false;
|
||||||
toRedefine = null; // assure NPE if classToLoad not called
|
toRedefine = null; // assure NPE if classToLoad not called
|
||||||
activeGuts = si.guts();
|
activeGuts = si.guts();
|
||||||
markOldDeclarationOverwritten();
|
markOldDeclarationOverwritten();
|
||||||
setWrap(working, working);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWrap(Collection<Unit> except, Collection<Unit> plus) {
|
// Set the outer wrap of our Snippet
|
||||||
si.setOuterWrap(isImport()
|
void setWrap(Collection<Unit> exceptUnit, Collection<Unit> plusUnfiltered) {
|
||||||
? OuterWrap.wrapImport(si.source(), activeGuts)
|
if (isImport()) {
|
||||||
: state.eval.wrapInClass(si,
|
si.setOuterWrap(state.outerMap.wrapImport(activeGuts, si));
|
||||||
except.stream().map(u -> u.snippet().key()).collect(toSet()),
|
} else {
|
||||||
activeGuts,
|
// Collect Units for be wrapped together. Just this except for overloaded methods
|
||||||
plus.stream().map(u -> u.snippet())
|
List<Unit> units;
|
||||||
.filter(sn -> sn != si)
|
if (snippet().kind() == Kind.METHOD) {
|
||||||
.collect(toList())));
|
String name = ((MethodSnippet) snippet()).name();
|
||||||
|
units = plusUnfiltered.stream()
|
||||||
|
.filter(u -> u.snippet().kind() == Kind.METHOD &&
|
||||||
|
((MethodSnippet) u.snippet()).name().equals(name))
|
||||||
|
.collect(toList());
|
||||||
|
} else {
|
||||||
|
units = Collections.singletonList(this);
|
||||||
|
}
|
||||||
|
// Keys to exclude from imports
|
||||||
|
Set<Key> except = exceptUnit.stream()
|
||||||
|
.map(u -> u.snippet().key())
|
||||||
|
.collect(toSet());
|
||||||
|
// Snippets to add to imports
|
||||||
|
Collection<Snippet> plus = plusUnfiltered.stream()
|
||||||
|
.filter(u -> !units.contains(u))
|
||||||
|
.map(u -> u.snippet())
|
||||||
|
.collect(toList());
|
||||||
|
// Snippets to wrap in an outer
|
||||||
|
List<Snippet> snippets = units.stream()
|
||||||
|
.map(u -> u.snippet())
|
||||||
|
.collect(toList());
|
||||||
|
// Snippet wraps to wrap in an outer
|
||||||
|
List<Wrap> wraps = units.stream()
|
||||||
|
.map(u -> u.activeGuts)
|
||||||
|
.collect(toList());
|
||||||
|
// Set the outer wrap for this snippet
|
||||||
|
si.setOuterWrap(state.outerMap.wrapInClass(except, plus, snippets, wraps));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDiagnostics(AnalyzeTask ct) {
|
void setDiagnostics(AnalyzeTask ct) {
|
||||||
@ -302,11 +324,13 @@ final class Unit {
|
|||||||
|
|
||||||
private boolean sigChanged() {
|
private boolean sigChanged() {
|
||||||
return (status.isDefined != prevStatus.isDefined)
|
return (status.isDefined != prevStatus.isDefined)
|
||||||
|| (seq != seqInitial && status.isDefined)
|
|| (status.isDefined && !si.className().equals(classNameInitial))
|
||||||
|| signatureChanged;
|
|| signatureChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<Unit> effectedDependents() {
|
Stream<Unit> effectedDependents() {
|
||||||
|
//System.err.printf("effectedDependents sigChanged=%b dependenciesNeeded=%b status=%s\n",
|
||||||
|
// sigChanged(), dependenciesNeeded, status);
|
||||||
return sigChanged() || dependenciesNeeded || status == RECOVERABLE_NOT_DEFINED
|
return sigChanged() || dependenciesNeeded || status == RECOVERABLE_NOT_DEFINED
|
||||||
? dependents()
|
? dependents()
|
||||||
: Stream.empty();
|
: Stream.empty();
|
||||||
@ -361,7 +385,7 @@ final class Unit {
|
|||||||
if (replaceOldEvent != null) secondaryEvents.add(replaceOldEvent);
|
if (replaceOldEvent != null) secondaryEvents.add(replaceOldEvent);
|
||||||
|
|
||||||
// Defined methods can overwrite methods of other (equivalent) snippets
|
// Defined methods can overwrite methods of other (equivalent) snippets
|
||||||
if (si.kind() == Kind.METHOD && status.isDefined) {
|
if (isNew && si.kind() == Kind.METHOD && status.isDefined) {
|
||||||
MethodSnippet msi = (MethodSnippet)si;
|
MethodSnippet msi = (MethodSnippet)si;
|
||||||
String oqpt = msi.qualifiedParameterTypes();
|
String oqpt = msi.qualifiedParameterTypes();
|
||||||
String nqpt = computeQualifiedParameterTypes(at, msi);
|
String nqpt = computeQualifiedParameterTypes(at, msi);
|
||||||
@ -405,7 +429,7 @@ final class Unit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String computeQualifiedParameterTypes(AnalyzeTask at, MethodSnippet msi) {
|
private String computeQualifiedParameterTypes(AnalyzeTask at, MethodSnippet msi) {
|
||||||
String rawSig = TreeDissector.createBySnippet(at, msi).typeOfMethod();
|
String rawSig = TreeDissector.createBySnippet(at, msi).typeOfMethod(msi);
|
||||||
String signature = expunge(rawSig);
|
String signature = expunge(rawSig);
|
||||||
int paren = signature.lastIndexOf(')');
|
int paren = signature.lastIndexOf(')');
|
||||||
|
|
||||||
@ -425,7 +449,9 @@ final class Unit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<SnippetEvent> secondaryEvents() {
|
List<SnippetEvent> secondaryEvents() {
|
||||||
return secondaryEvents;
|
return secondaryEvents==null
|
||||||
|
? Collections.emptyList()
|
||||||
|
: secondaryEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,7 +30,8 @@ import java.util.stream.Stream;
|
|||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
import javax.lang.model.element.Name;
|
import javax.lang.model.element.Name;
|
||||||
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
|
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
|
||||||
import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
|
import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
|
||||||
|
import static jdk.internal.jshell.remote.RemoteCodes.REPL_CLASS_PREFIX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assorted shared utilities.
|
* Assorted shared utilities.
|
||||||
@ -38,8 +39,7 @@ import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
|
|||||||
*/
|
*/
|
||||||
class Util {
|
class Util {
|
||||||
|
|
||||||
static final String REPL_CLASS_PREFIX = "$REPL";
|
static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"DOESNOTMATTER";
|
||||||
static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"00DOESNOTMATTER";
|
|
||||||
|
|
||||||
static final Locale PARSED_LOCALE = Locale.ROOT;
|
static final Locale PARSED_LOCALE = Locale.ROOT;
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ class Util {
|
|||||||
|
|
||||||
static String expunge(String s) {
|
static String expunge(String s) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (String comp : prefixPattern.split(s)) {
|
for (String comp : PREFIX_PATTERN.split(s)) {
|
||||||
sb.append(comp);
|
sb.append(comp);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
package jdk.jshell;
|
package jdk.jshell;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import static java.util.stream.Collectors.joining;
|
||||||
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
|
import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -237,6 +239,27 @@ abstract class Wrap implements GeneralWrap {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Wrap wrapIndexToWrap(long wi) {
|
||||||
|
int before = 0;
|
||||||
|
Wrap w = null;
|
||||||
|
for (Object o : os) {
|
||||||
|
if (o instanceof String) {
|
||||||
|
String s = (String) o;
|
||||||
|
before += s.length();
|
||||||
|
} else if (o instanceof Wrap) {
|
||||||
|
w = (Wrap) o;
|
||||||
|
int len = w.wrapped().length();
|
||||||
|
if ((wi - before) <= len) {
|
||||||
|
//System.err.printf("Defer to wrap %s - wi: %d. before; %d -- %s >>> %s\n",
|
||||||
|
// w, wi, before, w.debugPos(wi - before), w.wrapped());
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
before += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int wrapIndexToSnippetIndex(int wi) {
|
public int wrapIndexToSnippetIndex(int wi) {
|
||||||
int before = 0;
|
int before = 0;
|
||||||
@ -286,6 +309,25 @@ abstract class Wrap implements GeneralWrap {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Wrap wrapLineToWrap(int wline) {
|
||||||
|
int before = 0;
|
||||||
|
Wrap w = null;
|
||||||
|
for (Object o : os) {
|
||||||
|
if (o instanceof String) {
|
||||||
|
String s = (String) o;
|
||||||
|
before += countLines(s);
|
||||||
|
} else if (o instanceof Wrap) {
|
||||||
|
w = (Wrap) o;
|
||||||
|
int lns = countLines(w.wrapped());
|
||||||
|
if ((wline - before) < lns) {
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
before += lns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int wrapLineToSnippetLine(int wline) {
|
public int wrapLineToSnippetLine(int wline) {
|
||||||
int before = 0;
|
int before = 0;
|
||||||
@ -315,7 +357,10 @@ abstract class Wrap implements GeneralWrap {
|
|||||||
return snlineLast;
|
return snlineLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CompoundWrap(" + Arrays.stream(os).map(u -> u.toString()).collect(joining(",")) + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class RangeWrap extends Wrap {
|
private static class RangeWrap extends Wrap {
|
||||||
@ -404,6 +449,10 @@ abstract class Wrap implements GeneralWrap {
|
|||||||
return lastSnline;
|
return lastSnline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RangeWrap(" + range + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class NoWrap extends RangeWrap {
|
private static class NoWrap extends RangeWrap {
|
||||||
|
@ -47,6 +47,7 @@ import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
|
|||||||
import static jdk.jshell.Snippet.Status.DROPPED;
|
import static jdk.jshell.Snippet.Status.DROPPED;
|
||||||
import static jdk.jshell.Snippet.Status.REJECTED;
|
import static jdk.jshell.Snippet.Status.REJECTED;
|
||||||
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
|
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
|
||||||
|
import static jdk.jshell.Snippet.Status.NONEXISTENT;
|
||||||
import static jdk.jshell.Snippet.SubKind.*;
|
import static jdk.jshell.Snippet.SubKind.*;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
@ -83,7 +84,7 @@ public class ClassesTest extends KullaTesting {
|
|||||||
TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareFail("class A { void f() { return g(); } }", "compiler.err.prob.found.req");
|
TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareFail("class A { void f() { return g(); } }", "compiler.err.prob.found.req");
|
||||||
assertTypeDeclSnippet(c1, "A", REJECTED, CLASS_SUBKIND, 0, 2);
|
assertTypeDeclSnippet(c1, "A", REJECTED, CLASS_SUBKIND, 0, 2);
|
||||||
TypeDeclSnippet c2 = classKey(assertEval("class A { int f() { return g(); } }",
|
TypeDeclSnippet c2 = classKey(assertEval("class A { int f() { return g(); } }",
|
||||||
ste(c1, REJECTED, RECOVERABLE_DEFINED, true, null)));
|
ste(c1, NONEXISTENT, RECOVERABLE_DEFINED, true, null)));
|
||||||
assertTypeDeclSnippet(c2, "A", RECOVERABLE_DEFINED, CLASS_SUBKIND, 1, 0);
|
assertTypeDeclSnippet(c2, "A", RECOVERABLE_DEFINED, CLASS_SUBKIND, 1, 0);
|
||||||
assertDrop(c2,
|
assertDrop(c2,
|
||||||
ste(c2, RECOVERABLE_DEFINED, DROPPED, true, null));
|
ste(c2, RECOVERABLE_DEFINED, DROPPED, true, null));
|
||||||
@ -176,6 +177,7 @@ public class ClassesTest extends KullaTesting {
|
|||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//8154496: test3 update: sig change should false
|
||||||
public void classesRedeclaration3() {
|
public void classesRedeclaration3() {
|
||||||
Snippet a = classKey(assertEval("class A { }"));
|
Snippet a = classKey(assertEval("class A { }"));
|
||||||
assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"));
|
assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"));
|
||||||
@ -190,7 +192,7 @@ public class ClassesTest extends KullaTesting {
|
|||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(test1, VALID, VALID, true, MAIN_SNIPPET),
|
ste(test1, VALID, VALID, true, MAIN_SNIPPET),
|
||||||
ste(test2, VALID, VALID, true, MAIN_SNIPPET),
|
ste(test2, VALID, VALID, true, MAIN_SNIPPET),
|
||||||
ste(test3, VALID, VALID, false, MAIN_SNIPPET),
|
ste(test3, VALID, VALID, true, MAIN_SNIPPET),
|
||||||
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"));
|
assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"));
|
||||||
assertMethods(method("()A", "test"), method("(A)void", "test"), method("(int)void", "test"));
|
assertMethods(method("()A", "test"), method("(A)void", "test"), method("(int)void", "test"));
|
||||||
@ -201,8 +203,7 @@ public class ClassesTest extends KullaTesting {
|
|||||||
Snippet b = classKey(assertEval("class B extends A { }",
|
Snippet b = classKey(assertEval("class B extends A { }",
|
||||||
added(RECOVERABLE_NOT_DEFINED)));
|
added(RECOVERABLE_NOT_DEFINED)));
|
||||||
Snippet a = classKey(assertEval("class A extends B { }", DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE,
|
Snippet a = classKey(assertEval("class A extends B { }", DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE,
|
||||||
added(RECOVERABLE_NOT_DEFINED),
|
added(REJECTED)));
|
||||||
ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)));
|
|
||||||
/***
|
/***
|
||||||
assertDeclareFail("class A extends B { }", "****",
|
assertDeclareFail("class A extends B { }", "****",
|
||||||
added(REJECTED),
|
added(REJECTED),
|
||||||
|
@ -57,10 +57,10 @@ public class DropTest extends KullaTesting {
|
|||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
|
|
||||||
method = methodKey(assertEval("int mu() { return x * 4; }",
|
method = methodKey(assertEval("int mu() { return x * 4; }",
|
||||||
ste(MAIN_SNIPPET, DROPPED, RECOVERABLE_DEFINED, true, null),
|
added(RECOVERABLE_DEFINED),
|
||||||
ste(clazz, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET)));
|
ste(clazz, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET)));
|
||||||
assertEval("int x = 10;", "10",
|
assertEval("int x = 10;", "10",
|
||||||
ste(MAIN_SNIPPET, DROPPED, VALID, true, null),
|
added(VALID),
|
||||||
ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
|
ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
|
||||||
PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
|
PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
|
||||||
assertEval("c0.v();", "\"#40\"");
|
assertEval("c0.v();", "\"#40\"");
|
||||||
@ -189,12 +189,11 @@ public class DropTest extends KullaTesting {
|
|||||||
assertDrop(c,
|
assertDrop(c,
|
||||||
DiagCheck.DIAG_OK,
|
DiagCheck.DIAG_OK,
|
||||||
DiagCheck.DIAG_ERROR,
|
DiagCheck.DIAG_ERROR,
|
||||||
ste(c, RECOVERABLE_NOT_DEFINED, DROPPED, false, null),
|
ste(c, RECOVERABLE_NOT_DEFINED, DROPPED, false, null));
|
||||||
ste(d, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, c));
|
|
||||||
assertEval("interface A {}", null, null,
|
assertEval("interface A {}", null, null,
|
||||||
DiagCheck.DIAG_OK, DiagCheck.DIAG_ERROR,
|
DiagCheck.DIAG_OK,
|
||||||
ste(a, DROPPED, VALID, true, null),
|
DiagCheck.DIAG_ERROR,
|
||||||
ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET));
|
added(VALID));
|
||||||
assertClasses();
|
assertClasses();
|
||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
}
|
}
|
||||||
|
@ -651,7 +651,7 @@ public class KullaTesting {
|
|||||||
DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates);
|
DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates);
|
||||||
SnippetEvent e = events.get(0);
|
SnippetEvent e = events.get(0);
|
||||||
List<Diag> diagnostics = getState().diagnostics(e.snippet());
|
List<Diag> diagnostics = getState().diagnostics(e.snippet());
|
||||||
assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
|
if (expectedDiagnostic != null) assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
|
||||||
return e.snippet();
|
return e.snippet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -58,7 +58,7 @@ public class MethodsTest extends KullaTesting {
|
|||||||
MethodSnippet m1 = (MethodSnippet) assertDeclareFail("void f() { return g(); }", "compiler.err.prob.found.req");
|
MethodSnippet m1 = (MethodSnippet) assertDeclareFail("void f() { return g(); }", "compiler.err.prob.found.req");
|
||||||
assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
|
assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
|
||||||
MethodSnippet m2 = methodKey(assertEval("int f() { return g(); }",
|
MethodSnippet m2 = methodKey(assertEval("int f() { return g(); }",
|
||||||
ste(m1, REJECTED, RECOVERABLE_DEFINED, true, null)));
|
added(RECOVERABLE_DEFINED)));
|
||||||
assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
|
assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
|
||||||
assertMethodDeclSnippet(m2, "f", "()int", RECOVERABLE_DEFINED, 1, 0);
|
assertMethodDeclSnippet(m2, "f", "()int", RECOVERABLE_DEFINED, 1, 0);
|
||||||
}
|
}
|
||||||
@ -115,6 +115,26 @@ public class MethodsTest extends KullaTesting {
|
|||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
public void methodOverloadDependent() {
|
||||||
|
assertEval("String m(String s) { return s + s; }");
|
||||||
|
assertEval("String m(double d) { return m(\"#\" + d); }");
|
||||||
|
assertEval("String m(int x) { return m(2.25 * x); }");
|
||||||
|
assertEval("String m() { return m(3); }");
|
||||||
|
assertMethods(
|
||||||
|
method("(String)String", "m"),
|
||||||
|
method("(double)String", "m"),
|
||||||
|
method("(int)String", "m"),
|
||||||
|
method("()String", "m")
|
||||||
|
);
|
||||||
|
assertEval("m();", "\"#6.75#6.75\"");
|
||||||
|
assertEval("m(2);", "\"#4.5#4.5\"");
|
||||||
|
assertEval("m(3.14);", "\"#3.14#3.14\"");
|
||||||
|
assertEval("m(\"hi\");", "\"hihi\"");
|
||||||
|
assertActiveKeys();
|
||||||
|
}
|
||||||
|
***/
|
||||||
|
|
||||||
public void methodsRedeclaration1() {
|
public void methodsRedeclaration1() {
|
||||||
Snippet x = methodKey(assertEval("int x() { return 10; }"));
|
Snippet x = methodKey(assertEval("int x() { return 10; }"));
|
||||||
Snippet y = methodKey(assertEval("String y() { return \"\"; }"));
|
Snippet y = methodKey(assertEval("String y() { return \"\"; }"));
|
||||||
@ -149,8 +169,7 @@ public class MethodsTest extends KullaTesting {
|
|||||||
|
|
||||||
assertEval("double b() { return 3.14159; }",
|
assertEval("double b() { return 3.14159; }",
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
ste(c, VALID, VALID, false, MAIN_SNIPPET));
|
|
||||||
assertMethods(method("()int", "a"), method("()double", "b"), method("()double", "c"));
|
assertMethods(method("()int", "a"), method("()double", "b"), method("()double", "c"));
|
||||||
assertEval("c();", "3.14159");
|
assertEval("c();", "3.14159");
|
||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
@ -202,7 +221,7 @@ public class MethodsTest extends KullaTesting {
|
|||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
|
|
||||||
assertDeclareFail("int f() {}", "compiler.err.missing.ret.stmt",
|
assertDeclareFail("int f() {}", "compiler.err.missing.ret.stmt",
|
||||||
ste(MAIN_SNIPPET, REJECTED, REJECTED, false, null));
|
added(REJECTED));
|
||||||
assertNumberOfActiveMethods(0);
|
assertNumberOfActiveMethods(0);
|
||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
|
|
||||||
|
@ -97,8 +97,7 @@ public class ReplaceTest extends KullaTesting {
|
|||||||
assertEval("mu() == 0.0;", "true");
|
assertEval("mu() == 0.0;", "true");
|
||||||
assertEval("double x = 2.5;",
|
assertEval("double x = 2.5;",
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
ste(musn, VALID, VALID, false, MAIN_SNIPPET));
|
|
||||||
Collection<MethodSnippet> meths = getState().methods();
|
Collection<MethodSnippet> meths = getState().methods();
|
||||||
assertEquals(meths.size(), 1);
|
assertEquals(meths.size(), 1);
|
||||||
assertTrue(musn == meths.iterator().next(), "Identity must not change");
|
assertTrue(musn == meths.iterator().next(), "Identity must not change");
|
||||||
@ -115,8 +114,7 @@ public class ReplaceTest extends KullaTesting {
|
|||||||
assertEval("d();", "1060.0");
|
assertEval("d();", "1060.0");
|
||||||
assertEval("int a() { return 5; }",
|
assertEval("int a() { return 5; }",
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
ste(b, VALID, VALID, false, MAIN_SNIPPET));
|
|
||||||
assertEval("d();", "1150.0");
|
assertEval("d();", "1150.0");
|
||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
}
|
}
|
||||||
@ -127,8 +125,7 @@ public class ReplaceTest extends KullaTesting {
|
|||||||
assertEval("m();", "7");
|
assertEval("m();", "7");
|
||||||
assertEval("class C { int x = 99; int f() { return x; } }",
|
assertEval("class C { int x = 99; int f() { return x; } }",
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
ste(m, VALID, VALID, false, MAIN_SNIPPET));
|
|
||||||
assertEval("m();", "99");
|
assertEval("m();", "99");
|
||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
}
|
}
|
||||||
@ -140,8 +137,7 @@ public class ReplaceTest extends KullaTesting {
|
|||||||
assertEval("new A().a == 0.0;", "true");
|
assertEval("new A().a == 0.0;", "true");
|
||||||
assertEval("double x = 2.5;",
|
assertEval("double x = 2.5;",
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
ste(c, VALID, VALID, false, MAIN_SNIPPET));
|
|
||||||
Collection<TypeDeclSnippet> classes = getState().types();
|
Collection<TypeDeclSnippet> classes = getState().types();
|
||||||
assertEquals(classes.size(), 1);
|
assertEquals(classes.size(), 1);
|
||||||
assertTrue(c == classes.iterator().next(), "Identity must not change");
|
assertTrue(c == classes.iterator().next(), "Identity must not change");
|
||||||
@ -157,8 +153,7 @@ public class ReplaceTest extends KullaTesting {
|
|||||||
assertEval("new A().a == 0.0;", "true");
|
assertEval("new A().a == 0.0;", "true");
|
||||||
assertEval("double x() { return 2.5; }",
|
assertEval("double x() { return 2.5; }",
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
ste(c, VALID, VALID, false, MAIN_SNIPPET));
|
|
||||||
assertEval("x();", "2.5");
|
assertEval("x();", "2.5");
|
||||||
Collection<TypeDeclSnippet> classes = getState().types();
|
Collection<TypeDeclSnippet> classes = getState().types();
|
||||||
assertEquals(classes.size(), 1);
|
assertEquals(classes.size(), 1);
|
||||||
@ -875,18 +870,15 @@ public class ReplaceTest extends KullaTesting {
|
|||||||
MethodSnippet k1 = methodKey(assertEval(ms1, added(VALID)));
|
MethodSnippet k1 = methodKey(assertEval(ms1, added(VALID)));
|
||||||
VarSnippet xd = varKey(assertEval(xsd,
|
VarSnippet xd = varKey(assertEval(xsd,
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
|
||||||
ste(k1, VALID, VALID, false, MAIN_SNIPPET)));
|
|
||||||
MethodSnippet k2 = methodKey(assertEval(ms2,
|
MethodSnippet k2 = methodKey(assertEval(ms2,
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null), //TODO: technically, should be false
|
ste(MAIN_SNIPPET, VALID, VALID, true, null), //TODO: technically, should be false
|
||||||
ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
|
ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
|
||||||
VarSnippet xi2 = varKey(assertEval(xsi,
|
VarSnippet xi2 = varKey(assertEval(xsi,
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
|
||||||
ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
|
|
||||||
varKey(assertEval(xsd,
|
varKey(assertEval(xsd,
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
|
||||||
ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public class SnippetStatusListenerTest extends KullaTesting {
|
|||||||
getState().unsubscribe(subscription1);
|
getState().unsubscribe(subscription1);
|
||||||
|
|
||||||
assertDrop(f, DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE, ste(f, REJECTED, DROPPED, false, null));
|
assertDrop(f, DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE, ste(f, REJECTED, DROPPED, false, null));
|
||||||
assertEval("void f() { }", ste(MAIN_SNIPPET, DROPPED, VALID, true, null));
|
assertEval("void f() { }", added(VALID));
|
||||||
assertEvalException("throw new RuntimeException();");
|
assertEvalException("throw new RuntimeException();");
|
||||||
assertEquals(listener1.getEvents(), events1, "Checking that unsubscribed listener does not get events");
|
assertEquals(listener1.getEvents(), events1, "Checking that unsubscribed listener does not get events");
|
||||||
|
|
||||||
|
@ -142,8 +142,7 @@ public class SnippetTest extends KullaTesting {
|
|||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
assertEval("double f() { return 0.0; }",
|
assertEval("double f() { return 0.0; }",
|
||||||
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
ste(MAIN_SNIPPET, VALID, VALID, true, null),
|
||||||
ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
|
ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
|
||||||
ste(g, VALID, VALID, false, MAIN_SNIPPET));
|
|
||||||
assertKeys(method("()void", "g"), clazz(KullaTesting.ClassType.INTERFACE, "A"),
|
assertKeys(method("()void", "g"), clazz(KullaTesting.ClassType.INTERFACE, "A"),
|
||||||
method("()double", "f"));
|
method("()double", "f"));
|
||||||
assertActiveKeys();
|
assertActiveKeys();
|
||||||
|
@ -83,7 +83,7 @@ public class VariablesTest extends KullaTesting {
|
|||||||
public void testVarValue2() {
|
public void testVarValue2() {
|
||||||
VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
|
VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
|
||||||
badVarValue(v1);
|
badVarValue(v1);
|
||||||
VarSnippet v2 = varKey(assertEval("int a = 0;", ste(v1, REJECTED, VALID, true, null)));
|
VarSnippet v2 = varKey(assertEval("int a = 0;", added(VALID)));
|
||||||
assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
|
assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
|
||||||
badVarValue(v2);
|
badVarValue(v2);
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ public class VariablesTest extends KullaTesting {
|
|||||||
VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
|
VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
|
||||||
assertVariableDeclSnippet(v1, "a", "int", REJECTED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 1);
|
assertVariableDeclSnippet(v1, "a", "int", REJECTED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 1);
|
||||||
VarSnippet v2 = varKey(assertEval("int a = 0;",
|
VarSnippet v2 = varKey(assertEval("int a = 0;",
|
||||||
ste(v1, REJECTED, VALID, true, null)));
|
added(VALID)));
|
||||||
assertVariableDeclSnippet(v2, "a", "int", VALID, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
|
assertVariableDeclSnippet(v2, "a", "int", VALID, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
|
||||||
assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
|
assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
|
||||||
assertVariableDeclSnippet(v2, "a", "int", DROPPED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
|
assertVariableDeclSnippet(v2, "a", "int", DROPPED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user