Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
10c19e9a
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
10c19e9a
编写于
4月 04, 2016
作者:
R
rfield
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8147515: JShell: Internationalize
Reviewed-by: jlahoda
上级
6bfd5683
变更
13
展开全部
隐藏空白更改
内联
并排
Showing
13 changed file
with
998 addition
and
516 deletion
+998
-516
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
...re/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
+7
-7
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java
...hell/share/classes/jdk/internal/jshell/tool/Feedback.java
+25
-94
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
...ll/share/classes/jdk/internal/jshell/tool/JShellTool.java
+255
-352
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties
...lasses/jdk/internal/jshell/tool/resources/l10n.properties
+409
-14
langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java
langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java
+8
-6
langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
...tools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
+33
-8
langtools/src/jdk.jshell/share/classes/jdk/jshell/resources/l10n.properties
...jshell/share/classes/jdk/jshell/resources/l10n.properties
+34
-0
langtools/test/jdk/jshell/ReplToolTesting.java
langtools/test/jdk/jshell/ReplToolTesting.java
+9
-7
langtools/test/jdk/jshell/StartOptionTest.java
langtools/test/jdk/jshell/StartOptionTest.java
+5
-3
langtools/test/jdk/jshell/ToolBasicTest.java
langtools/test/jdk/jshell/ToolBasicTest.java
+5
-4
langtools/test/jdk/jshell/ToolFormatTest.java
langtools/test/jdk/jshell/ToolFormatTest.java
+5
-20
langtools/test/jdk/jshell/ToolLocaleMessageTest.java
langtools/test/jdk/jshell/ToolLocaleMessageTest.java
+202
-0
langtools/test/jdk/jshell/ToolReloadTest.java
langtools/test/jdk/jshell/ToolReloadTest.java
+1
-1
未找到文件。
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
浏览文件 @
10c19e9a
...
...
@@ -132,7 +132,7 @@ class ConsoleIOContext extends IOContext {
}
catch
(
IOException
ex
)
{
throw
new
IllegalStateException
(
ex
);
}
result
.
add
(
"<press tab to see more>"
);
result
.
add
(
repl
.
messageFormat
(
"jshell.console.see.more"
)
);
return
cursor
;
//anchor should not be used.
}
...
...
@@ -337,7 +337,7 @@ class ConsoleIOContext extends IOContext {
fixes
.
add
(
0
,
new
Fix
()
{
@Override
public
String
displayName
()
{
return
"Do nothing"
;
return
repl
.
messageFormat
(
"jshell.console.do.nothing"
)
;
}
@Override
...
...
@@ -353,7 +353,7 @@ class ConsoleIOContext extends IOContext {
char2Fix
.
put
((
char
)
(
'0'
+
i
),
fix
);
in
.
println
(
""
+
i
+
": "
+
fixes
.
get
(
i
).
displayName
());
}
in
.
print
(
"Choice: "
);
in
.
print
(
repl
.
messageFormat
(
"jshell.console.choice"
)
);
in
.
flush
();
int
read
;
...
...
@@ -438,7 +438,7 @@ class ConsoleIOContext extends IOContext {
return
new
FixResult
(
Collections
.
singletonList
(
new
Fix
()
{
@Override
public
String
displayName
()
{
return
"Create variable"
;
return
repl
.
messageFormat
(
"jshell.console.create.variable"
)
;
}
@Override
public
void
perform
(
ConsoleReader
in
)
throws
IOException
{
...
...
@@ -472,14 +472,14 @@ class ConsoleIOContext extends IOContext {
}
if
(
res
.
isResolvable
())
{
return
new
FixResult
(
Collections
.
emptyList
(),
"\nThe identifier is resolvable in this context."
);
repl
.
messageFormat
(
"jshell.console.resolvable"
)
);
}
else
{
String
error
=
""
;
if
(
fixes
.
isEmpty
())
{
error
=
"\nNo candidate fully qualified names found to import."
;
error
=
repl
.
messageFormat
(
"jshell.console.no.candidate"
)
;
}
if
(!
res
.
isUpToDate
())
{
error
+=
"\nResults may be incomplete; try again later for complete results."
;
error
+=
repl
.
messageFormat
(
"jshell.console.incomplete"
)
;
}
return
new
FixResult
(
fixes
,
error
);
}
...
...
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java
浏览文件 @
10c19e9a
...
...
@@ -33,10 +33,8 @@ import java.util.HashMap;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.function.Function
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
java.util.stream.Stream
;
import
static
java
.
util
.
stream
.
Collectors
.
joining
;
/**
...
...
@@ -113,22 +111,6 @@ class Feedback {
return
new
Setter
(
tool
,
at
).
setPrompt
();
}
public
void
printFeedbackHelp
(
JShellTool
tool
)
{
new
Setter
(
tool
,
null
).
printFeedbackHelp
();
}
public
void
printFormatHelp
(
JShellTool
tool
)
{
new
Setter
(
tool
,
null
).
printFormatHelp
();
}
public
void
printNewModeHelp
(
JShellTool
tool
)
{
new
Setter
(
tool
,
null
).
printNewModeHelp
();
}
public
void
printPromptHelp
(
JShellTool
tool
)
{
new
Setter
(
tool
,
null
).
printPromptHelp
();
}
{
for
(
FormatCase
e
:
EnumSet
.
allOf
(
FormatCase
.
class
))
selectorMap
.
put
(
e
.
name
().
toLowerCase
(
Locale
.
US
),
e
);
...
...
@@ -555,38 +537,18 @@ class Feedback {
this
.
at
=
at
;
}
void
hard
(
String
format
,
Object
...
args
)
{
tool
.
hard
(
format
,
args
);
}
void
hardrb
(
String
key
)
{
tool
.
hardrb
(
key
);
}
<
E
extends
Enum
<
E
>>
void
hardEnums
(
EnumSet
<
E
>
es
,
Function
<
E
,
String
>
e2s
)
{
hardPairs
(
es
.
stream
(),
ev
->
ev
.
name
().
toLowerCase
(
Locale
.
US
),
e2s
);
}
<
T
>
void
hardPairs
(
Stream
<
T
>
stream
,
Function
<
T
,
String
>
a
,
Function
<
T
,
String
>
b
)
{
tool
.
hardPairs
(
stream
,
a
,
b
);
}
void
fluff
(
String
format
,
Object
...
args
)
{
tool
.
fluff
(
format
,
args
);
}
void
error
(
String
format
,
Object
...
args
)
{
tool
.
error
(
format
,
args
);
void
fluffmsg
(
String
format
,
Object
...
args
)
{
tool
.
fluffmsg
(
format
,
args
);
}
void
errorat
(
String
format
,
Object
...
args
)
{
Object
[]
a2
=
Arrays
.
copyOf
(
args
,
args
.
length
+
1
);
a2
[
args
.
length
]
=
at
.
whole
();
tool
.
error
(
format
+
" -- /set %s"
,
a2
);
}
void
fluffRaw
(
String
format
,
Object
...
args
)
{
tool
.
fluffRaw
(
format
,
args
);
void
errorat
(
String
messageKey
,
Object
...
args
)
{
Object
[]
a2
=
Arrays
.
copyOf
(
args
,
args
.
length
+
2
);
a2
[
args
.
length
]
=
"/set "
+
at
.
whole
();
tool
.
errormsg
(
messageKey
,
a2
);
}
// For /set prompt <mode> "<prompt>" "<continuation-prompt>"
...
...
@@ -597,7 +559,7 @@ class Feedback {
if
(
valid
)
{
m
.
setPrompts
(
prompt
,
continuationPrompt
);
}
else
{
fluff
(
"See '/help /set prompt' for help
"
);
fluff
msg
(
"jshell.msg.see"
,
"/help /set prompt
"
);
}
return
valid
;
}
...
...
@@ -606,17 +568,17 @@ class Feedback {
boolean
setNewMode
()
{
String
umode
=
at
.
next
();
if
(
umode
==
null
)
{
errorat
(
"
Expected new feedback
mode"
);
errorat
(
"
jshell.err.feedback.expected.new.feedback.
mode"
);
valid
=
false
;
}
if
(
modeMap
.
containsKey
(
umode
))
{
errorat
(
"
Expected a new feedback mode name. %s is a known feedback mod
e"
,
umode
);
errorat
(
"
jshell.err.feedback.expected.mode.nam
e"
,
umode
);
valid
=
false
;
}
String
[]
fluffOpt
=
at
.
next
(
"command"
,
"quiet"
);
boolean
fluff
=
fluffOpt
==
null
||
fluffOpt
.
length
!=
1
||
"command"
.
equals
(
fluffOpt
[
0
]);
if
(
fluffOpt
!=
null
&&
fluffOpt
.
length
!=
1
)
{
errorat
(
"
Specify either 'command' or 'quiet'
"
);
errorat
(
"
jshell.err.feedback.command.quiet
"
);
valid
=
false
;
}
Mode
om
=
null
;
...
...
@@ -629,9 +591,9 @@ class Feedback {
?
new
Mode
(
umode
,
fluff
,
om
)
:
new
Mode
(
umode
,
fluff
);
modeMap
.
put
(
umode
,
nm
);
fluff
(
"Created new feedback mode: %s
"
,
nm
.
name
);
fluff
msg
(
"jshell.msg.feedback.new.mode
"
,
nm
.
name
);
}
else
{
fluff
(
"See '/help /set newmode' for help
"
);
fluff
msg
(
"jshell.msg.see"
,
"/help /set newmode
"
);
}
return
valid
;
}
...
...
@@ -641,9 +603,9 @@ class Feedback {
Mode
m
=
nextMode
();
if
(
valid
&&
m
!=
null
)
{
mode
=
m
;
fluff
(
"Feedback mode: %s
"
,
mode
.
name
);
fluff
msg
(
"jshell.msg.feedback.mode
"
,
mode
.
name
);
}
else
{
fluff
(
"See '/help /set feedback' for help
"
);
fluff
msg
(
"jshell.msg.see"
,
"/help /set feedback
"
);
}
return
valid
;
}
...
...
@@ -653,7 +615,7 @@ class Feedback {
Mode
m
=
nextMode
();
String
field
=
at
.
next
();
if
(
field
==
null
||
at
.
isQuoted
())
{
errorat
(
"
Expected field name missing
"
);
errorat
(
"
jshell.err.feedback.expected.field
"
);
valid
=
false
;
}
String
format
=
valid
?
nextFormat
()
:
null
;
...
...
@@ -675,7 +637,7 @@ class Feedback {
format
));
}
}
else
{
fluff
(
"See '/help /set format' for help
"
);
fluff
msg
(
"jshell.msg.see"
,
"/help /set format
"
);
}
return
valid
;
}
...
...
@@ -687,7 +649,7 @@ class Feedback {
Mode
toMode
(
String
umode
)
{
if
(
umode
==
null
)
{
errorat
(
"
Expected a feedback
mode"
);
errorat
(
"
jshell.err.feedback.expected.
mode"
);
valid
=
false
;
return
null
;
}
...
...
@@ -705,11 +667,11 @@ class Feedback {
}
else
{
valid
=
false
;
if
(
matches
.
length
==
0
)
{
errorat
(
"
Does not match any current feedback mode: %s
"
,
umode
);
errorat
(
"
jshell.err.feedback.does.not.match.mode
"
,
umode
);
}
else
{
errorat
(
"
Matches more then one current feedback mode: %s
"
,
umode
);
errorat
(
"
jshell.err.feedback.ambiguous.mode
"
,
umode
);
}
fluff
(
"The feedback mode should be one of the following:
"
);
fluff
msg
(
"jshell.msg.feedback.mode.following
"
);
modeMap
.
keySet
().
stream
()
.
forEach
(
mk
->
fluff
(
" %s"
,
mk
));
return
null
;
...
...
@@ -720,12 +682,12 @@ class Feedback {
final
String
nextFormat
()
{
String
format
=
at
.
next
();
if
(
format
==
null
)
{
errorat
(
"
Expected format missing
"
);
errorat
(
"
jshell.err.feedback.expected.format
"
);
valid
=
false
;
return
null
;
}
if
(!
at
.
isQuoted
())
{
errorat
(
"
Format '%s' must be
quoted"
,
format
);
errorat
(
"
jshell.err.feedback.must.be.
quoted"
,
format
);
valid
=
false
;
return
null
;
}
...
...
@@ -748,19 +710,19 @@ class Feedback {
if
(!
as
.
isEmpty
())
{
Selector
<?>
sel
=
selectorMap
.
get
(
as
);
if
(
sel
==
null
)
{
errorat
(
"
Not a valid selector %s in %s
"
,
as
,
s
);
errorat
(
"
jshell.err.feedback.not.a.valid.selector
"
,
as
,
s
);
valid
=
false
;
return
;
}
SelectorCollector
<?>
collector
=
sel
.
collector
(
this
);
if
(
lastCollector
==
null
)
{
if
(!
collector
.
isEmpty
())
{
errorat
(
"
Selector kind in multiple sections of selector list %s in %
s"
,
as
,
s
);
errorat
(
"
jshell.err.feedback.multiple.section
s"
,
as
,
s
);
valid
=
false
;
return
;
}
}
else
if
(
collector
!=
lastCollector
)
{
errorat
(
"
Different selector kinds in same sections of selector list %s in %
s"
,
as
,
s
);
errorat
(
"
jshell.err.feedback.different.selector.kind
s"
,
as
,
s
);
valid
=
false
;
return
;
}
...
...
@@ -771,36 +733,5 @@ class Feedback {
}
}
}
final
void
printFormatHelp
()
{
hardrb
(
"help.set.format"
);
hardrb
(
"help.set.format.case"
);
hardEnums
(
EnumSet
.
allOf
(
FormatCase
.
class
),
ev
->
ev
.
doc
);
hardrb
(
"help.set.format.action"
);
hardEnums
(
EnumSet
.
allOf
(
FormatAction
.
class
),
ev
->
ev
.
doc
);
hardrb
(
"help.set.format.when"
);
hardEnums
(
EnumSet
.
allOf
(
FormatWhen
.
class
),
ev
->
ev
.
doc
);
hardrb
(
"help.set.format.resolve"
);
hardEnums
(
EnumSet
.
allOf
(
FormatResolve
.
class
),
ev
->
ev
.
doc
);
hardrb
(
"help.set.format.unresolved"
);
hardEnums
(
EnumSet
.
allOf
(
FormatUnresolved
.
class
),
ev
->
ev
.
doc
);
hardrb
(
"help.set.format.errors"
);
hardEnums
(
EnumSet
.
allOf
(
FormatErrors
.
class
),
ev
->
ev
.
doc
);
hardrb
(
"help.set.format.end"
);
}
final
void
printFeedbackHelp
()
{
hardrb
(
"help.set.feedback"
);
modeMap
.
keySet
().
stream
()
.
forEach
(
m
->
hard
(
" %s"
,
m
));
}
final
void
printNewModeHelp
()
{
hardrb
(
"help.set.newmode"
);
}
final
void
printPromptHelp
()
{
hardrb
(
"help.set.prompt"
);
}
}
}
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
浏览文件 @
10c19e9a
此差异已折叠。
点击以展开。
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties
浏览文件 @
10c19e9a
此差异已折叠。
点击以展开。
langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java
浏览文件 @
10c19e9a
...
...
@@ -651,17 +651,19 @@ class Eval {
ModifierDiagnostic
(
List
<
Modifier
>
list
,
boolean
fatal
)
{
this
.
fatal
=
fatal
;
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
((
list
.
size
()
>
1
)
?
"Modifiers "
:
"Modifier "
);
for
(
Modifier
mod
:
list
)
{
sb
.
append
(
"'"
);
sb
.
append
(
mod
.
toString
());
sb
.
append
(
"' "
);
}
sb
.
append
(
"not permitted in top-level declarations"
);
if
(!
fatal
)
{
sb
.
append
(
", ignored"
);
}
this
.
message
=
sb
.
toString
();
String
key
=
(
list
.
size
()
>
1
)
?
fatal
?
"jshell.diag.modifier.plural.fatal"
:
"jshell.diag.modifier.plural.ignore"
:
fatal
?
"jshell.diag.modifier.single.fatal"
:
"jshell.diag.modifier.single.ignore"
;
this
.
message
=
state
.
messageFormat
(
key
,
sb
.
toString
());
}
@Override
...
...
langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
浏览文件 @
10c19e9a
...
...
@@ -29,12 +29,14 @@ import java.io.ByteArrayInputStream;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.PrintStream
;
import
java.
util.ArrayLis
t
;
import
java.
text.MessageForma
t
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.MissingResourceException
;
import
java.util.Objects
;
import
java.util.ResourceBundle
;
import
java.util.function.BiFunction
;
import
java.util.function.Consumer
;
...
...
@@ -42,7 +44,6 @@ import java.util.function.Supplier;
import
jdk.internal.jshell.debug.InternalDebugControl
;
import
static
java
.
util
.
stream
.
Collectors
.
collectingAndThen
;
import
static
java
.
util
.
stream
.
Collectors
.
toList
;
import
static
jdk
.
internal
.
jshell
.
debug
.
InternalDebugControl
.
DBG_EVNT
;
import
static
jdk
.
jshell
.
Util
.
expunge
;
import
jdk.jshell.Snippet.Status
;
...
...
@@ -91,10 +92,11 @@ public class JShell implements AutoCloseable {
private
final
Map
<
Subscription
,
Consumer
<
SnippetEvent
>>
keyStatusListeners
=
new
HashMap
<>();
private
boolean
closed
=
false
;
private
ExecutionControl
executionControl
=
null
;
private
SourceCodeAnalysisImpl
sourceCodeAnalysis
=
null
;
private
static
final
String
L10N_RB_NAME
=
"jdk.jshell.resources.l10n"
;
private
static
ResourceBundle
outputRB
=
null
;
JShell
(
Builder
b
)
{
this
.
in
=
b
.
in
;
...
...
@@ -558,8 +560,8 @@ public class JShell implements AutoCloseable {
checkIfAlive
();
checkValidSnippet
(
snippet
);
if
(
snippet
.
status
()
!=
Status
.
VALID
)
{
throw
new
IllegalArgumentException
(
"Snippet parameter of varValue() '"
+
snippet
+
"' must be VALID, it is: "
+
snippet
.
status
(
));
throw
new
IllegalArgumentException
(
messageFormat
(
"jshell.exc.var.not.valid"
,
snippet
,
snippet
.
status
()
));
}
String
value
=
executionControl
().
commandVarValue
(
maps
.
classFullName
(
snippet
),
snippet
.
name
());
return
expunge
(
value
);
...
...
@@ -680,7 +682,7 @@ public class JShell implements AutoCloseable {
*/
private
void
checkIfAlive
()
throws
IllegalStateException
{
if
(
closed
)
{
throw
new
IllegalStateException
(
"JShell ("
+
this
+
") has been closed."
);
throw
new
IllegalStateException
(
messageFormat
(
"jshell.exc.closed"
,
this
)
);
}
}
...
...
@@ -693,13 +695,36 @@ public class JShell implements AutoCloseable {
*/
private
Snippet
checkValidSnippet
(
Snippet
sn
)
{
if
(
sn
==
null
)
{
throw
new
NullPointerException
(
"Snippet must not be null"
);
throw
new
NullPointerException
(
messageFormat
(
"jshell.exc.null"
)
);
}
else
{
if
(
sn
.
key
().
state
()
!=
this
)
{
throw
new
IllegalArgumentException
(
"Snippet not from this JShell"
);
throw
new
IllegalArgumentException
(
messageFormat
(
"jshell.exc.alien"
)
);
}
return
sn
;
}
}
/**
* Format using resource bundle look-up using MessageFormat
*
* @param key the resource key
* @param args
*/
String
messageFormat
(
String
key
,
Object
...
args
)
{
if
(
outputRB
==
null
)
{
try
{
outputRB
=
ResourceBundle
.
getBundle
(
L10N_RB_NAME
);
}
catch
(
MissingResourceException
mre
)
{
throw
new
InternalError
(
"Cannot find ResourceBundle: "
+
L10N_RB_NAME
);
}
}
String
s
;
try
{
s
=
outputRB
.
getString
(
key
);
}
catch
(
MissingResourceException
mre
)
{
throw
new
InternalError
(
"Missing resource: "
+
key
+
" in "
+
L10N_RB_NAME
);
}
return
MessageFormat
.
format
(
s
,
args
);
}
}
langtools/src/jdk.jshell/share/classes/jdk/jshell/resources/l10n.properties
0 → 100644
浏览文件 @
10c19e9a
#
# 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.
#
jshell.diag.modifier.plural.fatal
=
Modifiers {0} not permitted in top-level declarations
jshell.diag.modifier.plural.ignore
=
Modifiers {0} not permitted in top-level declarations, ignored
jshell.diag.modifier.single.fatal
=
Modifier {0} not permitted in top-level declarations
jshell.diag.modifier.single.ignore
=
Modifier {0} not permitted in top-level declarations, ignored
jshell.exc.null
=
Snippet must not be null
jshell.exc.alien
=
Snippet not from this JShell
jshell.exc.closed
=
JShell ({0}) has been closed.
jshell.exc.var.not.valid
=
Snippet parameter of varValue() {0} must be VALID, it is: {1}
langtools/test/jdk/jshell/ReplToolTesting.java
浏览文件 @
10c19e9a
...
...
@@ -29,6 +29,7 @@ import java.util.Arrays;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.function.Consumer
;
import
java.util.function.Function
;
...
...
@@ -194,10 +195,10 @@ public class ReplToolTesting {
}
public
void
test
(
boolean
isDefaultStartUp
,
String
[]
args
,
ReplTest
...
tests
)
{
test
(
isDefaultStartUp
,
args
,
DEFAULT_STARTUP_MESSAGE
,
tests
);
test
(
Locale
.
ROOT
,
isDefaultStartUp
,
args
,
DEFAULT_STARTUP_MESSAGE
,
tests
);
}
public
void
test
(
boolean
isDefaultStartUp
,
String
[]
args
,
String
startUpMessage
,
ReplTest
...
tests
)
{
public
void
test
(
Locale
locale
,
boolean
isDefaultStartUp
,
String
[]
args
,
String
startUpMessage
,
ReplTest
...
tests
)
{
this
.
isDefaultStartUp
=
isDefaultStartUp
;
initSnippets
();
ReplTest
[]
wtests
=
new
ReplTest
[
tests
.
length
+
3
];
...
...
@@ -206,7 +207,7 @@ public class ReplToolTesting {
wtests
[
1
]
=
a
->
assertCommand
(
a
,
"/debug 0"
,
null
);
System
.
arraycopy
(
tests
,
0
,
wtests
,
2
,
tests
.
length
);
wtests
[
tests
.
length
+
2
]
=
a
->
assertCommand
(
a
,
"/exit"
,
null
);
testRaw
(
args
,
wtests
);
testRaw
(
locale
,
args
,
wtests
);
}
private
void
initSnippets
()
{
...
...
@@ -230,7 +231,7 @@ public class ReplToolTesting {
prefs
=
new
MemoryPreferences
();
}
public
void
testRaw
(
String
[]
args
,
ReplTest
...
tests
)
{
public
void
testRaw
(
Locale
locale
,
String
[]
args
,
ReplTest
...
tests
)
{
cmdin
=
new
WaitingTestingInputStream
();
cmdout
=
new
ByteArrayOutputStream
();
cmderr
=
new
ByteArrayOutputStream
();
...
...
@@ -246,7 +247,8 @@ public class ReplToolTesting {
userin
,
new
PrintStream
(
userout
),
new
PrintStream
(
usererr
),
prefs
);
prefs
,
locale
);
repl
.
testPrompt
=
true
;
try
{
repl
.
start
(
args
);
...
...
@@ -258,7 +260,7 @@ public class ReplToolTesting {
String
ceos
=
getCommandErrorOutput
();
String
uos
=
getUserOutput
();
String
ueos
=
getUserErrorOutput
();
assertTrue
((
cos
.
isEmpty
()
||
cos
.
startsWith
(
"| Goodbye"
)),
assertTrue
((
cos
.
isEmpty
()
||
cos
.
startsWith
(
"| Goodbye"
)
||
!
locale
.
equals
(
Locale
.
ROOT
)
),
"Expected a goodbye, but got: "
+
cos
);
assertTrue
(
ceos
.
isEmpty
(),
"Expected empty error output, got: "
+
ceos
);
assertTrue
(
uos
.
isEmpty
(),
"Expected empty output, got: "
+
uos
);
...
...
@@ -459,7 +461,7 @@ public class ReplToolTesting {
private
List
<
String
>
computeCompletions
(
String
code
,
boolean
isSmart
)
{
JShellTool
js
=
this
.
repl
!=
null
?
this
.
repl
:
new
JShellTool
(
null
,
null
,
null
,
null
,
null
,
null
,
null
,
prefs
);
:
new
JShellTool
(
null
,
null
,
null
,
null
,
null
,
null
,
null
,
prefs
,
Locale
.
ROOT
);
int
cursor
=
code
.
indexOf
(
'|'
);
code
=
code
.
replace
(
"|"
,
""
);
assertTrue
(
cursor
>
-
1
,
"'|' not found: "
+
code
);
...
...
langtools/test/jdk/jshell/StartOptionTest.java
浏览文件 @
10c19e9a
...
...
@@ -37,6 +37,7 @@ import java.io.ByteArrayOutputStream;
import
java.io.PrintStream
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Path
;
import
java.util.Locale
;
import
java.util.function.Consumer
;
import
jdk.internal.jshell.tool.JShellTool
;
...
...
@@ -55,7 +56,8 @@ public class StartOptionTest {
private
JShellTool
getShellTool
()
{
return
new
JShellTool
(
null
,
new
PrintStream
(
out
),
new
PrintStream
(
err
),
null
,
null
,
null
,
null
,
new
ReplToolTesting
.
MemoryPreferences
());
null
,
new
ReplToolTesting
.
MemoryPreferences
(),
Locale
.
ROOT
);
}
private
String
getOutput
()
{
...
...
@@ -116,10 +118,10 @@ public class StartOptionTest {
Compiler
compiler
=
new
Compiler
();
Path
p
=
compiler
.
getPath
(
"file.txt"
);
compiler
.
writeToFile
(
p
);
start
(
""
,
"
Argument to -startup missing
.\n"
,
"-startup"
);
start
(
""
,
"
'-startup' requires a filename argument
.\n"
,
"-startup"
);
start
(
""
,
"Conflicting -startup or -nostartup option.\n"
,
"-startup"
,
p
.
toString
(),
"-startup"
,
p
.
toString
());
start
(
""
,
"Conflicting -startup or -nostartup option.\n"
,
"-nostartup"
,
"-startup"
,
p
.
toString
());
start
(
""
,
"Conflicting -startup option.\n"
,
"-startup"
,
p
.
toString
(),
"-nostartup"
);
start
(
""
,
"Conflicting -startup o
r -nostartup o
ption.\n"
,
"-startup"
,
p
.
toString
(),
"-nostartup"
);
}
@Test
...
...
langtools/test/jdk/jshell/ToolBasicTest.java
浏览文件 @
10c19e9a
...
...
@@ -43,6 +43,7 @@ import java.nio.file.Paths;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Scanner
;
import
java.util.function.BiFunction
;
import
java.util.function.Consumer
;
...
...
@@ -463,7 +464,7 @@ public class ToolBasicTest extends ReplToolTesting {
(
a
)
->
assertCommandCheckOutput
(
a
,
"printf(\"\")"
,
assertStartsWith
(
"| Error:\n| cannot find symbol"
))
);
test
((
a
)
->
assertCommand
(
a
,
"printf(\"A\")"
,
""
,
""
,
null
,
"A"
,
""
));
test
(
false
,
new
String
[]{
"-startup"
,
"UNKNOWN"
},
"| File 'UNKNOWN' for start-up is not found."
);
test
(
Locale
.
ROOT
,
false
,
new
String
[]{
"-startup"
,
"UNKNOWN"
},
"| File 'UNKNOWN' for start-up is not found."
);
}
finally
{
removeStartup
();
}
...
...
@@ -478,9 +479,9 @@ public class ToolBasicTest extends ReplToolTesting {
(
a
)
->
assertCommand
(
a
,
"a"
,
"| Variable a of type double has value 10.0\n"
)
);
Path
unknown
=
compiler
.
getPath
(
"UNKNOWN.jar"
);
test
(
true
,
new
String
[]{
unknown
.
toString
()},
"| File
'
"
+
unknown
+
"
'
is not found: "
+
unresolvableMessage
(
unknown
)
+
"\n"
);
test
(
Locale
.
ROOT
,
true
,
new
String
[]{
unknown
.
toString
()},
"| File "
+
unknown
+
" is not found: "
+
unresolvableMessage
(
unknown
)
+
"\n"
);
}
public
void
testReset
()
{
...
...
langtools/test/jdk/jshell/ToolFormatTest.java
浏览文件 @
10c19e9a
...
...
@@ -62,7 +62,7 @@ public class ToolFormatTest extends ReplToolTesting {
(
a
)
->
assertCommand
(
a
,
"/set format test result '={value} ' expression"
,
""
),
(
a
)
->
assertCommand
(
a
,
"/set format test display '{pre}{action}{ftype}{fname}{result}{resolve}'"
,
""
),
(
a
)
->
assertCommand
(
a
,
"/set format test display '{pre}HI this is enum' enum"
,
""
),
(
a
)
->
assertCommand
(
a
,
"/set feedback test"
,
"$ Feedback mode: test"
),
(
a
)
->
assertCommand
OutputStartsWith
(
a
,
"/set feedback test"
,
"$ Feedback mode: test"
),
(
a
)
->
assertCommand
(
a
,
"class D {}"
,
"$ ADD :D OK"
),
(
a
)
->
assertCommand
(
a
,
"void m() {}"
,
"$ ADD []:m OK"
),
(
a
)
->
assertCommand
(
a
,
"interface EX extends EEX {}"
,
"$ ADD :EX NODEF"
),
...
...
@@ -184,18 +184,18 @@ public class ToolFormatTest extends ReplToolTesting {
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set newmode te2"
,
"| Created new feedback mode: te2"
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set newmode te2 command"
,
"| Expected a new feedback mode name.
te2
is a known feedback mode"
),
"| Expected a new feedback mode name.
'te2'
is a known feedback mode"
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set newmode te command normal"
,
"| Created new feedback mode: te"
),
(
a
)
->
assertCommand
(
a
,
"/set format te errorpre 'ERROR: '"
,
""
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set feedback te"
,
""
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set "
,
"ERROR: The
/set command requires
arguments"
),
"ERROR: The
'/set' command requires a sub-command and
arguments"
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set xyz"
,
"ERROR:
Not a valid argument to /set
"
),
"ERROR:
Invalid '/set' argument: xyz
"
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set f"
,
"ERROR: Ambiguous
argument to /set
"
),
"ERROR: Ambiguous
sub-command argument to '/set': f
"
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set feedback"
,
"ERROR: Expected a feedback mode"
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set feedback xyz"
,
...
...
@@ -266,19 +266,4 @@ public class ToolFormatTest extends ReplToolTesting {
});
}
}
public
void
testSetHelpError
()
{
try
{
test
(
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set newmode te command normal"
,
"| Created new feedback mode: te"
),
(
a
)
->
assertCommand
(
a
,
"/set format te errorpre 'ERROR: '"
,
""
),
(
a
)
->
assertCommandOutputStartsWith
(
a
,
"/set feedback te"
,
"| Feedback mode: te"
),
(
a
)
->
assertCommandOutputContains
(
a
,
"/help /set xyz"
,
"ERROR: Not a valid argument to /set: xyz"
),
(
a
)
->
assertCommandOutputContains
(
a
,
"/help /set f"
,
"ERROR: Ambiguous argument to /set: f"
)
);
}
finally
{
assertCommandCheckOutput
(
false
,
"/set feedback normal"
,
s
->
{
});
}
}
}
langtools/test/jdk/jshell/ToolLocaleMessageTest.java
0 → 100644
浏览文件 @
10c19e9a
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8147515
* @summary Tests for output customization
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
* jdk.jshell/jdk.internal.jshell.tool
* @build KullaTesting TestingInputStream toolbox.ToolBox Compiler
* @run testng ToolLocaleMessageTest
*/
import
java.util.Locale
;
import
org.testng.annotations.Test
;
import
static
org
.
testng
.
Assert
.
assertFalse
;
import
static
org
.
testng
.
Assert
.
assertTrue
;
@Test
public
class
ToolLocaleMessageTest
extends
ReplToolTesting
{
void
testLocale
(
ReplTest
...
tests
)
{
test
(
Locale
.
getDefault
(),
false
,
new
String
[]{
"-nostartup"
},
""
,
tests
);
}
void
assertCommandOK
(
boolean
after
,
String
cmd
,
String
...
contains
)
{
assertCommandCheckOutput
(
after
,
cmd
,
s
->
{
assertFalse
(
s
.
contains
(
"Exception"
),
"Output of '"
+
cmd
+
"' has Exception: "
+
s
);
assertFalse
(
s
.
contains
(
"ERROR:"
),
"Output of '"
+
cmd
+
"' has error: "
+
s
);
for
(
String
m
:
contains
)
{
assertTrue
(
s
.
contains
(
m
),
"Expected to find '"
+
m
+
"' in output of '"
+
cmd
+
"' -- output: "
+
s
);
}
});
}
void
assertCommandFail
(
boolean
after
,
String
cmd
,
String
...
contains
)
{
assertCommandCheckOutput
(
after
,
cmd
,
s
->
{
assertFalse
(
s
.
contains
(
"Exception"
),
"Output of '"
+
cmd
+
"' has Exception: "
+
s
);
assertTrue
(
s
.
contains
(
"ERROR:"
),
"Expected to find error in output of '"
+
cmd
+
"' has error: "
+
s
);
for
(
String
m
:
contains
)
{
assertTrue
(
s
.
contains
(
m
),
"Expected to find '"
+
m
+
"' in output of '"
+
cmd
+
"' -- output: "
+
s
);
}
});
}
public
void
testTerminate
()
{
testLocale
(
(
a
)
->
assertCommandOK
(
a
,
"System.exit(1)"
,
"/reload"
)
);
}
public
void
testSample
()
{
try
{
testLocale
(
(
a
)
->
assertCommandOK
(
a
,
"/set newmode test command normal"
,
"test"
),
(
a
)
->
assertCommandOK
(
a
,
"/set format test errorpre 'ERROR: '"
),
(
a
)
->
assertCommandOK
(
a
,
"/set feedback test"
,
"test"
),
(
a
)
->
assertCommandFail
(
a
,
"/turkey"
,
"/turkey"
),
(
a
)
->
assertCommandFail
(
a
,
"/s"
,
"/set"
),
(
a
)
->
assertCommandOK
(
a
,
"void m() { blah(); }"
,
"blah"
),
(
a
)
->
assertCommandOK
(
a
,
"void m() {}"
),
(
a
)
->
assertCommandOK
(
a
,
"class C {}"
),
(
a
)
->
assertCommandOK
(
a
,
"47"
),
(
a
)
->
assertCommandOK
(
a
,
"double d"
),
(
a
)
->
assertCommandOK
(
a
,
"/drop m"
,
"m"
),
(
a
)
->
assertCommandOK
(
a
,
"void dup() {}"
),
(
a
)
->
assertCommandOK
(
a
,
"int dup"
),
(
a
)
->
assertCommandOK
(
a
,
"/set feedback normal"
,
"normal"
)
);
}
finally
{
assertCommandOK
(
false
,
"/set feedback normal"
);
}
}
public
void
testCommand
()
{
try
{
testLocale
(
(
a
)
->
assertCommandOK
(
a
,
"/set newmode test command normal"
,
"test"
),
(
a
)
->
assertCommandOK
(
a
,
"/set format test errorpre 'ERROR: '"
),
(
a
)
->
assertCommandOK
(
a
,
"/set feedback test"
,
"test"
),
(
a
)
->
assertCommandFail
(
a
,
"/list zebra"
),
(
a
)
->
assertCommandFail
(
a
,
"/set editor"
,
"/set editor"
),
(
a
)
->
assertCommandFail
(
a
,
"/set snowball"
,
"/set"
,
"snowball"
),
(
a
)
->
assertCommandFail
(
a
,
"/set"
,
"/set"
,
"/help"
),
(
a
)
->
assertCommandFail
(
a
,
"/set f"
,
"feedback"
),
(
a
)
->
assertCommandFail
(
a
,
"/classpath"
,
"/classpath"
),
(
a
)
->
assertCommandFail
(
a
,
"/help rabbits"
,
"rabbits"
),
(
a
)
->
assertCommandFail
(
a
,
"/drop"
),
(
a
)
->
assertCommandFail
(
a
,
"/drop rats"
),
(
a
)
->
assertCommandOK
(
a
,
"void dup() {}"
),
(
a
)
->
assertCommandOK
(
a
,
"int dup"
),
(
a
)
->
assertCommandFail
(
a
,
"/drop dup"
),
(
a
)
->
assertCommandFail
(
a
,
"/edit zebra"
,
"zebra"
),
(
a
)
->
assertCommandFail
(
a
,
"/list zebra"
,
"zebra"
,
"/list"
),
(
a
)
->
assertCommandFail
(
a
,
"/open"
,
"/open"
),
(
a
)
->
assertCommandFail
(
a
,
"/open zebra"
,
"zebra"
,
"/open"
),
(
a
)
->
assertCommandFail
(
a
,
"/reload zebra"
,
"zebra"
,
"/reload"
),
(
a
)
->
assertCommandFail
(
a
,
"/save"
,
"/save"
),
(
a
)
->
assertCommandFail
(
a
,
"/-99"
),
(
a
)
->
assertCommandOK
(
a
,
"/set feedback normal"
,
"normal"
)
);
}
finally
{
assertCommandOK
(
false
,
"/set feedback normal"
);
}
}
public
void
testHelp
()
{
testLocale
(
(
a
)
->
assertCommandOK
(
a
,
"/help"
,
"/list"
,
"/save"
,
"/set"
,
"[restore]"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /list"
,
"start"
,
"all"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /edit"
,
"/set editor"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /drop"
,
"/drop"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /save"
,
"all"
,
"start"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /open"
,
"/open"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /reload"
,
"restore"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /help"
,
"intro"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /set"
,
"newmode"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /?"
,
"intro"
),
(
a
)
->
assertCommandOK
(
a
,
"/help intro"
,
"/help"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /set format"
,
"import"
,
"case"
,
"{value}"
,
"added"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /set feedback"
,
"newmode"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /set newmode"
,
"feedback"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /set prompt"
,
"/set prompt"
),
(
a
)
->
assertCommandOK
(
a
,
"/help /set editor"
,
"/edit"
)
);
}
public
void
testFeedbackError
()
{
try
{
testLocale
(
(
a
)
->
assertCommandOK
(
a
,
"/set newmode tee command foo"
,
"foo"
),
(
a
)
->
assertCommandOK
(
a
,
"/set newmode tee flurb"
,
"command"
,
"quiet"
),
(
a
)
->
assertCommandOK
(
a
,
"/set newmode te2"
,
"te2"
),
(
a
)
->
assertCommandOK
(
a
,
"/set newmode te2 command"
,
"te2"
),
(
a
)
->
assertCommandOK
(
a
,
"/set newmode te command normal"
,
"te"
),
(
a
)
->
assertCommandOK
(
a
,
"/set format te errorpre 'ERROR: '"
),
(
a
)
->
assertCommandOK
(
a
,
"/set feedback te"
),
(
a
)
->
assertCommandFail
(
a
,
"/set "
),
(
a
)
->
assertCommandFail
(
a
,
"/set xyz"
,
"xyz"
),
(
a
)
->
assertCommandFail
(
a
,
"/set f"
,
"/set"
,
"f"
),
(
a
)
->
assertCommandFail
(
a
,
"/set feedback"
),
(
a
)
->
assertCommandFail
(
a
,
"/set feedback xyz"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format xyz"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format t"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format te"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format te fld"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format te fld aaa"
,
"aaa"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format te fld 'aaa' frog"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format te fld 'aaa' import-frog"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format te fld 'aaa' import-import"
),
(
a
)
->
assertCommandFail
(
a
,
"/set format te fld 'aaa' import,added"
),
(
a
)
->
assertCommandFail
(
a
,
"/set newmode"
),
(
a
)
->
assertCommandFail
(
a
,
"/set newmode te"
),
(
a
)
->
assertCommandFail
(
a
,
"/set newmode x xyz"
),
(
a
)
->
assertCommandFail
(
a
,
"/set newmode x quiet y"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt te"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt te aaa xyz"
,
"aaa"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt te 'aaa' xyz"
,
"xyz"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt te"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt te aaa"
),
(
a
)
->
assertCommandFail
(
a
,
"/set prompt te 'aaa'"
),
(
a
)
->
assertCommandOK
(
a
,
"/set feedback normal"
)
);
}
finally
{
assertCommandOK
(
false
,
"/set feedback normal"
);
}
}
}
langtools/test/jdk/jshell/ToolReloadTest.java
浏览文件 @
10c19e9a
...
...
@@ -71,7 +71,7 @@ public class ToolReloadTest extends ReplToolTesting {
Path
classpath
=
compiler
.
getPath
(
outDir
);
test
(
(
a
)
->
assertCommand
(
a
,
"/classpath "
+
classpath
,
String
.
format
(
"| Path
%s
added to classpath\n"
,
classpath
)),
String
.
format
(
"| Path
'%s'
added to classpath\n"
,
classpath
)),
(
a
)
->
assertMethod
(
a
,
"String foo() { return (new pkg.A()).toString(); }"
,
"()String"
,
"foo"
),
(
a
)
->
assertVariable
(
a
,
"String"
,
"v"
,
"foo()"
,
"\"A\""
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录