Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit f9327b3

Browse files
author
Robert Field
committedJul 23, 2020
8249197: JShell: variable declaration with unicode type name gets garbled result
8249199: JShell: Consistent representation of unicode Reviewed-by: jlahoda
1 parent 28f3f21 commit f9327b3

File tree

3 files changed

+93
-15
lines changed

3 files changed

+93
-15
lines changed
 

‎src/jdk.jshell/share/classes/jdk/jshell/Eval.java

+36-12
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@
2424
*/
2525
package jdk.jshell;
2626

27-
import java.util.ArrayList;
28-
import java.util.Collection;
29-
import java.util.Collections;
30-
import java.util.List;
31-
import java.util.Locale;
27+
import java.util.*;
3228
import java.util.regex.Matcher;
3329
import java.util.regex.Pattern;
3430
import java.util.stream.Collectors;
3531
import javax.lang.model.element.Modifier;
32+
import javax.lang.model.element.Name;
33+
3634
import com.sun.source.tree.ArrayTypeTree;
3735
import com.sun.source.tree.AssignmentTree;
3836
import com.sun.source.tree.ClassTree;
@@ -49,9 +47,7 @@
4947
import java.io.IOException;
5048
import java.io.StringWriter;
5149
import java.io.Writer;
52-
import java.util.Arrays;
53-
import java.util.LinkedHashSet;
54-
import java.util.Set;
50+
5551
import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo;
5652
import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo.AnonymousDescription;
5753
import jdk.jshell.ExpressionToTypeInfo.ExpressionInfo.AnonymousDescription.VariableDesc;
@@ -304,6 +300,7 @@ private List<Snippet> processVariables(String userSource, List<? extends Tree> u
304300
for (Tree unitTree : units) {
305301
VariableTree vt = (VariableTree) unitTree;
306302
String name = vt.getName().toString();
303+
// String name = userReadableName(vt.getName(), compileSource);
307304
String typeName;
308305
String fullTypeName;
309306
String displayType;
@@ -400,13 +397,18 @@ private List<Snippet> processVariables(String userSource, List<? extends Tree> u
400397
winit = Wrap.simpleWrap(sinit);
401398
subkind = SubKind.VAR_DECLARATION_SUBKIND;
402399
}
400+
Wrap wname;
403401
int nameStart = compileSource.lastIndexOf(name, nameMax);
404402
if (nameStart < 0) {
405-
throw new AssertionError("Name '" + name + "' not found");
403+
// the name has been transformed (e.g. unicode).
404+
// Use it directly
405+
wname = Wrap.identityWrap(name);
406+
} else {
407+
int nameEnd = nameStart + name.length();
408+
Range rname = new Range(nameStart, nameEnd);
409+
wname = new Wrap.RangeWrap(compileSource, rname);
406410
}
407-
int nameEnd = nameStart + name.length();
408-
Range rname = new Range(nameStart, nameEnd);
409-
Wrap guts = Wrap.varWrap(compileSource, typeWrap, sbBrackets.toString(), rname,
411+
Wrap guts = Wrap.varWrap(compileSource, typeWrap, sbBrackets.toString(), wname,
410412
winit, enhancedDesugaring, anonDeclareWrap);
411413
DiagList modDiag = modifierDiagnostics(vt.getModifiers(), dis, true);
412414
Snippet snip = new VarSnippet(state.keyMap.keyForVariable(name), userSource, guts,
@@ -417,6 +419,26 @@ private List<Snippet> processVariables(String userSource, List<? extends Tree> u
417419
return snippets;
418420
}
419421

422+
private String userReadableName(Name nn, String compileSource) {
423+
String s = nn.toString();
424+
if (s.length() > 0 && Character.isJavaIdentifierStart(s.charAt(0)) && compileSource.contains(s)) {
425+
return s;
426+
}
427+
String l = nameInUnicode(nn, false);
428+
if (compileSource.contains(l)) {
429+
return l;
430+
}
431+
return nameInUnicode(nn, true);
432+
}
433+
434+
private String nameInUnicode(Name nn, boolean upper) {
435+
return nn.codePoints()
436+
.mapToObj(cp -> (cp > 0x7F)
437+
? String.format(upper ? "\\u%04X" : "\\u%04x", cp)
438+
: "" + (char) cp)
439+
.collect(Collectors.joining());
440+
}
441+
420442
/**Convert anonymous classes in "init" to member classes, based
421443
* on the additional information from ExpressionInfo.anonymousClasses.
422444
*
@@ -680,6 +702,7 @@ private List<Snippet> processClass(String userSource, Tree unitTree, String comp
680702
TreeDissector dis = TreeDissector.createByFirstClass(pt);
681703

682704
ClassTree klassTree = (ClassTree) unitTree;
705+
// String name = userReadableName(klassTree.getSimpleName(), compileSource);
683706
String name = klassTree.getSimpleName().toString();
684707
DiagList modDiag = modifierDiagnostics(klassTree.getModifiers(), dis, false);
685708
TypeDeclKey key = state.keyMap.keyForClass(name);
@@ -730,6 +753,7 @@ private List<Snippet> processMethod(String userSource, Tree unitTree, String com
730753
final TreeDissector dis = TreeDissector.createByFirstClass(pt);
731754

732755
final MethodTree mt = (MethodTree) unitTree;
756+
//String name = userReadableName(mt.getName(), compileSource);
733757
final String name = mt.getName().toString();
734758
if (objectMethods.contains(name)) {
735759
// The name matches a method on Object, short of an overhaul, this

‎src/jdk.jshell/share/classes/jdk/jshell/Wrap.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,16 @@ private static String nlindent(int n) {
8080
* @param source the snippet's masked source code
8181
* @param wtype variable's denotable type suitable for field declaration
8282
* @param brackets any [] that should be appended to the type
83-
* @param rname range in source that denotes the name of the
83+
* @param wname a wrap of the source that denotes the name of the variable
8484
* @param winit Initializer or null
8585
* @param enhanced if the real inferred type of the variable is potentially
8686
* non-denotable, this must be true
8787
* @return a Wrap that declares the given variable, potentially with
8888
* an initialization method
8989
*/
9090
public static Wrap varWrap(String source, Wrap wtype, String brackets,
91-
Range rname, Wrap winit, boolean enhanced,
91+
Wrap wname, Wrap winit, boolean enhanced,
9292
Wrap anonDeclareWrap) {
93-
RangeWrap wname = new RangeWrap(source, rname);
9493
List<Object> components = new ArrayList<>();
9594
components.add(new VarDeclareWrap(wtype, brackets, wname));
9695
Wrap wmeth;
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8248157
27+
* @summary test Unicode characters in Snippets
28+
* @build KullaTesting TestingInputStream
29+
* @run testng UnicodeTest
30+
*/
31+
32+
import jdk.jshell.Snippet;
33+
import jdk.jshell.DeclarationSnippet;
34+
import org.testng.annotations.Test;
35+
36+
import jdk.jshell.Snippet.Status;
37+
import static org.testng.Assert.assertFalse;
38+
import static org.testng.Assert.assertTrue;
39+
import static jdk.jshell.Snippet.Status.VALID;
40+
import static jdk.jshell.Snippet.SubKind.*;
41+
42+
@Test
43+
public class UnicodeTest extends KullaTesting {
44+
45+
public void testVarDeclarationKey() {
46+
assertVarKeyMatch("int \\u00aa;", true, "\u00aa", VAR_DECLARATION_SUBKIND, "int", added(VALID));
47+
assertEval("\\u00aa", "0");
48+
}
49+
50+
public void testVarDeclarationWithInitializerKey() {
51+
assertVarKeyMatch("double \\u00ba\\u0044\\u0577 = 9.4;", true, "\u00ba\u0044\u0577",
52+
VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, "double", added(VALID));
53+
assertEval("\\u00ba\\u0044\\u0577", "9.4");
54+
}
55+
}

0 commit comments

Comments
 (0)
This repository has been archived.