Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_langtools
提交
9f575334
D
dragonwell8_langtools
项目概览
openanolis
/
dragonwell8_langtools
通知
0
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_langtools
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9f575334
编写于
1月 26, 2011
作者:
J
jjg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
7013272: Automatically generate info about how compiler resource keys are used
Reviewed-by: mcimadamore
上级
44d7c58e
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
1859 addition
and
65 deletion
+1859
-65
make/build.xml
make/build.xml
+2
-2
src/share/classes/com/sun/tools/javac/code/Printer.java
src/share/classes/com/sun/tools/javac/code/Printer.java
+2
-2
src/share/classes/com/sun/tools/javac/resources/compiler.properties
...classes/com/sun/tools/javac/resources/compiler.properties
+610
-54
test/tools/javac/diags/ArgTypeCompilerFactory.java
test/tools/javac/diags/ArgTypeCompilerFactory.java
+346
-0
test/tools/javac/diags/Example.java
test/tools/javac/diags/Example.java
+19
-4
test/tools/javac/diags/MessageFile.java
test/tools/javac/diags/MessageFile.java
+463
-0
test/tools/javac/diags/MessageInfo.java
test/tools/javac/diags/MessageInfo.java
+406
-0
test/tools/javac/diags/RunExamples.java
test/tools/javac/diags/RunExamples.java
+11
-3
未找到文件。
make/build.xml
浏览文件 @
9f575334
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2007, 20
09
, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2007, 20
11
, 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
...
...
@@ -331,7 +331,7 @@
executable=
"${dist.bin.dir}/javac"
srcdir=
"test/tools/javac/diags"
destdir=
"${build.dir}/diag-examples/classes"
includes=
"Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
includes=
"
ArgTypeCompilerFactory.java,
Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
sourcepath=
""
classpath=
"${dist.lib.dir}/javac.jar"
includeAntRuntime=
"no"
...
...
src/share/classes/com/sun/tools/javac/code/Printer.java
浏览文件 @
9f575334
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009,
2011,
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
...
...
@@ -106,7 +106,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
}
/**
* * Get a localized string represenation for all the symbols in the input list.
* * Get a localized string represen
t
ation for all the symbols in the input list.
*
* @param ts symbols to be displayed
* @param locale the locale in which the string is to be rendered
...
...
src/share/classes/com/sun/tools/javac/resources/compiler.properties
浏览文件 @
9f575334
此差异已折叠。
点击以展开。
test/tools/javac/diags/ArgTypeCompilerFactory.java
0 → 100644
浏览文件 @
9f575334
/*
* Copyright (c) 2010, 2011, 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.
*/
import
java.io.*
;
import
java.util.*
;
import
java.util.List
;
import
javax.tools.*
;
import
com.sun.tools.javac.api.*
;
import
com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart
;
import
com.sun.tools.javac.api.Formattable.LocalizedString
;
import
com.sun.tools.javac.code.Flags.Flag
;
import
com.sun.tools.javac.code.Kinds.KindName
;
import
com.sun.tools.javac.code.*
;
import
com.sun.tools.javac.file.*
;
import
com.sun.tools.javac.main.Main
;
import
com.sun.tools.javac.parser.Token
;
import
com.sun.tools.javac.util.*
;
import
com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration
;
import
javax.lang.model.SourceVersion
;
/**
* Compiler factory for instances of Example.Compiler that use custom
* DiagnosticFormatter and Messages objects to track the types of args
* when when localizing diagnostics.
* The compiler objects only support "output" mode, not "check" mode.
*/
class
ArgTypeCompilerFactory
implements
Example
.
Compiler
.
Factory
{
// Same code as Example.Compiler.DefaultFactory, but the names resolve differently
public
Example
.
Compiler
getCompiler
(
List
<
String
>
opts
,
boolean
verbose
)
{
String
first
;
String
[]
rest
;
if
(
opts
==
null
||
opts
.
isEmpty
())
{
first
=
null
;
rest
=
new
String
[
0
];
}
else
{
first
=
opts
.
get
(
0
);
rest
=
opts
.
subList
(
1
,
opts
.
size
()).
toArray
(
new
String
[
opts
.
size
()
-
1
]);
}
if
(
first
==
null
||
first
.
equals
(
"jsr199"
))
return
new
Jsr199Compiler
(
verbose
,
rest
);
else
if
(
first
.
equals
(
"simple"
))
return
new
SimpleCompiler
(
verbose
);
else
if
(
first
.
equals
(
"backdoor"
))
return
new
BackdoorCompiler
(
verbose
);
else
throw
new
IllegalArgumentException
(
first
);
}
/**
* Compile using the JSR 199 API. The diagnostics generated are
* scanned for resource keys. Not all diagnostic keys are generated
* via the JSR 199 API -- for example, rich diagnostics are not directly
* accessible, and some diagnostics generated by the file manager may
* not be generated (for example, the JSR 199 file manager does not see
* -Xlint:path).
*/
static
class
Jsr199Compiler
extends
Example
.
Compiler
{
List
<
String
>
fmOpts
;
Jsr199Compiler
(
boolean
verbose
,
String
...
args
)
{
super
(
verbose
);
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
String
arg
=
args
[
i
];
if
(
arg
.
equals
(
"-filemanager"
)
&&
(
i
+
1
<
args
.
length
))
{
fmOpts
=
Arrays
.
asList
(
args
[++
i
].
split
(
","
));
}
else
throw
new
IllegalArgumentException
(
arg
);
}
}
@Override
boolean
run
(
PrintWriter
out
,
Set
<
String
>
keys
,
boolean
raw
,
List
<
String
>
opts
,
List
<
File
>
files
)
{
assert
out
!=
null
&&
keys
==
null
;
if
(
verbose
)
System
.
err
.
println
(
"run_jsr199: "
+
opts
+
" "
+
files
);
JavacTool
tool
=
JavacTool
.
create
();
StandardJavaFileManager
fm
=
tool
.
getStandardFileManager
(
null
,
null
,
null
);
if
(
fmOpts
!=
null
)
fm
=
new
FileManager
(
fm
,
fmOpts
);
Iterable
<?
extends
JavaFileObject
>
fos
=
fm
.
getJavaFileObjectsFromFiles
(
files
);
JavacTaskImpl
t
=
(
JavacTaskImpl
)
tool
.
getTask
(
out
,
fm
,
null
,
opts
,
null
,
fos
);
Context
c
=
t
.
getContext
();
ArgTypeMessages
.
preRegister
(
c
);
Options
options
=
Options
.
instance
(
c
);
Log
.
instance
(
c
).
setDiagnosticFormatter
(
new
ArgTypeDiagnosticFormatter
(
options
));
Boolean
ok
=
t
.
call
();
return
ok
;
}
}
/**
* Run the test using the standard simple entry point.
*/
static
class
SimpleCompiler
extends
Example
.
Compiler
{
SimpleCompiler
(
boolean
verbose
)
{
super
(
verbose
);
}
@Override
boolean
run
(
PrintWriter
out
,
Set
<
String
>
keys
,
boolean
raw
,
List
<
String
>
opts
,
List
<
File
>
files
)
{
assert
out
!=
null
&&
keys
==
null
;
if
(
verbose
)
System
.
err
.
println
(
"run_simple: "
+
opts
+
" "
+
files
);
List
<
String
>
args
=
new
ArrayList
<
String
>();
args
.
addAll
(
opts
);
for
(
File
f:
files
)
args
.
add
(
f
.
getPath
());
Main
main
=
new
Main
(
"javac"
,
out
);
Context
c
=
new
Context
()
{
@Override
public
void
clear
()
{
((
JavacFileManager
)
get
(
JavaFileManager
.
class
)).
close
();
super
.
clear
();
}
};
JavacFileManager
.
preRegister
(
c
);
// can't create it until Log has been set up
ArgTypeDiagnosticFormatter
.
preRegister
(
c
);
ArgTypeMessages
.
preRegister
(
c
);
int
result
=
main
.
compile
(
args
.
toArray
(
new
String
[
args
.
size
()]),
c
);
return
(
result
==
0
);
}
}
static
class
BackdoorCompiler
extends
Example
.
Compiler
{
BackdoorCompiler
(
boolean
verbose
)
{
super
(
verbose
);
}
@Override
boolean
run
(
PrintWriter
out
,
Set
<
String
>
keys
,
boolean
raw
,
List
<
String
>
opts
,
List
<
File
>
files
)
{
assert
out
!=
null
&&
keys
==
null
;
if
(
verbose
)
System
.
err
.
println
(
"run_simple: "
+
opts
+
" "
+
files
);
List
<
String
>
args
=
new
ArrayList
<
String
>(
opts
);
for
(
File
f:
files
)
args
.
add
(
f
.
getPath
());
Context
c
=
new
Context
();
JavacFileManager
.
preRegister
(
c
);
// can't create it until Log has been set up
ArgTypeDiagnosticFormatter
.
preRegister
(
c
);
ArgTypeMessages
.
preRegister
(
c
);
com
.
sun
.
tools
.
javac
.
main
.
Main
m
=
new
com
.
sun
.
tools
.
javac
.
main
.
Main
(
"javac"
,
out
);
int
rc
=
m
.
compile
(
args
.
toArray
(
new
String
[
args
.
size
()]),
c
);
return
(
rc
==
0
);
}
}
// <editor-fold defaultstate="collapsed" desc="Custom Javac components">
/**
* Diagnostic formatter which reports formats a diag as a series of lines
* containing a key, and a possibly empty set of descriptive strings for the
* arg types.
*/
static
class
ArgTypeDiagnosticFormatter
extends
AbstractDiagnosticFormatter
{
static
void
preRegister
(
final
Context
context
)
{
context
.
put
(
Log
.
logKey
,
new
Context
.
Factory
<
Log
>()
{
public
Log
make
()
{
Log
log
=
new
Log
(
context
)
{
};
Options
options
=
Options
.
instance
(
context
);
log
.
setDiagnosticFormatter
(
new
ArgTypeDiagnosticFormatter
(
options
));
return
log
;
}
});
}
ArgTypeDiagnosticFormatter
(
Options
options
)
{
super
(
null
,
new
SimpleConfiguration
(
options
,
EnumSet
.
of
(
DiagnosticPart
.
SUMMARY
,
DiagnosticPart
.
DETAILS
,
DiagnosticPart
.
SUBDIAGNOSTICS
)));
}
@Override
protected
String
formatDiagnostic
(
JCDiagnostic
d
,
Locale
locale
)
{
return
formatMessage
(
d
,
locale
);
}
@Override
public
String
formatMessage
(
JCDiagnostic
d
,
Locale
l
)
{
StringBuilder
buf
=
new
StringBuilder
();
formatMessage
(
d
,
buf
);
return
buf
.
toString
();
}
private
void
formatMessage
(
JCDiagnostic
d
,
StringBuilder
buf
)
{
String
key
=
d
.
getCode
();
Object
[]
args
=
d
.
getArgs
();
// report the primary arg types, without recursing into diag fragments
buf
.
append
(
getKeyArgsString
(
key
,
args
));
// report details for any diagnostic fragments
for
(
Object
arg:
args
)
{
if
(
arg
instanceof
JCDiagnostic
)
{
buf
.
append
(
"\n"
);
formatMessage
((
JCDiagnostic
)
arg
,
buf
);
}
}
// report details for any subdiagnostics
for
(
String
s:
formatSubdiagnostics
(
d
,
null
))
{
buf
.
append
(
"\n"
);
buf
.
append
(
s
);
}
}
@Override
public
boolean
isRaw
()
{
return
true
;
}
}
/**
* Diagnostic formatter which "localizes" a message as a line
* containing a key, and a possibly empty set of descriptive strings for the
* arg types.
*/
static
class
ArgTypeMessages
extends
JavacMessages
{
static
void
preRegister
(
final
Context
c
)
{
c
.
put
(
JavacMessages
.
messagesKey
,
new
Context
.
Factory
<
JavacMessages
>()
{
public
JavacMessages
make
()
{
return
new
ArgTypeMessages
(
c
)
{
@Override
public
String
getLocalizedString
(
Locale
l
,
String
key
,
Object
...
args
)
{
return
getKeyArgsString
(
key
,
args
);
}
};
}
});
}
ArgTypeMessages
(
Context
context
)
{
super
(
context
);
}
}
/**
* Utility method to generate a string for key and args
*/
static
String
getKeyArgsString
(
String
key
,
Object
...
args
)
{
StringBuilder
buf
=
new
StringBuilder
();
buf
.
append
(
key
);
String
sep
=
": "
;
for
(
Object
o
:
args
)
{
buf
.
append
(
sep
);
buf
.
append
(
getArgTypeOrStringValue
(
o
));
sep
=
", "
;
}
return
buf
.
toString
();
}
static
boolean
showStringValues
=
false
;
static
String
getArgTypeOrStringValue
(
Object
o
)
{
if
(
showStringValues
&&
o
instanceof
String
)
return
"\""
+
o
+
"\""
;
return
getArgType
(
o
);
}
static
String
getArgType
(
Object
o
)
{
if
(
o
==
null
)
return
"null"
;
if
(
o
instanceof
Name
)
return
"name"
;
if
(
o
instanceof
Boolean
)
return
"boolean"
;
if
(
o
instanceof
Integer
)
return
"number"
;
if
(
o
instanceof
String
)
return
"string"
;
if
(
o
instanceof
Flag
)
return
"modifier"
;
if
(
o
instanceof
KindName
)
return
"symbol kind"
;
if
(
o
instanceof
Token
)
return
"token"
;
if
(
o
instanceof
Symbol
)
return
"symbol"
;
if
(
o
instanceof
Type
)
return
"type"
;
if
(
o
instanceof
List
)
{
List
<?>
l
=
(
List
<?>)
o
;
if
(
l
.
isEmpty
())
return
"list"
;
else
return
"list of "
+
getArgType
(
l
.
get
(
0
));
}
if
(
o
instanceof
ListBuffer
)
return
getArgType
(((
ListBuffer
)
o
).
toList
());
if
(
o
instanceof
Set
)
{
Set
<?>
s
=
(
Set
<?>)
o
;
if
(
s
.
isEmpty
())
return
"set"
;
else
return
"set of "
+
getArgType
(
s
.
iterator
().
next
());
}
if
(
o
instanceof
SourceVersion
)
return
"source version"
;
if
(
o
instanceof
FileObject
||
o
instanceof
File
)
return
"file name"
;
if
(
o
instanceof
JCDiagnostic
)
return
"message segment"
;
if
(
o
instanceof
LocalizedString
)
return
"message segment"
;
// only instance is "no arguments"
String
s
=
o
.
getClass
().
getSimpleName
();
return
(
s
.
isEmpty
()
?
o
.
getClass
().
getName
()
:
s
);
}
// </editor-fold>
}
test/tools/javac/diags/Example.java
浏览文件 @
9f575334
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010,
2011,
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
...
...
@@ -168,7 +168,7 @@ class Example implements Comparable<Example> {
try
{
run
(
null
,
keys
,
true
,
verbose
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
(
System
.
err
);
}
return
keys
;
}
...
...
@@ -293,10 +293,15 @@ class Example implements Comparable<Example> {
}
abstract
static
class
Compiler
{
static
Compiler
getCompiler
(
List
<
String
>
opts
,
boolean
verbose
)
{
interface
Factory
{
Compiler
getCompiler
(
List
<
String
>
opts
,
boolean
verbose
);
}
static
class
DefaultFactory
implements
Factory
{
public
Compiler
getCompiler
(
List
<
String
>
opts
,
boolean
verbose
)
{
String
first
;
String
[]
rest
;
if
(
opts
==
null
||
opts
.
size
()
==
0
)
{
if
(
opts
==
null
||
opts
.
isEmpty
()
)
{
first
=
null
;
rest
=
new
String
[
0
];
}
else
{
...
...
@@ -311,6 +316,16 @@ class Example implements Comparable<Example> {
return
new
BackdoorCompiler
(
verbose
);
else
throw
new
IllegalArgumentException
(
first
);
}
}
static
Factory
factory
;
static
Compiler
getCompiler
(
List
<
String
>
opts
,
boolean
verbose
)
{
if
(
factory
==
null
)
factory
=
new
DefaultFactory
();
return
factory
.
getCompiler
(
opts
,
verbose
);
}
protected
Compiler
(
boolean
verbose
)
{
...
...
test/tools/javac/diags/MessageFile.java
0 → 100644
浏览文件 @
9f575334
/*
* Copyright (c) 2010, 2011, 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.
*/
import
java.io.*
;
import
java.util.*
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* Class to facilitate manipulating compiler.properties.
*/
class
MessageFile
{
static
final
Pattern
emptyOrCommentPattern
=
Pattern
.
compile
(
"( *#.*)?"
);
static
final
Pattern
infoPattern
=
Pattern
.
compile
(
"# ([0-9]+: [-A-Za-z ]+, )*[0-9]+: [-A-Za-z ]+"
);
/**
* A line of text within the message file.
* The lines form a doubly linked list for simple navigation.
*/
class
Line
{
String
text
;
Line
prev
;
Line
next
;
Line
(
String
text
)
{
this
.
text
=
text
;
}
boolean
isEmptyOrComment
()
{
return
emptyOrCommentPattern
.
matcher
(
text
).
matches
();
}
boolean
isInfo
()
{
return
infoPattern
.
matcher
(
text
).
matches
();
}
boolean
hasContinuation
()
{
return
(
next
!=
null
)
&&
text
.
endsWith
(
"\\"
);
}
Line
insertAfter
(
String
text
)
{
Line
l
=
new
Line
(
text
);
insertAfter
(
l
);
return
l
;
}
void
insertAfter
(
Line
l
)
{
assert
prev
==
null
&&
next
==
null
;
l
.
prev
=
this
;
l
.
next
=
next
;
if
(
next
==
null
)
lastLine
=
l
;
else
next
.
prev
=
l
;
next
=
l
;
}
Line
insertBefore
(
String
text
)
{
Line
l
=
new
Line
(
text
);
insertBefore
(
l
);
return
l
;
}
void
insertBefore
(
Line
l
)
{
assert
prev
==
null
&&
next
==
null
;
l
.
prev
=
prev
;
l
.
next
=
this
;
if
(
prev
==
null
)
firstLine
=
l
;
else
prev
.
next
=
l
;
prev
=
l
;
}
void
remove
()
{
if
(
prev
==
null
)
firstLine
=
next
;
else
prev
.
next
=
next
;
if
(
next
==
null
)
lastLine
=
prev
;
else
next
.
prev
=
prev
;
prev
=
null
;
next
=
null
;
}
}
/**
* A message within the message file.
* A message is a series of lines containing a "name=value" property,
* optionally preceded by a comment describing the use of placeholders
* such as {0}, {1}, etc within the property value.
*/
static
final
class
Message
{
final
Line
firstLine
;
private
Info
info
;
Message
(
Line
l
)
{
firstLine
=
l
;
}
boolean
needInfo
()
{
Line
l
=
firstLine
;
while
(
true
)
{
if
(
l
.
text
.
matches
(
".*\\{[0-9]+\\}.*"
))
return
true
;
if
(!
l
.
hasContinuation
())
return
false
;
l
=
l
.
next
;
}
}
Set
<
Integer
>
getPlaceholders
()
{
Pattern
p
=
Pattern
.
compile
(
"\\{([0-9]+)\\}"
);
Set
<
Integer
>
results
=
new
TreeSet
<
Integer
>();
Line
l
=
firstLine
;
while
(
true
)
{
Matcher
m
=
p
.
matcher
(
l
.
text
);
while
(
m
.
find
())
results
.
add
(
Integer
.
parseInt
(
m
.
group
(
1
)));
if
(!
l
.
hasContinuation
())
return
results
;
l
=
l
.
next
;
}
}
/**
* Get the Info object for this message. It may be empty if there
* if no comment preceding the property specification.
*/
Info
getInfo
()
{
if
(
info
==
null
)
{
Line
l
=
firstLine
.
prev
;
if
(
l
!=
null
&&
l
.
isInfo
())
info
=
new
Info
(
l
.
text
);
else
info
=
new
Info
();
}
return
info
;
}
/**
* Set the Info for this message.
* If there was an info comment preceding the property specification,
* it will be updated; otherwise, one will be inserted.
*/
void
setInfo
(
Info
info
)
{
this
.
info
=
info
;
Line
l
=
firstLine
.
prev
;
if
(
l
!=
null
&&
l
.
isInfo
())
l
.
text
=
info
.
toComment
();
else
firstLine
.
insertBefore
(
info
.
toComment
());
}
/**
* Get all the lines pertaining to this message.
*/
List
<
Line
>
getLines
(
boolean
includeAllPrecedingComments
)
{
List
<
Line
>
lines
=
new
ArrayList
<
Line
>();
Line
l
=
firstLine
;
if
(
includeAllPrecedingComments
)
{
// scan back to find end of prev message
while
(
l
.
prev
!=
null
&&
l
.
prev
.
isEmptyOrComment
())
l
=
l
.
prev
;
// skip leading blank lines
while
(
l
.
text
.
isEmpty
())
l
=
l
.
next
;
}
else
{
if
(
l
.
prev
!=
null
&&
l
.
prev
.
isInfo
())
l
=
l
.
prev
;
}
// include any preceding lines
for
(
;
l
!=
firstLine
;
l
=
l
.
next
)
lines
.
add
(
l
);
// include message lines
for
(
l
=
firstLine
;
l
!=
null
&&
l
.
hasContinuation
();
l
=
l
.
next
)
lines
.
add
(
l
);
lines
.
add
(
l
);
// include trailing blank line if present
l
=
l
.
next
;
if
(
l
!=
null
&&
l
.
text
.
isEmpty
())
lines
.
add
(
l
);
return
lines
;
}
}
/**
* An object to represent the comment that may precede the property
* specification in a Message.
* The comment is modelled as a list of fields, where the fields correspond
* to the placeholder values (e.g. {0}, {1}, etc) within the message value.
*/
static
final
class
Info
{
/**
* An ordered set of descriptions for a placeholder value in a
* message.
*/
static
class
Field
{
boolean
unused
;
Set
<
String
>
values
;
boolean
listOfAny
=
false
;
boolean
setOfAny
=
false
;
Field
(
String
s
)
{
s
=
s
.
substring
(
s
.
indexOf
(
": "
)
+
2
);
values
=
new
LinkedHashSet
<
String
>(
Arrays
.
asList
(
s
.
split
(
" or "
)));
for
(
String
v:
values
)
{
if
(
v
.
startsWith
(
"list of"
))
listOfAny
=
true
;
if
(
v
.
startsWith
(
"set of"
))
setOfAny
=
true
;
}
}
/**
* Return true if this field logically contains all the values of
* another field.
*/
boolean
contains
(
Field
other
)
{
if
(
unused
!=
other
.
unused
)
return
false
;
for
(
String
v:
other
.
values
)
{
if
(
values
.
contains
(
v
))
continue
;
if
(
v
.
equals
(
"null"
)
||
v
.
equals
(
"string"
))
continue
;
if
(
v
.
equals
(
"list"
)
&&
listOfAny
)
continue
;
if
(
v
.
equals
(
"set"
)
&&
setOfAny
)
continue
;
return
false
;
}
return
true
;
}
/**
* Merge the values of another field into this field.
*/
void
merge
(
Field
other
)
{
unused
|=
other
.
unused
;
values
.
addAll
(
other
.
values
);
// cleanup unnecessary entries
if
(
values
.
contains
(
"null"
)
&&
values
.
size
()
>
1
)
{
// "null" is superceded by anything else
values
.
remove
(
"null"
);
}
if
(
values
.
contains
(
"string"
)
&&
values
.
size
()
>
1
)
{
// "string" is superceded by anything else
values
.
remove
(
"string"
);
}
if
(
values
.
contains
(
"list"
))
{
// list is superceded by "list of ..."
for
(
String
s:
values
)
{
if
(
s
.
startsWith
(
"list of "
))
{
values
.
remove
(
"list"
);
break
;
}
}
}
if
(
values
.
contains
(
"set"
))
{
// set is superceded by "set of ..."
for
(
String
s:
values
)
{
if
(
s
.
startsWith
(
"set of "
))
{
values
.
remove
(
"set"
);
break
;
}
}
}
if
(
other
.
values
.
contains
(
"unused"
))
{
values
.
clear
();
values
.
add
(
"unused"
);
}
}
void
markUnused
()
{
values
=
new
LinkedHashSet
<
String
>();
values
.
add
(
"unused"
);
listOfAny
=
false
;
setOfAny
=
false
;
}
@Override
public
String
toString
()
{
return
values
.
toString
();
}
}
/** The fields of the Info object. */
List
<
Field
>
fields
=
new
ArrayList
<
Field
>();
Info
()
{
}
Info
(
String
text
)
throws
IllegalArgumentException
{
if
(!
text
.
startsWith
(
"# "
))
throw
new
IllegalArgumentException
();
String
[]
segs
=
text
.
substring
(
2
).
split
(
", "
);
fields
=
new
ArrayList
<
Field
>();
for
(
String
seg:
segs
)
{
fields
.
add
(
new
Field
(
seg
));
}
}
Info
(
Set
<
String
>
infos
)
throws
IllegalArgumentException
{
for
(
String
s:
infos
)
merge
(
new
Info
(
s
));
}
boolean
isEmpty
()
{
return
fields
.
isEmpty
();
}
boolean
contains
(
Info
other
)
{
if
(
other
.
isEmpty
())
return
true
;
if
(
fields
.
size
()
!=
other
.
fields
.
size
())
return
false
;
Iterator
<
Field
>
oIter
=
other
.
fields
.
iterator
();
for
(
Field
values:
fields
)
{
if
(!
values
.
contains
(
oIter
.
next
()))
return
false
;
}
return
true
;
}
void
merge
(
Info
other
)
{
if
(
fields
.
isEmpty
())
{
fields
.
addAll
(
other
.
fields
);
return
;
}
if
(
other
.
fields
.
size
()
!=
fields
.
size
())
throw
new
IllegalArgumentException
();
Iterator
<
Field
>
oIter
=
other
.
fields
.
iterator
();
for
(
Field
d:
fields
)
{
d
.
merge
(
oIter
.
next
());
}
}
void
markUnused
(
Set
<
Integer
>
used
)
{
for
(
int
i
=
0
;
i
<
fields
.
size
();
i
++)
{
if
(!
used
.
contains
(
i
))
fields
.
get
(
i
).
markUnused
();
}
}
@Override
public
String
toString
()
{
return
fields
.
toString
();
}
String
toComment
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"# "
);
String
sep
=
""
;
int
i
=
0
;
for
(
Field
f:
fields
)
{
sb
.
append
(
sep
);
sb
.
append
(
i
++);
sb
.
append
(
": "
);
sep
=
""
;
for
(
String
s:
f
.
values
)
{
sb
.
append
(
sep
);
sb
.
append
(
s
);
sep
=
" or "
;
}
sep
=
", "
;
}
return
sb
.
toString
();
}
}
Line
firstLine
;
Line
lastLine
;
Map
<
String
,
Message
>
messages
=
new
TreeMap
<
String
,
Message
>();
MessageFile
(
File
file
)
throws
IOException
{
Reader
in
=
new
FileReader
(
file
);
try
{
read
(
in
);
}
finally
{
in
.
close
();
}
}
MessageFile
(
Reader
in
)
throws
IOException
{
read
(
in
);
}
final
void
read
(
Reader
in
)
throws
IOException
{
BufferedReader
br
=
(
in
instanceof
BufferedReader
)
?
(
BufferedReader
)
in
:
new
BufferedReader
(
in
);
String
line
;
while
((
line
=
br
.
readLine
())
!=
null
)
{
Line
l
;
if
(
firstLine
==
null
)
l
=
firstLine
=
lastLine
=
new
Line
(
line
);
else
l
=
lastLine
.
insertAfter
(
line
);
if
(
line
.
startsWith
(
"compiler."
))
{
int
eq
=
line
.
indexOf
(
"="
);
if
(
eq
>
0
)
messages
.
put
(
line
.
substring
(
0
,
eq
),
new
Message
(
l
));
}
}
}
void
write
(
File
file
)
throws
IOException
{
Writer
out
=
new
FileWriter
(
file
);
try
{
write
(
out
);
}
finally
{
out
.
close
();
}
}
void
write
(
Writer
out
)
throws
IOException
{
BufferedWriter
bw
=
(
out
instanceof
BufferedWriter
)
?
(
BufferedWriter
)
out
:
new
BufferedWriter
(
out
);
for
(
Line
l
=
firstLine
;
l
!=
null
;
l
=
l
.
next
)
{
bw
.
write
(
l
.
text
);
bw
.
write
(
"\n"
);
// always use Unix line endings
}
bw
.
flush
();
}
}
test/tools/javac/diags/MessageInfo.java
0 → 100644
浏览文件 @
9f575334
/*
* Copyright (c) 2010, 2011, 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 7013272
* @summary Automatically generate info about how compiler resource keys are used
* @build Example ArgTypeCompilerFactory MessageFile MessageInfo
* @run main MessageInfo
*/
import
java.io.*
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
/**
* Utility to manipulate compiler.properties, and suggest info comments based
* on information derived from running examples.
*
* Options:
* -examples dir location of examples directory
* -o file output file
* -check just check message file
* -ensureNewlines ensure newline after each entry
* -fixIndent fix indentation of continuation lines
* -sort sort messages
* -verbose verbose output
* -replace replace comments instead of merging comments
* file javac compiler.properties file
*
*/
public
class
MessageInfo
{
public
static
void
main
(
String
...
args
)
throws
Exception
{
jtreg
=
(
System
.
getProperty
(
"test.src"
)
!=
null
);
File
tmpDir
;
if
(
jtreg
)
{
// use standard jtreg scratch directory: the current directory
tmpDir
=
new
File
(
System
.
getProperty
(
"user.dir"
));
}
else
{
tmpDir
=
new
File
(
System
.
getProperty
(
"java.io.tmpdir"
),
MessageInfo
.
class
.
getName
()
+
(
new
SimpleDateFormat
(
"yyMMddHHmmss"
)).
format
(
new
Date
()));
}
Example
.
setTempDir
(
tmpDir
);
Example
.
Compiler
.
factory
=
new
ArgTypeCompilerFactory
();
MessageInfo
mi
=
new
MessageInfo
();
try
{
if
(
mi
.
run
(
args
))
return
;
}
finally
{
/* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the
* jtreg scratch directory, which is the current directory.
* In case someone is faking jtreg mode, make sure to only
* clean tmpDir when it is reasonable to do so.
*/
if
(
tmpDir
.
isDirectory
()
&&
tmpDir
.
getName
().
startsWith
(
MessageInfo
.
class
.
getName
()))
{
if
(
clean
(
tmpDir
))
tmpDir
.
delete
();
}
}
if
(
jtreg
)
throw
new
Exception
(
mi
.
errors
+
" errors occurred"
);
else
System
.
exit
(
1
);
}
void
usage
()
{
System
.
out
.
println
(
"Usage:"
);
System
.
out
.
println
(
" java MessageInfo [options] [file]"
);
System
.
out
.
println
(
"where options include"
);
System
.
out
.
println
(
" -examples dir location of examples directory"
);
System
.
out
.
println
(
" -o file output file"
);
System
.
out
.
println
(
" -check just check message file"
);
System
.
out
.
println
(
" -ensureNewlines ensure newline after each entry"
);
System
.
out
.
println
(
" -fixIndent fix indentation of continuation lines"
);
System
.
out
.
println
(
" -sort sort messages"
);
System
.
out
.
println
(
" -verbose verbose output"
);
System
.
out
.
println
(
" -replace replace comments instead of merging comments"
);
System
.
out
.
println
(
" file javac compiler.properties file"
);
}
boolean
run
(
String
...
args
)
{
File
testSrc
=
new
File
(
System
.
getProperty
(
"test.src"
,
"."
));
File
examplesDir
=
new
File
(
testSrc
,
"examples"
);
File
notYetFile
=
null
;
File
msgFile
=
null
;
File
outFile
=
null
;
boolean
verbose
=
false
;
boolean
ensureNewlines
=
false
;
boolean
fixIndent
=
false
;
boolean
sort
=
false
;
boolean
replace
=
false
;
boolean
check
=
jtreg
;
// default true in jtreg mode
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
String
arg
=
args
[
i
];
if
(
arg
.
equals
(
"-examples"
)
&&
(
i
+
1
)
<
args
.
length
)
examplesDir
=
new
File
(
args
[++
i
]);
else
if
(
arg
.
equals
(
"-notyet"
)
&&
(
i
+
1
)
<
args
.
length
)
notYetFile
=
new
File
(
args
[++
i
]);
else
if
(
arg
.
equals
(
"-ensureNewlines"
))
ensureNewlines
=
true
;
else
if
(
arg
.
equals
(
"-fixIndent"
))
fixIndent
=
true
;
else
if
(
arg
.
equals
(
"-sort"
))
sort
=
true
;
else
if
(
arg
.
equals
(
"-verbose"
))
verbose
=
true
;
else
if
(
arg
.
equals
(
"-replace"
))
replace
=
true
;
else
if
(
arg
.
equals
(
"-check"
))
check
=
true
;
else
if
(
arg
.
equals
(
"-o"
)
&&
(
i
+
1
)
<
args
.
length
)
outFile
=
new
File
(
args
[++
i
]);
else
if
(
arg
.
startsWith
(
"-"
))
{
error
(
"unknown option: "
+
arg
);
return
false
;
}
else
if
(
i
==
args
.
length
-
1
)
{
msgFile
=
new
File
(
arg
);
}
else
{
error
(
"unknown arg: "
+
arg
);
return
false
;
}
}
if
(!
check
&&
outFile
==
null
)
{
usage
();
return
true
;
}
if
((
ensureNewlines
||
fixIndent
||
sort
)
&&
outFile
==
null
)
{
error
(
"must set output file for these options"
);
return
false
;
}
if
(
notYetFile
==
null
)
{
notYetFile
=
new
File
(
examplesDir
.
getParentFile
(),
"examples.not-yet.txt"
);
}
if
(
msgFile
==
null
)
{
for
(
File
d
=
testSrc
;
d
!=
null
;
d
=
d
.
getParentFile
())
{
if
(
new
File
(
d
,
"TEST.ROOT"
).
exists
())
{
d
=
d
.
getParentFile
();
File
f
=
new
File
(
d
,
"src/share/classes/com/sun/tools/javac/resources/compiler.properties"
);
if
(
f
.
exists
())
{
msgFile
=
f
;
break
;
}
}
}
if
(
msgFile
==
null
)
{
error
(
"no message file available"
);
return
false
;
}
}
MessageFile
mf
;
try
{
mf
=
new
MessageFile
(
msgFile
);
}
catch
(
IOException
e
)
{
error
(
"problem reading message file: "
+
e
);
return
false
;
}
Map
<
String
,
Set
<
String
>>
msgInfo
=
runExamples
(
examplesDir
,
verbose
);
if
(
ensureNewlines
)
ensureNewlines
(
mf
);
if
(
fixIndent
)
fixIndent
(
mf
);
if
(
sort
)
sort
(
mf
,
true
);
for
(
Map
.
Entry
<
String
,
Set
<
String
>>
e:
msgInfo
.
entrySet
())
{
String
k
=
e
.
getKey
();
Set
<
String
>
suggestions
=
e
.
getValue
();
MessageFile
.
Message
m
=
mf
.
messages
.
get
(
k
);
if
(
m
==
null
)
{
error
(
"Can't find message for "
+
k
+
" in message file"
);
continue
;
}
MessageFile
.
Info
info
=
m
.
getInfo
();
Set
<
Integer
>
placeholders
=
m
.
getPlaceholders
();
MessageFile
.
Info
suggestedInfo
=
new
MessageFile
.
Info
(
suggestions
);
suggestedInfo
.
markUnused
(
placeholders
);
if
(!
info
.
isEmpty
())
{
if
(
info
.
contains
(
suggestedInfo
))
continue
;
if
(!
replace
)
{
if
(
info
.
fields
.
size
()
!=
suggestedInfo
.
fields
.
size
())
error
(
"Cannot merge info for "
+
k
);
else
suggestedInfo
.
merge
(
info
);
}
}
if
(
outFile
==
null
)
{
System
.
err
.
println
(
"suggest for "
+
k
);
System
.
err
.
println
(
suggestedInfo
.
toComment
());
}
else
m
.
setInfo
(
suggestedInfo
);
}
if
(
check
)
check
(
mf
,
notYetFile
);
try
{
if
(
outFile
!=
null
)
mf
.
write
(
outFile
);
}
catch
(
IOException
e
)
{
error
(
"problem writing file: "
+
e
);
return
false
;
}
return
(
errors
==
0
);
}
void
check
(
MessageFile
mf
,
File
notYetFile
)
{
Set
<
String
>
notYetList
=
null
;
for
(
Map
.
Entry
<
String
,
MessageFile
.
Message
>
e:
mf
.
messages
.
entrySet
())
{
String
key
=
e
.
getKey
();
MessageFile
.
Message
m
=
e
.
getValue
();
if
(
m
.
needInfo
()
&&
m
.
getInfo
().
isEmpty
())
{
if
(
notYetList
==
null
)
notYetList
=
getNotYetList
(
notYetFile
);
if
(
notYetList
.
contains
(
key
))
System
.
err
.
println
(
"Warning: no info for "
+
key
);
else
error
(
"no info for "
+
key
);
}
}
}
void
ensureNewlines
(
MessageFile
mf
)
{
for
(
MessageFile
.
Message
m:
mf
.
messages
.
values
())
{
MessageFile
.
Line
l
=
m
.
firstLine
;
while
(
l
.
text
.
endsWith
(
"\\"
))
l
=
l
.
next
;
if
(
l
.
next
!=
null
&&
!
l
.
next
.
text
.
isEmpty
())
l
.
insertAfter
(
""
);
}
}
void
fixIndent
(
MessageFile
mf
)
{
for
(
MessageFile
.
Message
m:
mf
.
messages
.
values
())
{
MessageFile
.
Line
l
=
m
.
firstLine
;
while
(
l
.
text
.
endsWith
(
"\\"
)
&&
l
.
next
!=
null
)
{
if
(!
l
.
next
.
text
.
matches
(
"^ \\S.*"
))
l
.
next
.
text
=
" "
+
l
.
next
.
text
.
trim
();
l
=
l
.
next
;
}
}
}
void
sort
(
MessageFile
mf
,
boolean
includePrecedingNewlines
)
{
for
(
MessageFile
.
Message
m:
mf
.
messages
.
values
())
{
for
(
MessageFile
.
Line
l:
m
.
getLines
(
includePrecedingNewlines
))
{
l
.
remove
();
mf
.
lastLine
.
insertAfter
(
l
);
}
}
}
Map
<
String
,
Set
<
String
>>
runExamples
(
File
examplesDir
,
boolean
verbose
)
{
Map
<
String
,
Set
<
String
>>
map
=
new
TreeMap
<
String
,
Set
<
String
>>();
for
(
Example
e:
getExamples
(
examplesDir
))
{
StringWriter
sw
=
new
StringWriter
();
PrintWriter
pw
=
new
PrintWriter
(
sw
);
e
.
run
(
pw
,
true
,
verbose
);
pw
.
close
();
String
[]
lines
=
sw
.
toString
().
split
(
"\n"
);
for
(
String
line:
lines
)
{
if
(!
line
.
startsWith
(
"compiler."
))
continue
;
int
colon
=
line
.
indexOf
(
":"
);
if
(
colon
==
-
1
)
continue
;
String
key
=
line
.
substring
(
0
,
colon
);
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"# "
);
int
i
=
0
;
String
[]
descs
=
line
.
substring
(
colon
+
1
).
split
(
", *"
);
for
(
String
desc:
descs
)
{
if
(
i
>
0
)
sb
.
append
(
", "
);
sb
.
append
(
i
++);
sb
.
append
(
": "
);
sb
.
append
(
desc
.
trim
());
}
Set
<
String
>
set
=
map
.
get
(
key
);
if
(
set
==
null
)
map
.
put
(
key
,
set
=
new
TreeSet
<
String
>());
set
.
add
(
sb
.
toString
());
}
}
return
map
;
}
/**
* Get the complete set of examples to be checked.
*/
Set
<
Example
>
getExamples
(
File
examplesDir
)
{
Set
<
Example
>
results
=
new
TreeSet
<
Example
>();
for
(
File
f:
examplesDir
.
listFiles
())
{
if
(
isValidExample
(
f
))
results
.
add
(
new
Example
(
f
));
}
return
results
;
}
boolean
isValidExample
(
File
f
)
{
return
(
f
.
isDirectory
()
&&
(!
jtreg
||
f
.
list
().
length
>
0
))
||
(
f
.
isFile
()
&&
f
.
getName
().
endsWith
(
".java"
));
}
/**
* Get the contents of the "not-yet" list.
*/
Set
<
String
>
getNotYetList
(
File
file
)
{
Set
<
String
>
results
=
new
TreeSet
<
String
>();
try
{
String
[]
lines
=
read
(
file
).
split
(
"[\r\n]"
);
for
(
String
line:
lines
)
{
int
hash
=
line
.
indexOf
(
"#"
);
if
(
hash
!=
-
1
)
line
=
line
.
substring
(
0
,
hash
).
trim
();
if
(
line
.
matches
(
"[A-Za-z0-9-_.]+"
))
results
.
add
(
line
);
}
}
catch
(
IOException
e
)
{
throw
new
Error
(
e
);
}
return
results
;
}
/**
* Read the contents of a file.
*/
String
read
(
File
f
)
throws
IOException
{
byte
[]
bytes
=
new
byte
[(
int
)
f
.
length
()];
DataInputStream
in
=
new
DataInputStream
(
new
FileInputStream
(
f
));
try
{
in
.
readFully
(
bytes
);
}
finally
{
in
.
close
();
}
return
new
String
(
bytes
);
}
/**
* Report an error.
*/
void
error
(
String
msg
)
{
System
.
err
.
println
(
"Error: "
+
msg
);
errors
++;
}
static
boolean
jtreg
;
int
errors
;
/**
* Clean the contents of a directory.
*/
static
boolean
clean
(
File
dir
)
{
boolean
ok
=
true
;
for
(
File
f:
dir
.
listFiles
())
{
if
(
f
.
isDirectory
())
ok
&=
clean
(
f
);
ok
&=
f
.
delete
();
}
return
ok
;
}
}
test/tools/javac/diags/RunExamples.java
浏览文件 @
9f575334
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010,
2011,
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
...
...
@@ -25,7 +25,7 @@
* @test
* @bug 6968063
* @summary provide examples of code that generate diagnostics
* @build Example HTMLWriter RunExamples
* @build
ArgTypeCompilerFactory
Example HTMLWriter RunExamples
* @run main RunExamples
*/
...
...
@@ -97,6 +97,7 @@ public class RunExamples {
boolean
raw
=
false
;
boolean
showFiles
=
false
;
boolean
verbose
=
false
;
boolean
argTypes
=
false
;
String
title
=
null
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
...
...
@@ -115,6 +116,8 @@ public class RunExamples {
outFile
=
new
File
(
args
[++
i
]);
else
if
(
arg
.
equals
(
"-title"
)
&&
(
i
+
1
)
<
args
.
length
)
title
=
args
[++
i
];
else
if
(
arg
.
equals
(
"-argtypes"
))
argTypes
=
true
;
else
if
(
arg
.
startsWith
(
"-"
))
{
error
(
"unknown option: "
+
arg
);
return
false
;
...
...
@@ -127,6 +130,11 @@ public class RunExamples {
}
}
// special mode to show message keys and the types of the args that
// are used.
if
(
argTypes
)
Example
.
Compiler
.
factory
=
new
ArgTypeCompilerFactory
();
if
(
selectedKeys
.
size
()
>
0
)
{
Set
<
Example
>
examples
=
getExamples
(
examplesDir
);
nextKey:
...
...
@@ -138,7 +146,7 @@ public class RunExamples {
error
(
"Key "
+
k
+
": no examples found"
);
}
}
else
{
if
(
selectedExamples
.
size
()
==
0
)
if
(
selectedExamples
.
isEmpty
()
)
selectedExamples
=
getExamples
(
examplesDir
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录