8249197: JShell: variable declaration with unicode type name gets garbled result
8249199: JShell: Consistent representation of unicode Reviewed-by: jlahoda
This commit is contained in:
parent
5088193336
commit
6e198fec0b
@ -24,15 +24,13 @@
|
||||
*/
|
||||
package jdk.jshell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.Name;
|
||||
|
||||
import com.sun.source.tree.ArrayTypeTree;
|
||||
import com.sun.source.tree.AssignmentTree;
|
||||
import com.sun.source.tree.ClassTree;
|
||||
@ -49,9 +47,7 @@ import com.sun.tools.javac.tree.Pretty;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo;
|
||||
import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo.AnonymousDescription;
|
||||
import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo.AnonymousDescription.VariableDesc;
|
||||
@ -304,6 +300,7 @@ class Eval {
|
||||
for (Tree unitTree : units) {
|
||||
VariableTree vt = (VariableTree) unitTree;
|
||||
String name = vt.getName().toString();
|
||||
// String name = userReadableName(vt.getName(), compileSource);
|
||||
String typeName;
|
||||
String fullTypeName;
|
||||
String displayType;
|
||||
@ -400,13 +397,18 @@ class Eval {
|
||||
winit = Wrap.simpleWrap(sinit);
|
||||
subkind = SubKind.VAR_DECLARATION_SUBKIND;
|
||||
}
|
||||
Wrap wname;
|
||||
int nameStart = compileSource.lastIndexOf(name, nameMax);
|
||||
if (nameStart < 0) {
|
||||
throw new AssertionError("Name '" + name + "' not found");
|
||||
// the name has been transformed (e.g. unicode).
|
||||
// Use it directly
|
||||
wname = Wrap.identityWrap(name);
|
||||
} else {
|
||||
int nameEnd = nameStart + name.length();
|
||||
Range rname = new Range(nameStart, nameEnd);
|
||||
wname = new Wrap.RangeWrap(compileSource, rname);
|
||||
}
|
||||
int nameEnd = nameStart + name.length();
|
||||
Range rname = new Range(nameStart, nameEnd);
|
||||
Wrap guts = Wrap.varWrap(compileSource, typeWrap, sbBrackets.toString(), rname,
|
||||
Wrap guts = Wrap.varWrap(compileSource, typeWrap, sbBrackets.toString(), wname,
|
||||
winit, enhancedDesugaring, anonDeclareWrap);
|
||||
DiagList modDiag = modifierDiagnostics(vt.getModifiers(), dis, true);
|
||||
Snippet snip = new VarSnippet(state.keyMap.keyForVariable(name), userSource, guts,
|
||||
@ -417,6 +419,26 @@ class Eval {
|
||||
return snippets;
|
||||
}
|
||||
|
||||
private String userReadableName(Name nn, String compileSource) {
|
||||
String s = nn.toString();
|
||||
if (s.length() > 0 && Character.isJavaIdentifierStart(s.charAt(0)) && compileSource.contains(s)) {
|
||||
return s;
|
||||
}
|
||||
String l = nameInUnicode(nn, false);
|
||||
if (compileSource.contains(l)) {
|
||||
return l;
|
||||
}
|
||||
return nameInUnicode(nn, true);
|
||||
}
|
||||
|
||||
private String nameInUnicode(Name nn, boolean upper) {
|
||||
return nn.codePoints()
|
||||
.mapToObj(cp -> (cp > 0x7F)
|
||||
? String.format(upper ? "\\u%04X" : "\\u%04x", cp)
|
||||
: "" + (char) cp)
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
/**Convert anonymous classes in "init" to member classes, based
|
||||
* on the additional information from ExpressionInfo.anonymousClasses.
|
||||
*
|
||||
@ -680,6 +702,7 @@ class Eval {
|
||||
TreeDissector dis = TreeDissector.createByFirstClass(pt);
|
||||
|
||||
ClassTree klassTree = (ClassTree) unitTree;
|
||||
// String name = userReadableName(klassTree.getSimpleName(), compileSource);
|
||||
String name = klassTree.getSimpleName().toString();
|
||||
DiagList modDiag = modifierDiagnostics(klassTree.getModifiers(), dis, false);
|
||||
TypeDeclKey key = state.keyMap.keyForClass(name);
|
||||
@ -730,6 +753,7 @@ class Eval {
|
||||
final TreeDissector dis = TreeDissector.createByFirstClass(pt);
|
||||
|
||||
final MethodTree mt = (MethodTree) unitTree;
|
||||
//String name = userReadableName(mt.getName(), compileSource);
|
||||
final String name = mt.getName().toString();
|
||||
if (objectMethods.contains(name)) {
|
||||
// The name matches a method on Object, short of an overhaul, this
|
||||
|
@ -80,7 +80,7 @@ abstract class Wrap implements GeneralWrap {
|
||||
* @param source the snippet's masked source code
|
||||
* @param wtype variable's denotable type suitable for field declaration
|
||||
* @param brackets any [] that should be appended to the type
|
||||
* @param rname range in source that denotes the name of the
|
||||
* @param wname a wrap of the source that denotes the name of the variable
|
||||
* @param winit Initializer or null
|
||||
* @param enhanced if the real inferred type of the variable is potentially
|
||||
* non-denotable, this must be true
|
||||
@ -88,9 +88,8 @@ abstract class Wrap implements GeneralWrap {
|
||||
* an initialization method
|
||||
*/
|
||||
public static Wrap varWrap(String source, Wrap wtype, String brackets,
|
||||
Range rname, Wrap winit, boolean enhanced,
|
||||
Wrap wname, Wrap winit, boolean enhanced,
|
||||
Wrap anonDeclareWrap) {
|
||||
RangeWrap wname = new RangeWrap(source, rname);
|
||||
List<Object> components = new ArrayList<>();
|
||||
components.add(new VarDeclareWrap(wtype, brackets, wname));
|
||||
Wrap wmeth;
|
||||
|
55
test/langtools/jdk/jshell/UnicodeTest.java
Normal file
55
test/langtools/jdk/jshell/UnicodeTest.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 8248157
|
||||
* @summary test Unicode characters in Snippets
|
||||
* @build KullaTesting TestingInputStream
|
||||
* @run testng UnicodeTest
|
||||
*/
|
||||
|
||||
import jdk.jshell.Snippet;
|
||||
import jdk.jshell.DeclarationSnippet;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import jdk.jshell.Snippet.Status;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static jdk.jshell.Snippet.Status.VALID;
|
||||
import static jdk.jshell.Snippet.SubKind.*;
|
||||
|
||||
@Test
|
||||
public class UnicodeTest extends KullaTesting {
|
||||
|
||||
public void testVarDeclarationKey() {
|
||||
assertVarKeyMatch("int \\u00aa;", true, "\u00aa", VAR_DECLARATION_SUBKIND, "int", added(VALID));
|
||||
assertEval("\\u00aa", "0");
|
||||
}
|
||||
|
||||
public void testVarDeclarationWithInitializerKey() {
|
||||
assertVarKeyMatch("double \\u00ba\\u0044\\u0577 = 9.4;", true, "\u00ba\u0044\u0577",
|
||||
VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, "double", added(VALID));
|
||||
assertEval("\\u00ba\\u0044\\u0577", "9.4");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user