mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Force LF for basically everything.
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
[*.{ql,qll,qlref,dbscheme,qhelp,html,js,mjs,ts,json,yml,c,cpp,h,hpp}]
|
[*]
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
|
|||||||
13
.gitattributes
vendored
13
.gitattributes
vendored
@@ -16,12 +16,25 @@
|
|||||||
*.dbscheme eol=lf
|
*.dbscheme eol=lf
|
||||||
*.qhelp eol=lf
|
*.qhelp eol=lf
|
||||||
*.html eol=lf
|
*.html eol=lf
|
||||||
|
*.htm eol=lf
|
||||||
|
*.xhtml eol=lf
|
||||||
|
*.xhtm eol=lf
|
||||||
*.js eol=lf
|
*.js eol=lf
|
||||||
*.mjs eol=lf
|
*.mjs eol=lf
|
||||||
*.ts eol=lf
|
*.ts eol=lf
|
||||||
*.json eol=lf
|
*.json eol=lf
|
||||||
*.yml eol=lf
|
*.yml eol=lf
|
||||||
|
*.yaml eol=lf
|
||||||
*.c eol=lf
|
*.c eol=lf
|
||||||
*.cpp eol=lf
|
*.cpp eol=lf
|
||||||
*.h eol=lf
|
*.h eol=lf
|
||||||
*.hpp eol=lf
|
*.hpp eol=lf
|
||||||
|
*.md eol=lf
|
||||||
|
*.stats eol=lf
|
||||||
|
*.xml eol=lf
|
||||||
|
*.sh eol=lf
|
||||||
|
*.pl eol=lf
|
||||||
|
*.java eol=lf
|
||||||
|
*.cs eol=lf
|
||||||
|
*.py eol=lf
|
||||||
|
*.lua eol=lf
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
# Improvements to C/C++ analysis
|
# Improvements to C/C++ analysis
|
||||||
|
|
||||||
## General improvements
|
## General improvements
|
||||||
|
|
||||||
## New queries
|
## New queries
|
||||||
|
|
||||||
| **Query** | **Tags** | **Purpose** |
|
| **Query** | **Tags** | **Purpose** |
|
||||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||||
| *@name of query (Query ID)* | *Tags* |*Aim of the new query and whether it is enabled by default or not* |
|
| *@name of query (Query ID)* | *Tags* |*Aim of the new query and whether it is enabled by default or not* |
|
||||||
|
|
||||||
## Changes to existing queries
|
## Changes to existing queries
|
||||||
|
|
||||||
| **Query** | **Expected impact** | **Change** |
|
| **Query** | **Expected impact** | **Change** |
|
||||||
|----------------------------|------------------------|------------------------------------------------------------------|
|
|----------------------------|------------------------|------------------------------------------------------------------|
|
||||||
| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. |
|
| Resource not released in destructor | Fewer false positive results | Placement new is now excluded from the query. |
|
||||||
|
|
||||||
|
|
||||||
## Changes to QL libraries
|
## Changes to QL libraries
|
||||||
|
|
||||||
* Added a hash consing library for structural comparison of expressions.
|
* Added a hash consing library for structural comparison of expressions.
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?eclipse version="3.2"?>
|
<?eclipse version="3.2"?>
|
||||||
<plugin>
|
<plugin>
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="semmlecode-cpp-queries"/>
|
<name value="semmlecode-cpp-queries"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.cpp.library"/>
|
<name value="com.semmle.code.cpp.library"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.cpp.dbscheme"/>
|
<name value="com.semmle.code.cpp.dbscheme"/>
|
||||||
<path value="/semmlecode.cpp.dbscheme"/>
|
<path value="/semmlecode.cpp.dbscheme"/>
|
||||||
</extension>
|
</extension>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -1,137 +1,137 @@
|
|||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
import glob
|
import glob
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
|
||||||
BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$")
|
BEGIN_TEMPLATE = re.compile(r"^/\*template\s*$")
|
||||||
END_TEMPLATE = re.compile(r"^\*/\s*$")
|
END_TEMPLATE = re.compile(r"^\*/\s*$")
|
||||||
|
|
||||||
def expand_template_params(args, param_arg_map):
|
def expand_template_params(args, param_arg_map):
|
||||||
'''Given a list of template arguments that may reference template parameters
|
'''Given a list of template arguments that may reference template parameters
|
||||||
of the current template, return a new list of template arguments with each
|
of the current template, return a new list of template arguments with each
|
||||||
parameter use replaced with the appropriate fully-qualified argument for
|
parameter use replaced with the appropriate fully-qualified argument for
|
||||||
that parameter.'''
|
that parameter.'''
|
||||||
result = []
|
result = []
|
||||||
for arg in args:
|
for arg in args:
|
||||||
if arg in param_arg_map:
|
if arg in param_arg_map:
|
||||||
result.append(param_arg_map[arg])
|
result.append(param_arg_map[arg])
|
||||||
else:
|
else:
|
||||||
result.append(arg)
|
result.append(arg)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def find_instantiation(module, args, templates):
|
def find_instantiation(module, args, templates):
|
||||||
'''Given a template module and a set of template arguments, find the module
|
'''Given a template module and a set of template arguments, find the module
|
||||||
name of the instantiation of that module with those arguments.'''
|
name of the instantiation of that module with those arguments.'''
|
||||||
template = templates[module]
|
template = templates[module]
|
||||||
for instantiation in template["template_def"]["instantiations"]:
|
for instantiation in template["template_def"]["instantiations"]:
|
||||||
if instantiation["args"] == args:
|
if instantiation["args"] == args:
|
||||||
return instantiation["name"]
|
return instantiation["name"]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def instantiate_template(template, instantiation, root, templates):
|
def instantiate_template(template, instantiation, root, templates):
|
||||||
'''Create a single instantiation of a template.'''
|
'''Create a single instantiation of a template.'''
|
||||||
template_def = template["template_def"]
|
template_def = template["template_def"]
|
||||||
output_components = instantiation["name"].split(".")
|
output_components = instantiation["name"].split(".")
|
||||||
output_path = root
|
output_path = root
|
||||||
for component in output_components:
|
for component in output_components:
|
||||||
output_path = os.path.join(output_path, component)
|
output_path = os.path.join(output_path, component)
|
||||||
output_path = output_path + ".qll"
|
output_path = output_path + ".qll"
|
||||||
with open(output_path, "w") as output:
|
with open(output_path, "w") as output:
|
||||||
output.write(
|
output.write(
|
||||||
"""
|
"""
|
||||||
/*
|
/*
|
||||||
* THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'.
|
* THIS FILE IS AUTOMATICALLY GENERATED FROM '%s'.
|
||||||
* DO NOT EDIT MANUALLY.
|
* DO NOT EDIT MANUALLY.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
""" % (template["name"].replace(".", "/") + ".qllt")
|
""" % (template["name"].replace(".", "/") + ".qllt")
|
||||||
)
|
)
|
||||||
param_arg_map = {}
|
param_arg_map = {}
|
||||||
for param_index in range(len(template_def["params"])):
|
for param_index in range(len(template_def["params"])):
|
||||||
param = template_def["params"][param_index]
|
param = template_def["params"][param_index]
|
||||||
arg = instantiation["args"][param_index]
|
arg = instantiation["args"][param_index]
|
||||||
output.write("private import %s as %s // Template parameter\n" % (arg, param))
|
output.write("private import %s as %s // Template parameter\n" % (arg, param))
|
||||||
param_arg_map[param] = arg
|
param_arg_map[param] = arg
|
||||||
for import_record in template_def["imports"]:
|
for import_record in template_def["imports"]:
|
||||||
if "access" in import_record:
|
if "access" in import_record:
|
||||||
output.write(import_record["access"] + " ")
|
output.write(import_record["access"] + " ")
|
||||||
imported_module = find_instantiation(import_record["module"],
|
imported_module = find_instantiation(import_record["module"],
|
||||||
expand_template_params(import_record["args"], param_arg_map), templates)
|
expand_template_params(import_record["args"], param_arg_map), templates)
|
||||||
output.write("import %s // %s<%s>\n" %
|
output.write("import %s // %s<%s>\n" %
|
||||||
(
|
(
|
||||||
imported_module,
|
imported_module,
|
||||||
import_record["module"],
|
import_record["module"],
|
||||||
", ".join(import_record["args"])
|
", ".join(import_record["args"])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
output.writelines(template_def["body_lines"])
|
output.writelines(template_def["body_lines"])
|
||||||
|
|
||||||
def generate_instantiations(template, root, templates):
|
def generate_instantiations(template, root, templates):
|
||||||
'''Create a .qll source file for each instantiation of the specified template.'''
|
'''Create a .qll source file for each instantiation of the specified template.'''
|
||||||
template_def = template["template_def"]
|
template_def = template["template_def"]
|
||||||
if "instantiations" in template_def:
|
if "instantiations" in template_def:
|
||||||
for instantiation in template_def["instantiations"]:
|
for instantiation in template_def["instantiations"]:
|
||||||
instantiate_template(template, instantiation, root, templates)
|
instantiate_template(template, instantiation, root, templates)
|
||||||
|
|
||||||
def read_template(template_path, module_name):
|
def read_template(template_path, module_name):
|
||||||
'''Read a .qllt template file from template_path, using module_name as the
|
'''Read a .qllt template file from template_path, using module_name as the
|
||||||
fully qualified name of the module.'''
|
fully qualified name of the module.'''
|
||||||
with open(template_path) as input:
|
with open(template_path) as input:
|
||||||
in_template = False
|
in_template = False
|
||||||
template_text = ""
|
template_text = ""
|
||||||
template_def = None
|
template_def = None
|
||||||
body_lines = []
|
body_lines = []
|
||||||
for line in iter(input):
|
for line in iter(input):
|
||||||
if in_template:
|
if in_template:
|
||||||
if END_TEMPLATE.match(line):
|
if END_TEMPLATE.match(line):
|
||||||
template_def = json.loads(template_text)
|
template_def = json.loads(template_text)
|
||||||
in_template = False
|
in_template = False
|
||||||
else:
|
else:
|
||||||
template_text += line
|
template_text += line
|
||||||
else:
|
else:
|
||||||
if BEGIN_TEMPLATE.match(line) and not template_def:
|
if BEGIN_TEMPLATE.match(line) and not template_def:
|
||||||
in_template = True
|
in_template = True
|
||||||
else:
|
else:
|
||||||
body_lines.append(line)
|
body_lines.append(line)
|
||||||
|
|
||||||
if template_def:
|
if template_def:
|
||||||
template_def["body_lines"] = body_lines
|
template_def["body_lines"] = body_lines
|
||||||
|
|
||||||
result = { "name": module_name }
|
result = { "name": module_name }
|
||||||
if template_def:
|
if template_def:
|
||||||
result["template_def"] = template_def
|
result["template_def"] = template_def
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def module_name_from_path_impl(path):
|
def module_name_from_path_impl(path):
|
||||||
(head, tail) = os.path.split(path)
|
(head, tail) = os.path.split(path)
|
||||||
if head == "":
|
if head == "":
|
||||||
return tail
|
return tail
|
||||||
else:
|
else:
|
||||||
return module_name_from_path(head) + "." + tail
|
return module_name_from_path(head) + "." + tail
|
||||||
|
|
||||||
def module_name_from_path(path):
|
def module_name_from_path(path):
|
||||||
'''Compute the fully qualified name of a module from the path of its .qll[t]
|
'''Compute the fully qualified name of a module from the path of its .qll[t]
|
||||||
file. The path should be relative to the library root.'''
|
file. The path should be relative to the library root.'''
|
||||||
(module_root, ext) = os.path.splitext(path)
|
(module_root, ext) = os.path.splitext(path)
|
||||||
return module_name_from_path_impl(module_root)
|
return module_name_from_path_impl(module_root)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
templates = {}
|
templates = {}
|
||||||
|
|
||||||
root = sys.argv[1]
|
root = sys.argv[1]
|
||||||
for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True):
|
for template_path in glob.glob(os.path.join(root, "**\\*.qllt"), recursive = True):
|
||||||
print(template_path)
|
print(template_path)
|
||||||
module_name = module_name_from_path(os.path.relpath(template_path, root))
|
module_name = module_name_from_path(os.path.relpath(template_path, root))
|
||||||
print(module_name)
|
print(module_name)
|
||||||
template = read_template(template_path, module_name)
|
template = read_template(template_path, module_name)
|
||||||
templates[template["name"]] = template
|
templates[template["name"]] = template
|
||||||
|
|
||||||
for name, template in templates.items():
|
for name, template in templates.items():
|
||||||
if "template_def" in template:
|
if "template_def" in template:
|
||||||
generate_instantiations(template, root, templates)
|
generate_instantiations(template, root, templates)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?eclipse version="3.2"?>
|
<?eclipse version="3.2"?>
|
||||||
<plugin>
|
<plugin>
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="semmlecode-csharp-queries"/>
|
<name value="semmlecode-csharp-queries"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.csharp.library"/>
|
<name value="com.semmle.code.csharp.library"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.csharp.dbscheme"/>
|
<name value="com.semmle.code.csharp.dbscheme"/>
|
||||||
<path value="/semmlecode.csharp.dbscheme"/>
|
<path value="/semmlecode.csharp.dbscheme"/>
|
||||||
</extension>
|
</extension>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
// semmle-extractor-options: --standalone
|
// semmle-extractor-options: --standalone
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
class Cfg
|
class Cfg
|
||||||
{
|
{
|
||||||
void F()
|
void F()
|
||||||
{
|
{
|
||||||
var v = new InvalidType();
|
var v = new InvalidType();
|
||||||
Debug.Assert(v.a.b, "This is true");
|
Debug.Assert(v.a.b, "This is true");
|
||||||
|
|
||||||
new CounterCreationData() { CounterHelp = string.Empty, CounterType = v.Type };
|
new CounterCreationData() { CounterHelp = string.Empty, CounterType = v.Type };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,417 +1,417 @@
|
|||||||
# QL Style Guide
|
# QL Style Guide
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
This document describes how to format the QL code you contribute to this repository. It covers aspects such as layout, white-space, naming and documentation. Adhering to consistent standards makes code easier to read and maintain. Of course, these are only guidelines, and can be overridden as the need arises on a case-by-case basis. Where existing code deviates from these guidelines, prefer consistency with the surrounding code.
|
This document describes how to format the QL code you contribute to this repository. It covers aspects such as layout, white-space, naming and documentation. Adhering to consistent standards makes code easier to read and maintain. Of course, these are only guidelines, and can be overridden as the need arises on a case-by-case basis. Where existing code deviates from these guidelines, prefer consistency with the surrounding code.
|
||||||
|
|
||||||
Words in *italic* are defined in the [Glossary](#glossary).
|
Words in *italic* are defined in the [Glossary](#glossary).
|
||||||
|
|
||||||
## Indentation
|
## Indentation
|
||||||
1. *Always* use 2 spaces for indentation.
|
1. *Always* use 2 spaces for indentation.
|
||||||
1. *Always* indent:
|
1. *Always* indent:
|
||||||
- The *body* of a module, newtype, class or predicate
|
- The *body* of a module, newtype, class or predicate
|
||||||
- The second and subsequent lines after you use a line break to split a long line
|
- The second and subsequent lines after you use a line break to split a long line
|
||||||
- The *body* of a `from`, `where` or `select` clause where it spans multiple lines
|
- The *body* of a `from`, `where` or `select` clause where it spans multiple lines
|
||||||
- The *body* of a *quantifier* that spans multiple lines
|
- The *body* of a *quantifier* that spans multiple lines
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
module Helpers {
|
module Helpers {
|
||||||
/** ... */
|
/** ... */
|
||||||
class X ... {
|
class X ... {
|
||||||
/** ... */
|
/** ... */
|
||||||
int getNumberOfChildren () {
|
int getNumberOfChildren () {
|
||||||
result = count(int child |
|
result = count(int child |
|
||||||
exists(this.getChild(child))
|
exists(this.getChild(child))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
from Call c, string reason
|
from Call c, string reason
|
||||||
where isDeprecated(c, reason)
|
where isDeprecated(c, reason)
|
||||||
select c, "This call to '$@' is deprecated because " + reason + ".",
|
select c, "This call to '$@' is deprecated because " + reason + ".",
|
||||||
c.getTarget(), c.getTarget().getName()
|
c.getTarget(), c.getTarget().getName()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Line breaks
|
## Line breaks
|
||||||
1. Use UNIX line endings.
|
1. Use UNIX line endings.
|
||||||
1. Lines *must not* exceed 100 characters.
|
1. Lines *must not* exceed 100 characters.
|
||||||
1. Long lines *should* be split with a line break, and the following lines *must* be indented one level until the next "regular" line break.
|
1. Long lines *should* be split with a line break, and the following lines *must* be indented one level until the next "regular" line break.
|
||||||
1. There *should* be a single blank line:
|
1. There *should* be a single blank line:
|
||||||
- Between the file documentation and the first `import`
|
- Between the file documentation and the first `import`
|
||||||
- Before each declaration, except for the first declaration in a *body*
|
- Before each declaration, except for the first declaration in a *body*
|
||||||
- Before the `from`-`where`-`select` section in a query file
|
- Before the `from`-`where`-`select` section in a query file
|
||||||
1. *Avoid* two or more adjacent blank lines.
|
1. *Avoid* two or more adjacent blank lines.
|
||||||
1. There *must* be a new line after the *annotations* `cached`, `pragma`, `language` and `bindingset`. Other *annotations* do not have a new line.
|
1. There *must* be a new line after the *annotations* `cached`, `pragma`, `language` and `bindingset`. Other *annotations* do not have a new line.
|
||||||
1. There *should not* be additional blank lines within a predicate.
|
1. There *should not* be additional blank lines within a predicate.
|
||||||
1. There *may* be a new line:
|
1. There *may* be a new line:
|
||||||
- Immediately after the `from`, `where` or `select` keywords in a query.
|
- Immediately after the `from`, `where` or `select` keywords in a query.
|
||||||
- Immediately after `if`, `then`, or `else` keywords. The `then` and `else` parts *should* be consistent.
|
- Immediately after `if`, `then`, or `else` keywords. The `then` and `else` parts *should* be consistent.
|
||||||
1. *Avoid* other line breaks in declarations, other than to break long lines.
|
1. *Avoid* other line breaks in declarations, other than to break long lines.
|
||||||
1. When operands of *binary operators* span two lines, the operator *should* be placed at the end of the first line.
|
1. When operands of *binary operators* span two lines, the operator *should* be placed at the end of the first line.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
cached
|
cached
|
||||||
private int getNumberOfParameters() {
|
private int getNumberOfParameters() {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
predicate methodStats(string qualifiedName, string name,
|
predicate methodStats(string qualifiedName, string name,
|
||||||
int numberOfParameters, int numberOfStatements, int numberOfExpressions,
|
int numberOfParameters, int numberOfStatements, int numberOfExpressions,
|
||||||
int linesOfCode, int nestingDepth, int numberOfBranches) {
|
int linesOfCode, int nestingDepth, int numberOfBranches) {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
from Method main
|
from Method main
|
||||||
where main.getName() = "Main"
|
where main.getName() = "Main"
|
||||||
select main, "This is the program entry point."
|
select main, "This is the program entry point."
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
from Method main
|
from Method main
|
||||||
where
|
where
|
||||||
main.getName() = "Main" and
|
main.getName() = "Main" and
|
||||||
main.getNumberOfParameters() = 0
|
main.getNumberOfParameters() = 0
|
||||||
select main, "Main method has no parameters."
|
select main, "Main method has no parameters."
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if x.isPublic()
|
if x.isPublic()
|
||||||
then result = "public"
|
then result = "public"
|
||||||
else result = "private"
|
else result = "private"
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if x.isPublic() then
|
if x.isPublic() then
|
||||||
result = "public"
|
result = "public"
|
||||||
else
|
else
|
||||||
result = "private"
|
result = "private"
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if
|
if
|
||||||
x.isPublic()
|
x.isPublic()
|
||||||
then
|
then
|
||||||
result = "public"
|
result = "public"
|
||||||
else
|
else
|
||||||
result = "private"
|
result = "private"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Braces
|
## Braces
|
||||||
1. Braces follow [Stroustrup](https://en.wikipedia.org/wiki/Indentation_style#Variant:_Stroustrup) style. The opening `{` *must* be placed at the end of the preceding line.
|
1. Braces follow [Stroustrup](https://en.wikipedia.org/wiki/Indentation_style#Variant:_Stroustrup) style. The opening `{` *must* be placed at the end of the preceding line.
|
||||||
1. The closing `}` *must* be placed on its own line, indented to the outer level, or be on the same line as the opening `{`.
|
1. The closing `}` *must* be placed on its own line, indented to the outer level, or be on the same line as the opening `{`.
|
||||||
1. Braces of empty blocks *may* be placed on a single line, with a single space separating the braces.
|
1. Braces of empty blocks *may* be placed on a single line, with a single space separating the braces.
|
||||||
1. Short predicates, not exceeding the maximum line width, *may* be placed on a single line, with a space following the opening brace and preceding the closing brace.
|
1. Short predicates, not exceeding the maximum line width, *may* be placed on a single line, with a space following the opening brace and preceding the closing brace.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
class ThrowException extends ThrowExpr {
|
class ThrowException extends ThrowExpr {
|
||||||
Foo() {
|
Foo() {
|
||||||
this.getTarget() instanceof ExceptionClass
|
this.getTarget() instanceof ExceptionClass
|
||||||
}
|
}
|
||||||
|
|
||||||
override string toString() { result = "Throw Exception" }
|
override string toString() { result = "Throw Exception" }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Spaces
|
## Spaces
|
||||||
1. There *must* be a space or line break:
|
1. There *must* be a space or line break:
|
||||||
- Surrounding each `=` and `|`
|
- Surrounding each `=` and `|`
|
||||||
- After each `,`
|
- After each `,`
|
||||||
1. There *should* be a space or line break:
|
1. There *should* be a space or line break:
|
||||||
- Surrounding each *binary operator*, which *must* be balanced
|
- Surrounding each *binary operator*, which *must* be balanced
|
||||||
- Surrounding `..` in a range
|
- Surrounding `..` in a range
|
||||||
- Exceptions to this may be made to save space or to improve readability.
|
- Exceptions to this may be made to save space or to improve readability.
|
||||||
1. *Avoid* other spaces, for example:
|
1. *Avoid* other spaces, for example:
|
||||||
- After a *quantifier/aggregation* keyword
|
- After a *quantifier/aggregation* keyword
|
||||||
- After the predicate name in a *call*
|
- After the predicate name in a *call*
|
||||||
- Inside brackets used for *calls*, single-line quantifiers, and parenthesised formulas
|
- Inside brackets used for *calls*, single-line quantifiers, and parenthesised formulas
|
||||||
- Surrounding a `.`
|
- Surrounding a `.`
|
||||||
- Inside the opening or closing `[ ]` in a range expression
|
- Inside the opening or closing `[ ]` in a range expression
|
||||||
- Inside casts `a.(X)`
|
- Inside casts `a.(X)`
|
||||||
1. *Avoid* multiple spaces, except for indentation, and *avoid* additional indentation to align formulas, parameters or arguments.
|
1. *Avoid* multiple spaces, except for indentation, and *avoid* additional indentation to align formulas, parameters or arguments.
|
||||||
1. *Do not* put whitespace on blank lines, or trailing on the end of a line.
|
1. *Do not* put whitespace on blank lines, or trailing on the end of a line.
|
||||||
1. *Do not* use tabs.
|
1. *Do not* use tabs.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
cached
|
cached
|
||||||
private predicate foo(Expr e, Expr p) {
|
private predicate foo(Expr e, Expr p) {
|
||||||
exists(int n |
|
exists(int n |
|
||||||
n in [0 .. 1] |
|
n in [0 .. 1] |
|
||||||
e = p.getChild(n + 1)
|
e = p.getChild(n + 1)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Naming
|
## Naming
|
||||||
1. Use [PascalCase](http://wiki.c2.com/?PascalCase) for:
|
1. Use [PascalCase](http://wiki.c2.com/?PascalCase) for:
|
||||||
- `class` names
|
- `class` names
|
||||||
- `module` names
|
- `module` names
|
||||||
- `newtype` names
|
- `newtype` names
|
||||||
1. Use [camelCase](https://en.wikipedia.org/wiki/Camel_case) for:
|
1. Use [camelCase](https://en.wikipedia.org/wiki/Camel_case) for:
|
||||||
- Predicate names
|
- Predicate names
|
||||||
- Variable names
|
- Variable names
|
||||||
1. Newtype predicate names *should* begin with `T`.
|
1. Newtype predicate names *should* begin with `T`.
|
||||||
1. Predicates that have a result *should* be named `get...`
|
1. Predicates that have a result *should* be named `get...`
|
||||||
1. Predicates that can return multiple results *should* be named `getA...` or `getAn...`
|
1. Predicates that can return multiple results *should* be named `getA...` or `getAn...`
|
||||||
1. Predicates that don't have a result or parameters *should* be named `is...` or `has...`
|
1. Predicates that don't have a result or parameters *should* be named `is...` or `has...`
|
||||||
1. *Avoid* underscores in names.
|
1. *Avoid* underscores in names.
|
||||||
1. *Avoid* short or single-letter names for classes, predicates and fields.
|
1. *Avoid* short or single-letter names for classes, predicates and fields.
|
||||||
1. Short or single letter names for parameters and *quantifiers* *may* be used provided that they are sufficiently clear.
|
1. Short or single letter names for parameters and *quantifiers* *may* be used provided that they are sufficiently clear.
|
||||||
1. Use names as they are used in the target-language specification.
|
1. Use names as they are used in the target-language specification.
|
||||||
1. Use American English.
|
1. Use American English.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
/** ... */
|
/** ... */
|
||||||
predicate calls(Callable caller, Callable callee) {
|
predicate calls(Callable caller, Callable callee) {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
/** ... */
|
/** ... */
|
||||||
class Type extends ... {
|
class Type extends ... {
|
||||||
/** ... */
|
/** ... */
|
||||||
string getName() { ... }
|
string getName() { ... }
|
||||||
|
|
||||||
/** ... */
|
/** ... */
|
||||||
predicate declares(Member m) { ... }
|
predicate declares(Member m) { ... }
|
||||||
|
|
||||||
/** ... */
|
/** ... */
|
||||||
predicate isGeneric() { ... }
|
predicate isGeneric() { ... }
|
||||||
|
|
||||||
/** ... */
|
/** ... */
|
||||||
Type getTypeParameter(int n) { ... }
|
Type getTypeParameter(int n) { ... }
|
||||||
|
|
||||||
/** ... */
|
/** ... */
|
||||||
Type getATypeParameter() { ... }
|
Type getATypeParameter() { ... }
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
General requirements:
|
General requirements:
|
||||||
|
|
||||||
1. Documentation *must* adhere to the [QLDoc specification](https://help.semmle.com/QL/QLDocSpecification.html).
|
1. Documentation *must* adhere to the [QLDoc specification](https://help.semmle.com/QL/QLDocSpecification.html).
|
||||||
1. Use `/** ... */` for documentation, even for single line comments.
|
1. Use `/** ... */` for documentation, even for single line comments.
|
||||||
1. For single-line documentation, the `/**` and `*/` are written on the same line as the comment.
|
1. For single-line documentation, the `/**` and `*/` are written on the same line as the comment.
|
||||||
1. For multi-line documentation, the `/**` and `*/` are written on separate lines. There is a `*` preceding each comment line, aligned on the first `*`.
|
1. For multi-line documentation, the `/**` and `*/` are written on separate lines. There is a `*` preceding each comment line, aligned on the first `*`.
|
||||||
1. Use full sentences, with capital letters and full stops.
|
1. Use full sentences, with capital letters and full stops.
|
||||||
1. Use American English.
|
1. Use American English.
|
||||||
1. Documentation comments *should* be appropriate for users of the code.
|
1. Documentation comments *should* be appropriate for users of the code.
|
||||||
1. Documentation for maintainers of the code *must* use normal comments.
|
1. Documentation for maintainers of the code *must* use normal comments.
|
||||||
|
|
||||||
Documentation for specific items:
|
Documentation for specific items:
|
||||||
|
|
||||||
1. Public declarations *must* be documented.
|
1. Public declarations *must* be documented.
|
||||||
1. Non-public declarations *should* be documented.
|
1. Non-public declarations *should* be documented.
|
||||||
1. Declarations in query files *should* be documented.
|
1. Declarations in query files *should* be documented.
|
||||||
1. Library files (`.qll` files) *should* be have a documentation comment at the top of the file.
|
1. Library files (`.qll` files) *should* be have a documentation comment at the top of the file.
|
||||||
1. Query files, except for tests, *must* have a QLDoc query documentation comment at the top of the file.
|
1. Query files, except for tests, *must* have a QLDoc query documentation comment at the top of the file.
|
||||||
1. Predicates that do not have a result *should* be documented `/** Holds if ... */`
|
1. Predicates that do not have a result *should* be documented `/** Holds if ... */`
|
||||||
1. Predicates that have a result *should* be documented `/** Gets ... */`
|
1. Predicates that have a result *should* be documented `/** Gets ... */`
|
||||||
1. All predicate parameters *should* be referred to in the predicate documentation.
|
1. All predicate parameters *should* be referred to in the predicate documentation.
|
||||||
1. Reference names, such as types and parameters, using backticks `` ` ``.
|
1. Reference names, such as types and parameters, using backticks `` ` ``.
|
||||||
1. Give examples of code in the target language, enclosed in ```` ``` ```` or `` ` ``.
|
1. Give examples of code in the target language, enclosed in ```` ``` ```` or `` ` ``.
|
||||||
1. Classes *should* be documented in the singular, for example `/* An expression. */`
|
1. Classes *should* be documented in the singular, for example `/* An expression. */`
|
||||||
1. Where a class denotes a generic concept with subclasses, list those subclasses.
|
1. Where a class denotes a generic concept with subclasses, list those subclasses.
|
||||||
1. Declarations that are deprecated *should* be documented as `DEPRECATED: ...`
|
1. Declarations that are deprecated *should* be documented as `DEPRECATED: ...`
|
||||||
1. Declarations that are for internal use *should* be documented as `INTERNAL: Do not use`.
|
1. Declarations that are for internal use *should* be documented as `INTERNAL: Do not use`.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
/** Provides logic for determining constant expressions. */
|
/** Provides logic for determining constant expressions. */
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
/**
|
/**
|
||||||
* Holds if the qualifier of this call has type `qualifierType`.
|
* Holds if the qualifier of this call has type `qualifierType`.
|
||||||
* `isExactType` indicates whether the type is exact, that is, whether
|
* `isExactType` indicates whether the type is exact, that is, whether
|
||||||
* the qualifier is guaranteed not to be a subtype of `qualifierType`.
|
* the qualifier is guaranteed not to be a subtype of `qualifierType`.
|
||||||
*/
|
*/
|
||||||
```
|
```
|
||||||
```ql
|
```ql
|
||||||
/**
|
/**
|
||||||
* A delegate declaration, for example
|
* A delegate declaration, for example
|
||||||
* ```
|
* ```
|
||||||
* delegate void Logger(string text);
|
* delegate void Logger(string text);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
class Delegate extends ...
|
class Delegate extends ...
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
/**
|
/**
|
||||||
* An element that can be called.
|
* An element that can be called.
|
||||||
*
|
*
|
||||||
* Either a method (`Method`), a constructor (`Constructor`), a destructor
|
* Either a method (`Method`), a constructor (`Constructor`), a destructor
|
||||||
* (`Destructor`), an operator (`Operator`), an accessor (`Accessor`),
|
* (`Destructor`), an operator (`Operator`), an accessor (`Accessor`),
|
||||||
* an anonymous function (`AnonymousFunctionExpr`), or a local function
|
* an anonymous function (`AnonymousFunctionExpr`), or a local function
|
||||||
* (`LocalFunction`).
|
* (`LocalFunction`).
|
||||||
*/
|
*/
|
||||||
class Callable extends ...
|
class Callable extends ...
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
/** DEPRECATED: Use `getAnExpr()` instead. */
|
/** DEPRECATED: Use `getAnExpr()` instead. */
|
||||||
deprecated Expr getInitializer()
|
deprecated Expr getInitializer()
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
/**
|
/**
|
||||||
* INTERNAL: Do not use.
|
* INTERNAL: Do not use.
|
||||||
*/
|
*/
|
||||||
```
|
```
|
||||||
|
|
||||||
## Formulas
|
## Formulas
|
||||||
1. *Prefer* one *conjunct* per line.
|
1. *Prefer* one *conjunct* per line.
|
||||||
1. Write the `and` at the end of the line. This also applies in `where` clauses.
|
1. Write the `and` at the end of the line. This also applies in `where` clauses.
|
||||||
1. *Prefer* to write the `or` keyword on its own line.
|
1. *Prefer* to write the `or` keyword on its own line.
|
||||||
1. The `or` keyword *may* be written at the end of a line, or within a line, provided that it has no unparenthesised `and` operands.
|
1. The `or` keyword *may* be written at the end of a line, or within a line, provided that it has no unparenthesised `and` operands.
|
||||||
1. Single-line formulas *may* be used in order to save space or add clarity, particularly in the *body* of a *quantifier/aggregation*.
|
1. Single-line formulas *may* be used in order to save space or add clarity, particularly in the *body* of a *quantifier/aggregation*.
|
||||||
1. *Always* use brackets to clarify the precedence of:
|
1. *Always* use brackets to clarify the precedence of:
|
||||||
- `implies`
|
- `implies`
|
||||||
- `if`-`then`-`else`
|
- `if`-`then`-`else`
|
||||||
1. Parenthesised formulas *can* be written:
|
1. Parenthesised formulas *can* be written:
|
||||||
- Within a single line. There *should not* be an additional space following the opening parenthesis or preceding the closing parenthesis.
|
- Within a single line. There *should not* be an additional space following the opening parenthesis or preceding the closing parenthesis.
|
||||||
- Spanning multiple lines. The opening parenthesis *should* be placed at the end of the preceding line, the body should be indented one level, and the closing bracket should be placed on a new line at the outer indentation.
|
- Spanning multiple lines. The opening parenthesis *should* be placed at the end of the preceding line, the body should be indented one level, and the closing bracket should be placed on a new line at the outer indentation.
|
||||||
1. *Quantifiers/aggregations* *can* be written:
|
1. *Quantifiers/aggregations* *can* be written:
|
||||||
- Within a single line. In this case, there is no space to the inside of the parentheses, or after the quantifier keyword.
|
- Within a single line. In this case, there is no space to the inside of the parentheses, or after the quantifier keyword.
|
||||||
- Across multiple lines. In this case, type declarations are on the same line as the quantifier, the `|` *may* be at the end of the line, or *may* be on its own line, and the body of the quantifier *must* be indented one level. The closing `)` is written on a new line, at the outer indentation.
|
- Across multiple lines. In this case, type declarations are on the same line as the quantifier, the `|` *may* be at the end of the line, or *may* be on its own line, and the body of the quantifier *must* be indented one level. The closing `)` is written on a new line, at the outer indentation.
|
||||||
1. `if`-`then`-`else` *can* be written:
|
1. `if`-`then`-`else` *can* be written:
|
||||||
- On a single line
|
- On a single line
|
||||||
- With the *body* after the `if`/`then`/`else` keyword
|
- With the *body* after the `if`/`then`/`else` keyword
|
||||||
- With the *body* indented on the next line
|
- With the *body* indented on the next line
|
||||||
- *Always* parenthesise the `else` part if it is a compound formula.
|
- *Always* parenthesise the `else` part if it is a compound formula.
|
||||||
1. The `and` and `else` keywords *may* be placed on the same line as the closing parenthesis.
|
1. The `and` and `else` keywords *may* be placed on the same line as the closing parenthesis.
|
||||||
1. The `and` and `else` keywords *may* be "cuddled": `) else (`
|
1. The `and` and `else` keywords *may* be "cuddled": `) else (`
|
||||||
1. *Always* qualify *calls* to predicates of the same class with `this`.
|
1. *Always* qualify *calls* to predicates of the same class with `this`.
|
||||||
2. *Prefer* postfix casts `a.(Expr)` to prefix casts `(Expr)a`.
|
2. *Prefer* postfix casts `a.(Expr)` to prefix casts `(Expr)a`.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
argumentType.isImplicitlyConvertibleTo(parameterType)
|
argumentType.isImplicitlyConvertibleTo(parameterType)
|
||||||
or
|
or
|
||||||
argumentType instanceof NullType and
|
argumentType instanceof NullType and
|
||||||
result.getParameter(i).isOut() and
|
result.getParameter(i).isOut() and
|
||||||
parameterType instanceof SimpleType
|
parameterType instanceof SimpleType
|
||||||
or
|
or
|
||||||
reflectionOrDynamicArg(argumentType, parameterType)
|
reflectionOrDynamicArg(argumentType, parameterType)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
this.getName() = "Finalize" and not exists(this.getAParameter())
|
this.getName() = "Finalize" and not exists(this.getAParameter())
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
e1.getType() instanceof BoolType and (
|
e1.getType() instanceof BoolType and (
|
||||||
b1 = true
|
b1 = true
|
||||||
or
|
or
|
||||||
b1 = false
|
b1 = false
|
||||||
) and (
|
) and (
|
||||||
b2 = true
|
b2 = true
|
||||||
or
|
or
|
||||||
b2 = false
|
b2 = false
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if e1 instanceof BitwiseOrExpr or e1 instanceof LogicalOrExpr then (
|
if e1 instanceof BitwiseOrExpr or e1 instanceof LogicalOrExpr then (
|
||||||
impliesSub(e1.(BinaryOperation).getAnOperand(), e2, b1, b2) and
|
impliesSub(e1.(BinaryOperation).getAnOperand(), e2, b1, b2) and
|
||||||
b1 = false
|
b1 = false
|
||||||
) else (
|
) else (
|
||||||
e1.getType() instanceof BoolType and
|
e1.getType() instanceof BoolType and
|
||||||
e1 = e2 and
|
e1 = e2 and
|
||||||
b1 = b2 and
|
b1 = b2 and
|
||||||
(b1 = true or b1 = false)
|
(b1 = true or b1 = false)
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
(x instanceof Exception implies x.isPublic()) and y instanceof Exception
|
(x instanceof Exception implies x.isPublic()) and y instanceof Exception
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
x instanceof Exception implies (x.isPublic() and y instanceof Exception)
|
x instanceof Exception implies (x.isPublic() and y instanceof Exception)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
exists(Type arg | arg = this.getAChild() | arg instanceof TypeParameter)
|
exists(Type arg | arg = this.getAChild() | arg instanceof TypeParameter)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
exists(Type qualifierType |
|
exists(Type qualifierType |
|
||||||
this.hasNonExactQualifierType(qualifierType) |
|
this.hasNonExactQualifierType(qualifierType) |
|
||||||
result = getANonExactQualifierSubType(qualifierType)
|
result = getANonExactQualifierSubType(qualifierType)
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
methods = count(Method m | t = m.getDeclaringType() and not ilc(m))
|
methods = count(Method m | t = m.getDeclaringType() and not ilc(m))
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if n = 0 then result = 1 else result = n * f(n - 1)
|
if n = 0 then result = 1 else result = n * f(n - 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if n = 0
|
if n = 0
|
||||||
then result = 1
|
then result = 1
|
||||||
else result = n * f(n - 1)
|
else result = n * f(n - 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if
|
if
|
||||||
n = 0
|
n = 0
|
||||||
then
|
then
|
||||||
result = 1
|
result = 1
|
||||||
else
|
else
|
||||||
result = n * f(n - 1)
|
result = n * f(n - 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ql
|
```ql
|
||||||
if exists(this.getContainingType()) then (
|
if exists(this.getContainingType()) then (
|
||||||
result = "A nested class" and
|
result = "A nested class" and
|
||||||
parentName = this.getContainingType().getFullyQualifiedName()
|
parentName = this.getContainingType().getFullyQualifiedName()
|
||||||
) else (
|
) else (
|
||||||
result = parentName + "." + this.getName() and
|
result = parentName + "." + this.getName() and
|
||||||
parentName = this.getNamespace().getFullyQualifiedName()
|
parentName = this.getNamespace().getFullyQualifiedName()
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Glossary
|
## Glossary
|
||||||
|
|
||||||
| Phrase | Meaning |
|
| Phrase | Meaning |
|
||||||
|-------------|----------|
|
|-------------|----------|
|
||||||
| *[annotation](https://help.semmle.com/QL/QLLanguageSpecification.html#annotations)* | An additional specifier used to modify a declaration, such as `private`, `override`, `deprecated`, `pragma`, `bindingset`, or `cached`. |
|
| *[annotation](https://help.semmle.com/QL/QLLanguageSpecification.html#annotations)* | An additional specifier used to modify a declaration, such as `private`, `override`, `deprecated`, `pragma`, `bindingset`, or `cached`. |
|
||||||
| *body* | The text inside `{ }`, `( )`, or each section of an `if`-`then`-`else` or `from`-`where`-`select`. |
|
| *body* | The text inside `{ }`, `( )`, or each section of an `if`-`then`-`else` or `from`-`where`-`select`. |
|
||||||
| *binary operator* | An operator with two operands, such as comparison operators, `and`, `or`, `implies`, or arithmetic operators. |
|
| *binary operator* | An operator with two operands, such as comparison operators, `and`, `or`, `implies`, or arithmetic operators. |
|
||||||
| *call* | A *formula* that invokes a predicate, e.g. `this.isStatic()` or `calls(a,b)`. |
|
| *call* | A *formula* that invokes a predicate, e.g. `this.isStatic()` or `calls(a,b)`. |
|
||||||
| *[conjunct](https://help.semmle.com/QL/QLLanguageSpecification.html#conjunctions)* | A formula that is an operand to an `and`. |
|
| *[conjunct](https://help.semmle.com/QL/QLLanguageSpecification.html#conjunctions)* | A formula that is an operand to an `and`. |
|
||||||
| *declaration* | A class, module, predicate, field or newtype. |
|
| *declaration* | A class, module, predicate, field or newtype. |
|
||||||
| *[disjunct](https://help.semmle.com/QL/QLLanguageSpecification.html#disjunctions)* | A formula that is an operand to an `or`. |
|
| *[disjunct](https://help.semmle.com/QL/QLLanguageSpecification.html#disjunctions)* | A formula that is an operand to an `or`. |
|
||||||
| *[formula](https://help.semmle.com/QL/QLLanguageSpecification.html#formulas)* | A logical expression, such as `A = B`, a *call*, a *quantifier*, `and`, `or`, `not`, `in` or `instanceof`. |
|
| *[formula](https://help.semmle.com/QL/QLLanguageSpecification.html#formulas)* | A logical expression, such as `A = B`, a *call*, a *quantifier*, `and`, `or`, `not`, `in` or `instanceof`. |
|
||||||
| *should/should not/avoid/prefer* | Adhere to this rule wherever possible, where it makes sense. |
|
| *should/should not/avoid/prefer* | Adhere to this rule wherever possible, where it makes sense. |
|
||||||
| *may/can* | This is a reasonable alternative, to be used with discretion. |
|
| *may/can* | This is a reasonable alternative, to be used with discretion. |
|
||||||
| *must/always/do not* | Always adhere to this rule. |
|
| *must/always/do not* | Always adhere to this rule. |
|
||||||
| *[quantifier/aggregation](https://help.semmle.com/QL/QLLanguageSpecification.html#aggregations)* | `exists`, `count`, `strictcount`, `any`, `forall`, `forex` and so on. |
|
| *[quantifier/aggregation](https://help.semmle.com/QL/QLLanguageSpecification.html#aggregations)* | `exists`, `count`, `strictcount`, `any`, `forall`, `forex` and so on. |
|
||||||
| *variable* | A parameter to a predicate, a field, a from variable, or a variable introduced by a *quantifier* or *aggregation*. |
|
| *variable* | A parameter to a predicate, a field, a from variable, or a variable introduced by a *quantifier* or *aggregation*. |
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
<!--AVOID: 'shippingService' and 'orderService' share several properties with the same values-->
|
<!--AVOID: 'shippingService' and 'orderService' share several properties with the same values-->
|
||||||
<bean id="shippingService" class="documentation.examples.spring.ShippingService">
|
<bean id="shippingService" class="documentation.examples.spring.ShippingService">
|
||||||
<property name="transactionHelper">
|
<property name="transactionHelper">
|
||||||
<ref bean="transactionHelper"/>
|
<ref bean="transactionHelper"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="dao">
|
<property name="dao">
|
||||||
<ref bean="dao"/>
|
<ref bean="dao"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="registry">
|
<property name="registry">
|
||||||
<ref bean="basicRegistry"/>
|
<ref bean="basicRegistry"/>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
<property name="shippingProvider" value="Federal Parcel Service"/>
|
<property name="shippingProvider" value="Federal Parcel Service"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
||||||
<property name="transactionHelper">
|
<property name="transactionHelper">
|
||||||
<ref bean="transactionHelper"/>
|
<ref bean="transactionHelper"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="dao">
|
<property name="dao">
|
||||||
<ref bean="dao"/>
|
<ref bean="dao"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="registry">
|
<property name="registry">
|
||||||
<ref bean="basicRegistry"/>
|
<ref bean="basicRegistry"/>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
<property name="orderReference" value="8675309"/>
|
<property name="orderReference" value="8675309"/>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<beans>
|
<beans>
|
||||||
<!--Compose configuration files by using the 'import' element.-->
|
<!--Compose configuration files by using the 'import' element.-->
|
||||||
<import resource="services.xml"/>
|
<import resource="services.xml"/>
|
||||||
<import resource="resources/messageSource.xml"/>
|
<import resource="resources/messageSource.xml"/>
|
||||||
|
|
||||||
<bean id="bean1" class="..."/>
|
<bean id="bean1" class="..."/>
|
||||||
<bean id="bean2" class="..."/>
|
<bean id="bean2" class="..."/>
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<beans>
|
<beans>
|
||||||
<!-- This bean is referred to, so is live. -->
|
<!-- This bean is referred to, so is live. -->
|
||||||
<bean id="petStore" class="org.sample.PetStoreService"/>
|
<bean id="petStore" class="org.sample.PetStoreService"/>
|
||||||
<!-- This bean is never referred to, so is dead. -->
|
<!-- This bean is never referred to, so is dead. -->
|
||||||
<bean id="clinic" class="org.sample.ClinicService"/>
|
<bean id="clinic" class="org.sample.ClinicService"/>
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
<beans>
|
<beans>
|
||||||
<bean id="baseShippingService" abstract="true">
|
<bean id="baseShippingService" abstract="true">
|
||||||
<property name="transactionHelper">
|
<property name="transactionHelper">
|
||||||
<ref bean="transactionHelper"/>
|
<ref bean="transactionHelper"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="dao">
|
<property name="dao">
|
||||||
<ref bean="dao"/>
|
<ref bean="dao"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="registry">
|
<property name="registry">
|
||||||
<ref bean="basicRegistry"/>
|
<ref bean="basicRegistry"/>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="shippingService"
|
<bean id="shippingService"
|
||||||
class="documentation.examples.spring.ShippingService"
|
class="documentation.examples.spring.ShippingService"
|
||||||
parent="baseShippingService">
|
parent="baseShippingService">
|
||||||
<!--AVOID: This property is already defined with the same value in the parent bean.-->
|
<!--AVOID: This property is already defined with the same value in the parent bean.-->
|
||||||
<property name="registry">
|
<property name="registry">
|
||||||
<ref bean="basicRegistry"/>
|
<ref bean="basicRegistry"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="shippingProvider" value="Federal Parcel Service"/>
|
<property name="shippingProvider" value="Federal Parcel Service"/>
|
||||||
</bean>
|
</bean>
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<!--AVOID: Using autowiring makes it difficult to see the dependencies of the bean-->
|
<!--AVOID: Using autowiring makes it difficult to see the dependencies of the bean-->
|
||||||
<bean id="autoWiredOrderService"
|
<bean id="autoWiredOrderService"
|
||||||
class="documentation.examples.spring.OrderService"
|
class="documentation.examples.spring.OrderService"
|
||||||
autowire="byName"/>
|
autowire="byName"/>
|
||||||
|
|
||||||
<!--GOOD: Explicitly specifying the properties of the bean documents its dependencies
|
<!--GOOD: Explicitly specifying the properties of the bean documents its dependencies
|
||||||
and makes the bean configuration easier to maintain-->
|
and makes the bean configuration easier to maintain-->
|
||||||
<bean id="orderService"
|
<bean id="orderService"
|
||||||
class="documentation.examples.spring.OrderService">
|
class="documentation.examples.spring.OrderService">
|
||||||
<property name="DAO">
|
<property name="DAO">
|
||||||
<idref bean="dao"/>
|
<idref bean="dao"/>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
<!--AVOID: Using explicit constructor indices makes the bean configuration
|
<!--AVOID: Using explicit constructor indices makes the bean configuration
|
||||||
vulnerable to changes to the constructor-->
|
vulnerable to changes to the constructor-->
|
||||||
<bean id="billingService1" class="documentation.examples.spring.BillingService">
|
<bean id="billingService1" class="documentation.examples.spring.BillingService">
|
||||||
<constructor-arg index="0" value="John Doe"/>
|
<constructor-arg index="0" value="John Doe"/>
|
||||||
<constructor-arg index="1" ref="dao"/>
|
<constructor-arg index="1" ref="dao"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!--GOOD: Using type matching makes the bean configuration more robust to changes in
|
<!--GOOD: Using type matching makes the bean configuration more robust to changes in
|
||||||
the constructor-->
|
the constructor-->
|
||||||
<bean id="billingService2" class="documentation.examples.spring.BillingService">
|
<bean id="billingService2" class="documentation.examples.spring.BillingService">
|
||||||
<constructor-arg ref="dao"/>
|
<constructor-arg ref="dao"/>
|
||||||
<constructor-arg type="java.lang.String" value="Jane Doe"/>
|
<constructor-arg type="java.lang.String" value="Jane Doe"/>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -1,26 +1,26 @@
|
|||||||
<beans>
|
<beans>
|
||||||
<import resource="services.xml"/>
|
<import resource="services.xml"/>
|
||||||
|
|
||||||
<bean id="bean1" class="..."/>
|
<bean id="bean1" class="..."/>
|
||||||
<bean id="bean2" class="..."/>
|
<bean id="bean2" class="..."/>
|
||||||
|
|
||||||
<!--AVOID: Imports in the middle of a bean configuration make it difficult
|
<!--AVOID: Imports in the middle of a bean configuration make it difficult
|
||||||
to immediately determine the dependencies of the configuration-->
|
to immediately determine the dependencies of the configuration-->
|
||||||
<import resource="resources/messageSource.xml"/>
|
<import resource="resources/messageSource.xml"/>
|
||||||
|
|
||||||
<bean id="bean3" class="..."/>
|
<bean id="bean3" class="..."/>
|
||||||
<bean id="bean4" class="..."/>
|
<bean id="bean4" class="..."/>
|
||||||
</beans>
|
</beans>
|
||||||
|
|
||||||
|
|
||||||
<beans>
|
<beans>
|
||||||
<!--GOOD: Having the imports at the top immediately gives an idea of
|
<!--GOOD: Having the imports at the top immediately gives an idea of
|
||||||
what the dependencies of the configuration are-->
|
what the dependencies of the configuration are-->
|
||||||
<import resource="services.xml"/>
|
<import resource="services.xml"/>
|
||||||
<import resource="resources/messageSource.xml"/>
|
<import resource="resources/messageSource.xml"/>
|
||||||
|
|
||||||
<bean id="bean1" class="..."/>
|
<bean id="bean1" class="..."/>
|
||||||
<bean id="bean2" class="..."/>
|
<bean id="bean2" class="..."/>
|
||||||
<bean id="bean3" class="..."/>
|
<bean id="bean3" class="..."/>
|
||||||
<bean id="bean4" class="..."/>
|
<bean id="bean4" class="..."/>
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
<beans>
|
<beans>
|
||||||
<!--Using a description element makes it easier for tools to pick up
|
<!--Using a description element makes it easier for tools to pick up
|
||||||
documentation of the bean configuration-->
|
documentation of the bean configuration-->
|
||||||
<description>
|
<description>
|
||||||
This file configures the various service beans.
|
This file configures the various service beans.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<!--You can also put a description element in a bean-->
|
<!--You can also put a description element in a bean-->
|
||||||
<bean id="baseService" abstract="true">
|
<bean id="baseService" abstract="true">
|
||||||
<description>
|
<description>
|
||||||
This bean defines base properties common to the service beans
|
This bean defines base properties common to the service beans
|
||||||
</description>
|
</description>
|
||||||
...
|
...
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="shippingService"
|
<bean id="shippingService"
|
||||||
class="documentation.examples.spring.ShippingService"
|
class="documentation.examples.spring.ShippingService"
|
||||||
parent="baseService">
|
parent="baseService">
|
||||||
...
|
...
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="orderService"
|
<bean id="orderService"
|
||||||
class="documentation.examples.spring.OrderService"
|
class="documentation.examples.spring.OrderService"
|
||||||
parent="baseService">
|
parent="baseService">
|
||||||
...
|
...
|
||||||
</bean>
|
</bean>
|
||||||
</beans>
|
</beans>
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
<!--AVOID: Using the 'name' attribute disables checking of bean references at XML parse time-->
|
<!--AVOID: Using the 'name' attribute disables checking of bean references at XML parse time-->
|
||||||
<bean name="dao" class="documentation.examples.spring.DAO"/>
|
<bean name="dao" class="documentation.examples.spring.DAO"/>
|
||||||
|
|
||||||
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
||||||
<!--The XML parser cannot catch this typo-->
|
<!--The XML parser cannot catch this typo-->
|
||||||
<property name="dao" ref="da0"/>
|
<property name="dao" ref="da0"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<!--GOOD: Using the 'id' attribute enables checking of bean references at XML parse time-->
|
<!--GOOD: Using the 'id' attribute enables checking of bean references at XML parse time-->
|
||||||
<bean id="dao" class="documentation.examples.spring.DAO"/>
|
<bean id="dao" class="documentation.examples.spring.DAO"/>
|
||||||
|
|
||||||
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
||||||
<!--The XML parser can catch this typo-->
|
<!--The XML parser can catch this typo-->
|
||||||
<property name="dao" ref="da0"/>
|
<property name="dao" ref="da0"/>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
<beans>
|
<beans>
|
||||||
<bean id="shippingService" class="documentation.examples.spring.ShippingService">
|
<bean id="shippingService" class="documentation.examples.spring.ShippingService">
|
||||||
<!--AVOID: This form of reference cannot be checked by the XML parser-->
|
<!--AVOID: This form of reference cannot be checked by the XML parser-->
|
||||||
<property name="dao">
|
<property name="dao">
|
||||||
<ref bean="dao"/>
|
<ref bean="dao"/>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
<bean id="orderService" class="documentation.examples.spring.OrderService">
|
||||||
<!--GOOD: This form of reference allows the XML parser to find any errors at parse time-->
|
<!--GOOD: This form of reference allows the XML parser to find any errors at parse time-->
|
||||||
<property name="dao">
|
<property name="dao">
|
||||||
<idref local="dao"/>
|
<idref local="dao"/>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="dao" class="documentation.examples.spring.DAO"/>
|
<bean id="dao" class="documentation.examples.spring.DAO"/>
|
||||||
</beans>
|
</beans>
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
// Class for bean 'chart1'
|
// Class for bean 'chart1'
|
||||||
public class WrongChartMaker {
|
public class WrongChartMaker {
|
||||||
private AxisRenderer axisRenderer = new DefaultAxisRenderer();
|
private AxisRenderer axisRenderer = new DefaultAxisRenderer();
|
||||||
private TrendRenderer trendRenderer = new DefaultTrendRenderer();
|
private TrendRenderer trendRenderer = new DefaultTrendRenderer();
|
||||||
|
|
||||||
public WrongChartMaker() {}
|
public WrongChartMaker() {}
|
||||||
|
|
||||||
// Each combination of the optional parameters must be represented by a constructor.
|
// Each combination of the optional parameters must be represented by a constructor.
|
||||||
public WrongChartMaker(AxisRenderer customAxisRenderer) {
|
public WrongChartMaker(AxisRenderer customAxisRenderer) {
|
||||||
this.axisRenderer = customAxisRenderer;
|
this.axisRenderer = customAxisRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WrongChartMaker(TrendRenderer customTrendRenderer) {
|
public WrongChartMaker(TrendRenderer customTrendRenderer) {
|
||||||
this.trendRenderer = customTrendRenderer;
|
this.trendRenderer = customTrendRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WrongChartMaker(AxisRenderer customAxisRenderer,
|
public WrongChartMaker(AxisRenderer customAxisRenderer,
|
||||||
TrendRenderer customTrendRenderer) {
|
TrendRenderer customTrendRenderer) {
|
||||||
this.axisRenderer = customAxisRenderer;
|
this.axisRenderer = customAxisRenderer;
|
||||||
this.trendRenderer = customTrendRenderer;
|
this.trendRenderer = customTrendRenderer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,38 +1,38 @@
|
|||||||
<!--AVOID: Using nested 'value' elements can make the configuration file difficult to read-->
|
<!--AVOID: Using nested 'value' elements can make the configuration file difficult to read-->
|
||||||
<bean id="serviceRegistry" class="documentation.examples.spring.ServiceRegistry">
|
<bean id="serviceRegistry" class="documentation.examples.spring.ServiceRegistry">
|
||||||
<constructor-arg type="java.lang.String">
|
<constructor-arg type="java.lang.String">
|
||||||
<value>main_service_registry</value>
|
<value>main_service_registry</value>
|
||||||
</constructor-arg>
|
</constructor-arg>
|
||||||
<property name="description">
|
<property name="description">
|
||||||
<value>Top-level registry for services</value>
|
<value>Top-level registry for services</value>
|
||||||
</property>
|
</property>
|
||||||
<property name="serviceMap">
|
<property name="serviceMap">
|
||||||
<map>
|
<map>
|
||||||
<entry>
|
<entry>
|
||||||
<key>
|
<key>
|
||||||
<value>orderService</value>
|
<value>orderService</value>
|
||||||
</key>
|
</key>
|
||||||
<value>com.foo.bar.OrderService</value>
|
<value>com.foo.bar.OrderService</value>
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
<key>
|
<key>
|
||||||
<value>billingService</value>
|
<value>billingService</value>
|
||||||
</key>
|
</key>
|
||||||
<value>com.foo.bar.BillingService</value>
|
<value>com.foo.bar.BillingService</value>
|
||||||
</entry>
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<!--GOOD: Shortcut forms (Spring 1.2) result in more concise bean definitions-->
|
<!--GOOD: Shortcut forms (Spring 1.2) result in more concise bean definitions-->
|
||||||
<bean id="serviceRegistry" class="documentation.examples.spring.ServiceRegistry">
|
<bean id="serviceRegistry" class="documentation.examples.spring.ServiceRegistry">
|
||||||
<constructor-arg type="java.lang.String" value="main_service_registry"/>
|
<constructor-arg type="java.lang.String" value="main_service_registry"/>
|
||||||
<property name="description" value="Top-level registry for services"/>
|
<property name="description" value="Top-level registry for services"/>
|
||||||
<property name="serviceMap">
|
<property name="serviceMap">
|
||||||
<map>
|
<map>
|
||||||
<entry key="orderService" value="com.foo.bar.OrderService"/>
|
<entry key="orderService" value="com.foo.bar.OrderService"/>
|
||||||
<entry key="billingService" value="com.foo.bar.BillingService"/>
|
<entry key="billingService" value="com.foo.bar.BillingService"/>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// bean class
|
// bean class
|
||||||
public class ContentService {
|
public class ContentService {
|
||||||
private TransactionHelper helper;
|
private TransactionHelper helper;
|
||||||
|
|
||||||
// This method does not match the property in the bean file.
|
// This method does not match the property in the bean file.
|
||||||
public void setHelper(TransactionHelper helper) {
|
public void setHelper(TransactionHelper helper) {
|
||||||
this.helper = helper;
|
this.helper = helper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<bean id="contentService" class="documentation.examples.spring.ContentService">
|
<bean id="contentService" class="documentation.examples.spring.ContentService">
|
||||||
<!--BAD: The setter method in the class is 'setHelper', so this property
|
<!--BAD: The setter method in the class is 'setHelper', so this property
|
||||||
does not match the setter method.-->
|
does not match the setter method.-->
|
||||||
<property name="transactionHelper">
|
<property name="transactionHelper">
|
||||||
<ref bean="transactionHelper"/>
|
<ref bean="transactionHelper"/>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
|
|
||||||
// BAD: 'mayBeNegativeInt' is negative if
|
// BAD: 'mayBeNegativeInt' is negative if
|
||||||
// 'nextInt()' returns 'Integer.MIN_VALUE'.
|
// 'nextInt()' returns 'Integer.MIN_VALUE'.
|
||||||
int mayBeNegativeInt = Math.abs(r.nextInt());
|
int mayBeNegativeInt = Math.abs(r.nextInt());
|
||||||
|
|
||||||
// GOOD: 'nonNegativeInt' is always a value between 0 (inclusive)
|
// GOOD: 'nonNegativeInt' is always a value between 0 (inclusive)
|
||||||
// and Integer.MAX_VALUE (exclusive).
|
// and Integer.MAX_VALUE (exclusive).
|
||||||
int nonNegativeInt = r.nextInt(Integer.MAX_VALUE);
|
int nonNegativeInt = r.nextInt(Integer.MAX_VALUE);
|
||||||
|
|
||||||
// GOOD: When 'nextInt' returns a negative number increment the returned value.
|
// GOOD: When 'nextInt' returns a negative number increment the returned value.
|
||||||
int nextInt = r.nextInt();
|
int nextInt = r.nextInt();
|
||||||
if(nextInt < 0)
|
if(nextInt < 0)
|
||||||
nextInt++;
|
nextInt++;
|
||||||
int nonNegativeInt = Math.abs(nextInt);
|
int nonNegativeInt = Math.abs(nextInt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
// BAD: A new 'Random' object is created every time
|
// BAD: A new 'Random' object is created every time
|
||||||
// a pseudo-random integer is required.
|
// a pseudo-random integer is required.
|
||||||
int notReallyRandom = new Random().nextInt();
|
int notReallyRandom = new Random().nextInt();
|
||||||
int notReallyRandom2 = new Random().nextInt();
|
int notReallyRandom2 = new Random().nextInt();
|
||||||
|
|
||||||
// GOOD: The same 'Random' object is used to generate
|
// GOOD: The same 'Random' object is used to generate
|
||||||
// two pseudo-random integers.
|
// two pseudo-random integers.
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
int random1 = r.nextInt();
|
int random1 = r.nextInt();
|
||||||
int random2 = r.nextInt();
|
int random2 = r.nextInt();
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,30 @@
|
|||||||
class LocalCache {
|
class LocalCache {
|
||||||
private Collection<NativeResource> localResources;
|
private Collection<NativeResource> localResources;
|
||||||
|
|
||||||
//...
|
//...
|
||||||
|
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
for (NativeResource r : localResources) {
|
for (NativeResource r : localResources) {
|
||||||
r.dispose();
|
r.dispose();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrongCache extends LocalCache {
|
class WrongCache extends LocalCache {
|
||||||
//...
|
//...
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
// BAD: Empty 'finalize', which does not call 'super.finalize'.
|
// BAD: Empty 'finalize', which does not call 'super.finalize'.
|
||||||
// Native resources in LocalCache are not disposed of.
|
// Native resources in LocalCache are not disposed of.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RightCache extends LocalCache {
|
class RightCache extends LocalCache {
|
||||||
//...
|
//...
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
// GOOD: 'finalize' calls 'super.finalize'.
|
// GOOD: 'finalize' calls 'super.finalize'.
|
||||||
// Native resources in LocalCache are disposed of.
|
// Native resources in LocalCache are disposed of.
|
||||||
super.finalize();
|
super.finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
public class BadSuiteMethod extends TestCase {
|
public class BadSuiteMethod extends TestCase {
|
||||||
// BAD: JUnit 3.8 does not detect the following method as a 'suite' method.
|
// BAD: JUnit 3.8 does not detect the following method as a 'suite' method.
|
||||||
// The method should be public, static, and return 'junit.framework.Test'
|
// The method should be public, static, and return 'junit.framework.Test'
|
||||||
// or one of its subtypes.
|
// or one of its subtypes.
|
||||||
static Test suite() {
|
static Test suite() {
|
||||||
TestSuite suite = new TestSuite();
|
TestSuite suite = new TestSuite();
|
||||||
suite.addTest(new MyTests("testEquals"));
|
suite.addTest(new MyTests("testEquals"));
|
||||||
suite.addTest(new MyTests("testNotEquals"));
|
suite.addTest(new MyTests("testNotEquals"));
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CorrectSuiteMethod extends TestCase {
|
public class CorrectSuiteMethod extends TestCase {
|
||||||
// GOOD: JUnit 3.8 correctly detects the following method as a 'suite' method.
|
// GOOD: JUnit 3.8 correctly detects the following method as a 'suite' method.
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
TestSuite suite = new TestSuite();
|
TestSuite suite = new TestSuite();
|
||||||
suite.addTest(new MyTests("testEquals"));
|
suite.addTest(new MyTests("testEquals"));
|
||||||
suite.addTest(new MyTests("testNotEquals"));
|
suite.addTest(new MyTests("testNotEquals"));
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,65 +1,65 @@
|
|||||||
// Abstract class that initializes then shuts down the
|
// Abstract class that initializes then shuts down the
|
||||||
// framework after each set of tests
|
// framework after each set of tests
|
||||||
abstract class FrameworkTestCase extends TestCase {
|
abstract class FrameworkTestCase extends TestCase {
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
Framework.init();
|
Framework.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
Framework.shutdown();
|
Framework.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following classes extend 'FrameworkTestCase' to reuse the
|
// The following classes extend 'FrameworkTestCase' to reuse the
|
||||||
// 'setUp' and 'tearDown' methods of the framework.
|
// 'setUp' and 'tearDown' methods of the framework.
|
||||||
|
|
||||||
public class TearDownNoSuper extends FrameworkTestCase {
|
public class TearDownNoSuper extends FrameworkTestCase {
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFramework() {
|
public void testFramework() {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFramework2() {
|
public void testFramework2() {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
// BAD: Does not call 'super.tearDown'. May cause later tests to fail
|
// BAD: Does not call 'super.tearDown'. May cause later tests to fail
|
||||||
// when they try to re-initialize an already initialized framework.
|
// when they try to re-initialize an already initialized framework.
|
||||||
// Even if the framework allows re-initialization, it may maintain the
|
// Even if the framework allows re-initialization, it may maintain the
|
||||||
// internal state, which could affect the results of succeeding tests.
|
// internal state, which could affect the results of succeeding tests.
|
||||||
System.out.println("Tests complete");
|
System.out.println("Tests complete");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TearDownSuper extends FrameworkTestCase {
|
public class TearDownSuper extends FrameworkTestCase {
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFramework() {
|
public void testFramework() {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFramework2() {
|
public void testFramework2() {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
// GOOD: Correctly calls 'super.tearDown' to shut down the
|
// GOOD: Correctly calls 'super.tearDown' to shut down the
|
||||||
// framework.
|
// framework.
|
||||||
System.out.println("Tests complete");
|
System.out.println("Tests complete");
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,28 @@
|
|||||||
// BAD: This test case class does not have any valid JUnit 3.8 test methods.
|
// BAD: This test case class does not have any valid JUnit 3.8 test methods.
|
||||||
public class TestCaseNoTests38 extends TestCase {
|
public class TestCaseNoTests38 extends TestCase {
|
||||||
// This is not a test case because it does not start with 'test'.
|
// This is not a test case because it does not start with 'test'.
|
||||||
public void simpleTest() {
|
public void simpleTest() {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is not a test case because it takes two parameters.
|
// This is not a test case because it takes two parameters.
|
||||||
public void testNotEquals(int i, int j) {
|
public void testNotEquals(int i, int j) {
|
||||||
assertEquals(i != j, true);
|
assertEquals(i != j, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is recognized as a test, but causes JUnit to fail
|
// This is recognized as a test, but causes JUnit to fail
|
||||||
// when run because it is not public.
|
// when run because it is not public.
|
||||||
void testEquals() {
|
void testEquals() {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOOD: This test case class correctly declares test methods.
|
// GOOD: This test case class correctly declares test methods.
|
||||||
public class MyTests extends TestCase {
|
public class MyTests extends TestCase {
|
||||||
public void testEquals() {
|
public void testEquals() {
|
||||||
assertEquals(1, 1);
|
assertEquals(1, 1);
|
||||||
}
|
}
|
||||||
public void testNotEquals() {
|
public void testNotEquals() {
|
||||||
assertFalse(1 == 2);
|
assertFalse(1 == 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
String phrase = "I miss my home in Mississippi.";
|
String phrase = "I miss my home in Mississippi.";
|
||||||
|
|
||||||
// AVOID: Calling 'toLowerCase()' or 'toUpperCase()'
|
// AVOID: Calling 'toLowerCase()' or 'toUpperCase()'
|
||||||
// produces different results depending on what the default locale is.
|
// produces different results depending on what the default locale is.
|
||||||
System.out.println(phrase.toUpperCase());
|
System.out.println(phrase.toUpperCase());
|
||||||
System.out.println(phrase.toLowerCase());
|
System.out.println(phrase.toLowerCase());
|
||||||
|
|
||||||
// GOOD: Explicitly setting the locale when calling 'toLowerCase()' or
|
// GOOD: Explicitly setting the locale when calling 'toLowerCase()' or
|
||||||
// 'toUpperCase()' ensures that the resulting string is
|
// 'toUpperCase()' ensures that the resulting string is
|
||||||
// English, regardless of the default locale.
|
// English, regardless of the default locale.
|
||||||
System.out.println(phrase.toLowerCase(Locale.ENGLISH));
|
System.out.println(phrase.toLowerCase(Locale.ENGLISH));
|
||||||
System.out.println(phrase.toUpperCase(Locale.ENGLISH));
|
System.out.println(phrase.toUpperCase(Locale.ENGLISH));
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
class WrongNote implements Serializable {
|
class WrongNote implements Serializable {
|
||||||
// BAD: serialVersionUID must be static, final, and 'long'
|
// BAD: serialVersionUID must be static, final, and 'long'
|
||||||
private static final int serialVersionUID = 1;
|
private static final int serialVersionUID = 1;
|
||||||
|
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
class Note implements Serializable {
|
class Note implements Serializable {
|
||||||
// GOOD: serialVersionUID is of the correct type
|
// GOOD: serialVersionUID is of the correct type
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
class WrongNetRequest implements Serializable {
|
class WrongNetRequest implements Serializable {
|
||||||
// BAD: Does not match the exact signature required for a custom
|
// BAD: Does not match the exact signature required for a custom
|
||||||
// deserialization protocol. Will not be called during deserialization.
|
// deserialization protocol. Will not be called during deserialization.
|
||||||
void readObject(ObjectInputStream in) {
|
void readObject(ObjectInputStream in) {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: Does not match the exact signature required for a custom
|
// BAD: Does not match the exact signature required for a custom
|
||||||
// serialization protocol. Will not be called during serialization.
|
// serialization protocol. Will not be called during serialization.
|
||||||
protected void writeObject(ObjectOutputStream out) {
|
protected void writeObject(ObjectOutputStream out) {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NetRequest implements Serializable {
|
class NetRequest implements Serializable {
|
||||||
// GOOD: Signature for a custom deserialization implementation.
|
// GOOD: Signature for a custom deserialization implementation.
|
||||||
private void readObject(ObjectInputStream in) {
|
private void readObject(ObjectInputStream in) {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOOD: Signature for a custom serialization implementation.
|
// GOOD: Signature for a custom serialization implementation.
|
||||||
private void writeObject(ObjectOutputStream out) {
|
private void writeObject(ObjectOutputStream out) {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,37 @@
|
|||||||
class WrongMemo implements Externalizable {
|
class WrongMemo implements Externalizable {
|
||||||
private String memo;
|
private String memo;
|
||||||
|
|
||||||
// BAD: No public no-argument constructor is defined. Deserializing this object
|
// BAD: No public no-argument constructor is defined. Deserializing this object
|
||||||
// causes an 'InvalidClassException'.
|
// causes an 'InvalidClassException'.
|
||||||
|
|
||||||
public WrongMemo(String memo) {
|
public WrongMemo(String memo) {
|
||||||
this.memo = memo;
|
this.memo = memo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeExternal(ObjectOutput arg0) throws IOException {
|
public void writeExternal(ObjectOutput arg0) throws IOException {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Memo implements Externalizable {
|
class Memo implements Externalizable {
|
||||||
private String memo;
|
private String memo;
|
||||||
|
|
||||||
// GOOD: Declare a public no-argument constructor, which is used by the
|
// GOOD: Declare a public no-argument constructor, which is used by the
|
||||||
// serialization framework when the object is deserialized.
|
// serialization framework when the object is deserialized.
|
||||||
public Memo() {
|
public Memo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Memo(String memo) {
|
public Memo(String memo) {
|
||||||
this.memo = memo;
|
this.memo = memo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeExternal(ObjectOutput out) throws IOException {
|
public void writeExternal(ObjectOutput out) throws IOException {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,42 +1,42 @@
|
|||||||
class WrongItem {
|
class WrongItem {
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
// BAD: This class does not have a no-argument constructor, and throws an
|
// BAD: This class does not have a no-argument constructor, and throws an
|
||||||
// 'InvalidClassException' at runtime.
|
// 'InvalidClassException' at runtime.
|
||||||
|
|
||||||
public WrongItem(String name) {
|
public WrongItem(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrongSubItem extends WrongItem implements Serializable {
|
class WrongSubItem extends WrongItem implements Serializable {
|
||||||
public WrongSubItem() {
|
public WrongSubItem() {
|
||||||
super(null);
|
super(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WrongSubItem(String name) {
|
public WrongSubItem(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Item {
|
class Item {
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
// GOOD: This class declares a no-argument constructor, which allows serializable
|
// GOOD: This class declares a no-argument constructor, which allows serializable
|
||||||
// subclasses to be deserialized without error.
|
// subclasses to be deserialized without error.
|
||||||
public Item() {}
|
public Item() {}
|
||||||
|
|
||||||
public Item(String name) {
|
public Item(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SubItem extends Item implements Serializable {
|
class SubItem extends Item implements Serializable {
|
||||||
public SubItem() {
|
public SubItem() {
|
||||||
super(null);
|
super(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubItem(String name) {
|
public SubItem(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
// BAD: This is not serializable, and throws a 'java.io.NotSerializableException'
|
// BAD: This is not serializable, and throws a 'java.io.NotSerializableException'
|
||||||
// when used in a serializable sorted collection.
|
// when used in a serializable sorted collection.
|
||||||
class WrongComparator implements Comparator<String> {
|
class WrongComparator implements Comparator<String> {
|
||||||
public int compare(String o1, String o2) {
|
public int compare(String o1, String o2) {
|
||||||
return o1.compareTo(o2);
|
return o1.compareTo(o2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOOD: This is serializable, and can be used in collections that are meant to be serialized.
|
// GOOD: This is serializable, and can be used in collections that are meant to be serialized.
|
||||||
class StringComparator implements Comparator<String>, Serializable {
|
class StringComparator implements Comparator<String>, Serializable {
|
||||||
private static final long serialVersionUID = -5972458403679726498L;
|
private static final long serialVersionUID = -5972458403679726498L;
|
||||||
|
|
||||||
public int compare(String arg0, String arg1) {
|
public int compare(String arg0, String arg1) {
|
||||||
return arg0.compareTo(arg1);
|
return arg0.compareTo(arg1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
class DerivedFactors { // Class that contains derived values computed from entries in a
|
class DerivedFactors { // Class that contains derived values computed from entries in a
|
||||||
private Number efficiency; // performance record
|
private Number efficiency; // performance record
|
||||||
private Number costPerItem;
|
private Number costPerItem;
|
||||||
private Number profitPerItem;
|
private Number profitPerItem;
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrongPerformanceRecord implements Serializable {
|
class WrongPerformanceRecord implements Serializable {
|
||||||
private String unitId;
|
private String unitId;
|
||||||
private Number dailyThroughput;
|
private Number dailyThroughput;
|
||||||
private Number dailyCost;
|
private Number dailyCost;
|
||||||
private DerivedFactors factors; // BAD: 'DerivedFactors' is not serializable
|
private DerivedFactors factors; // BAD: 'DerivedFactors' is not serializable
|
||||||
// but is in a serializable class. This
|
// but is in a serializable class. This
|
||||||
// causes a 'java.io.NotSerializableException'
|
// causes a 'java.io.NotSerializableException'
|
||||||
// when 'WrongPerformanceRecord' is serialized.
|
// when 'WrongPerformanceRecord' is serialized.
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
class PerformanceRecord implements Serializable {
|
class PerformanceRecord implements Serializable {
|
||||||
private String unitId;
|
private String unitId;
|
||||||
private Number dailyThroughput;
|
private Number dailyThroughput;
|
||||||
private Number dailyCost;
|
private Number dailyCost;
|
||||||
transient private DerivedFactors factors; // GOOD: 'DerivedFactors' is declared
|
transient private DerivedFactors factors; // GOOD: 'DerivedFactors' is declared
|
||||||
// 'transient' so it does not contribute to the
|
// 'transient' so it does not contribute to the
|
||||||
// serializable state of 'PerformanceRecord'.
|
// serializable state of 'PerformanceRecord'.
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
class WrongPair<L, R> implements Serializable{
|
class WrongPair<L, R> implements Serializable{
|
||||||
private final L left; // BAD
|
private final L left; // BAD
|
||||||
private final R right; // BAD: L and R are not guaranteed to be serializable
|
private final R right; // BAD: L and R are not guaranteed to be serializable
|
||||||
|
|
||||||
public WrongPair(L left, R right){ ... }
|
public WrongPair(L left, R right){ ... }
|
||||||
|
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
class Pair<L extends Serializable, R extends Serializable> implements Serializable{
|
class Pair<L extends Serializable, R extends Serializable> implements Serializable{
|
||||||
private final L left; // GOOD: L and R must implement Serializable
|
private final L left; // GOOD: L and R must implement Serializable
|
||||||
private final R right;
|
private final R right;
|
||||||
|
|
||||||
public Pair(L left, R right){ ... }
|
public Pair(L left, R right){ ... }
|
||||||
|
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrongEvent implements Serializable{
|
class WrongEvent implements Serializable{
|
||||||
private Object eventData; // BAD: Type is too general.
|
private Object eventData; // BAD: Type is too general.
|
||||||
|
|
||||||
public WrongEvent(Object eventData){ ... }
|
public WrongEvent(Object eventData){ ... }
|
||||||
}
|
}
|
||||||
|
|
||||||
class Event implements Serializable{
|
class Event implements Serializable{
|
||||||
private Serializable eventData; // GOOD: Force the user to supply only serializable data
|
private Serializable eventData; // GOOD: Force the user to supply only serializable data
|
||||||
|
|
||||||
public Event(Serializable eventData){ ... }
|
public Event(Serializable eventData){ ... }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
class NonSerializableServer {
|
class NonSerializableServer {
|
||||||
|
|
||||||
// BAD: The following class is serializable, but the enclosing class
|
// BAD: The following class is serializable, but the enclosing class
|
||||||
// 'NonSerializableServer' is not. Serializing an instance of 'WrongSession'
|
// 'NonSerializableServer' is not. Serializing an instance of 'WrongSession'
|
||||||
// causes a 'java.io.NotSerializableException'.
|
// causes a 'java.io.NotSerializableException'.
|
||||||
class WrongSession implements Serializable {
|
class WrongSession implements Serializable {
|
||||||
private static final long serialVersionUID = 8970783971992397218L;
|
private static final long serialVersionUID = 8970783971992397218L;
|
||||||
private int id;
|
private int id;
|
||||||
private String user;
|
private String user;
|
||||||
|
|
||||||
WrongSession(int id, String user) { /*...*/ }
|
WrongSession(int id, String user) { /*...*/ }
|
||||||
}
|
}
|
||||||
|
|
||||||
public WrongSession getNewSession(String user) {
|
public WrongSession getNewSession(String user) {
|
||||||
return new WrongSession(newId(), user);
|
return new WrongSession(newId(), user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
|
|
||||||
// GOOD: The following class can be correctly serialized because it is static.
|
// GOOD: The following class can be correctly serialized because it is static.
|
||||||
static class Session implements Serializable {
|
static class Session implements Serializable {
|
||||||
private static final long serialVersionUID = 1065454318648105638L;
|
private static final long serialVersionUID = 1065454318648105638L;
|
||||||
private int id;
|
private int id;
|
||||||
private String user;
|
private String user;
|
||||||
|
|
||||||
Session(int id, String user) { /*...*/ }
|
Session(int id, String user) { /*...*/ }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Session getNewSession(String user) {
|
public Session getNewSession(String user) {
|
||||||
return new Session(newId(), user);
|
return new Session(newId(), user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,40 +1,40 @@
|
|||||||
class FalseSingleton implements Serializable {
|
class FalseSingleton implements Serializable {
|
||||||
private static final long serialVersionUID = -7480651116825504381L;
|
private static final long serialVersionUID = -7480651116825504381L;
|
||||||
private static FalseSingleton instance;
|
private static FalseSingleton instance;
|
||||||
|
|
||||||
private FalseSingleton() {}
|
private FalseSingleton() {}
|
||||||
|
|
||||||
public static FalseSingleton getInstance() {
|
public static FalseSingleton getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new FalseSingleton();
|
instance = new FalseSingleton();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BAD: Signature of 'readResolve' does not match the exact signature that is expected
|
// BAD: Signature of 'readResolve' does not match the exact signature that is expected
|
||||||
// (that is, it does not return 'java.lang.Object').
|
// (that is, it does not return 'java.lang.Object').
|
||||||
public FalseSingleton readResolve() throws ObjectStreamException {
|
public FalseSingleton readResolve() throws ObjectStreamException {
|
||||||
return FalseSingleton.getInstance();
|
return FalseSingleton.getInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Singleton implements Serializable {
|
class Singleton implements Serializable {
|
||||||
private static final long serialVersionUID = -7480651116825504381L;
|
private static final long serialVersionUID = -7480651116825504381L;
|
||||||
private static Singleton instance;
|
private static Singleton instance;
|
||||||
|
|
||||||
private Singleton() {}
|
private Singleton() {}
|
||||||
|
|
||||||
public static Singleton getInstance() {
|
public static Singleton getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new Singleton();
|
instance = new Singleton();
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOOD: Signature of 'readResolve' matches the exact signature that is expected.
|
// GOOD: Signature of 'readResolve' matches the exact signature that is expected.
|
||||||
// It replaces the singleton that is read from a stream with an instance of 'Singleton',
|
// It replaces the singleton that is read from a stream with an instance of 'Singleton',
|
||||||
// instead of creating a new singleton.
|
// instead of creating a new singleton.
|
||||||
private Object readResolve() throws ObjectStreamException {
|
private Object readResolve() throws ObjectStreamException {
|
||||||
return Singleton.getInstance();
|
return Singleton.getInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
class State {
|
class State {
|
||||||
// The 'transient' modifier has no effect here because
|
// The 'transient' modifier has no effect here because
|
||||||
// the 'State' class does not implement 'Serializable'.
|
// the 'State' class does not implement 'Serializable'.
|
||||||
private transient int[] stateData;
|
private transient int[] stateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PersistentState implements Serializable {
|
class PersistentState implements Serializable {
|
||||||
private int[] stateData;
|
private int[] stateData;
|
||||||
// The 'transient' modifier indicates that this field is not part of
|
// The 'transient' modifier indicates that this field is not part of
|
||||||
// the persistent state and should therefore not be serialized.
|
// the persistent state and should therefore not be serialized.
|
||||||
private transient int[] cachedComputedData;
|
private transient int[] cachedComputedData;
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
class FinalizedClass {
|
class FinalizedClass {
|
||||||
Object o = new Object();
|
Object o = new Object();
|
||||||
String s = "abcdefg";
|
String s = "abcdefg";
|
||||||
Integer i = Integer.valueOf(2);
|
Integer i = Integer.valueOf(2);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
super.finalize();
|
super.finalize();
|
||||||
//No need to nullify fields
|
//No need to nullify fields
|
||||||
this.o = null;
|
this.o = null;
|
||||||
this.s = null;
|
this.s = null;
|
||||||
this.i = null;
|
this.i = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
synchronized void waitIfAutoSyncScheduled() {
|
synchronized void waitIfAutoSyncScheduled() {
|
||||||
try {
|
try {
|
||||||
while (isAutoSyncScheduled) {
|
while (isAutoSyncScheduled) {
|
||||||
this.wait(1000);
|
this.wait(1000);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// Expected exception. The file cannot be synchronized yet.
|
// Expected exception. The file cannot be synchronized yet.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
// Exception is passed to 'ignore' method with a comment
|
// Exception is passed to 'ignore' method with a comment
|
||||||
synchronized void waitIfAutoSyncScheduled() {
|
synchronized void waitIfAutoSyncScheduled() {
|
||||||
try {
|
try {
|
||||||
while (isAutoSyncScheduled) {
|
while (isAutoSyncScheduled) {
|
||||||
this.wait(1000);
|
this.wait(1000);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Exceptions.ignore(e, "Expected exception. The file cannot be synchronized yet.");
|
Exceptions.ignore(e, "Expected exception. The file cannot be synchronized yet.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// 'ignore' method. This method does nothing, but can be called
|
// 'ignore' method. This method does nothing, but can be called
|
||||||
// to document the reason why the exception can be ignored.
|
// to document the reason why the exception can be ignored.
|
||||||
public static void ignore(Throwable e, String message) {
|
public static void ignore(Throwable e, String message) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
void main() {
|
void main() {
|
||||||
// ...
|
// ...
|
||||||
// BAD: Call to 'runFinalizersOnExit' forces execution of all finalizers on termination of
|
// BAD: Call to 'runFinalizersOnExit' forces execution of all finalizers on termination of
|
||||||
// the runtime, which can cause live objects to transition to an invalid state.
|
// the runtime, which can cause live objects to transition to an invalid state.
|
||||||
// Avoid using this method (and finalizers in general).
|
// Avoid using this method (and finalizers in general).
|
||||||
System.runFinalizersOnExit(true);
|
System.runFinalizersOnExit(true);
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
String name = "John Doe";
|
String name = "John Doe";
|
||||||
|
|
||||||
// BAD: Unnecessary call to 'toString' on 'name'
|
// BAD: Unnecessary call to 'toString' on 'name'
|
||||||
System.out.println("Hi, my name is " + name.toString());
|
System.out.println("Hi, my name is " + name.toString());
|
||||||
|
|
||||||
// GOOD: No call to 'toString' on 'name'
|
// GOOD: No call to 'toString' on 'name'
|
||||||
System.out.println("Hi, my name is " + name);
|
System.out.println("Hi, my name is " + name);
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
// This class does not have a 'toString' method, so 'java.lang.Object.toString'
|
// This class does not have a 'toString' method, so 'java.lang.Object.toString'
|
||||||
// is used when the class is converted to a string.
|
// is used when the class is converted to a string.
|
||||||
class WrongPerson {
|
class WrongPerson {
|
||||||
private String name;
|
private String name;
|
||||||
private Date birthDate;
|
private Date birthDate;
|
||||||
|
|
||||||
public WrongPerson(String name, Date birthDate) {
|
public WrongPerson(String name, Date birthDate) {
|
||||||
this.name =name;
|
this.name =name;
|
||||||
this.birthDate = birthDate;
|
this.birthDate = birthDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String args[]) throws Exception {
|
public static void main(String args[]) throws Exception {
|
||||||
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
|
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
WrongPerson wp = new WrongPerson("Robert Van Winkle", dateFormatter.parse("1967-10-31"));
|
WrongPerson wp = new WrongPerson("Robert Van Winkle", dateFormatter.parse("1967-10-31"));
|
||||||
|
|
||||||
// BAD: The following statement implicitly calls 'Object.toString',
|
// BAD: The following statement implicitly calls 'Object.toString',
|
||||||
// which returns something similar to:
|
// which returns something similar to:
|
||||||
// WrongPerson@4383f74d
|
// WrongPerson@4383f74d
|
||||||
System.out.println(wp);
|
System.out.println(wp);
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
class RequestHandler extends Thread {
|
class RequestHandler extends Thread {
|
||||||
private boolean isRunning;
|
private boolean isRunning;
|
||||||
private Connection conn = new Connection();
|
private Connection conn = new Connection();
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
while (isRunning) {
|
while (isRunning) {
|
||||||
Request req = conn.getRequest();
|
Request req = conn.getRequest();
|
||||||
// Process the request ...
|
// Process the request ...
|
||||||
|
|
||||||
System.gc(); // This call may cause a garbage collection after each request.
|
System.gc(); // This call may cause a garbage collection after each request.
|
||||||
// This will likely reduce the throughput of the RequestHandler
|
// This will likely reduce the throughput of the RequestHandler
|
||||||
// because the JVM spends time on unnecessary garbage collection passes.
|
// because the JVM spends time on unnecessary garbage collection passes.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
String[] words = {"Who", "is", "John", "Galt"};
|
String[] words = {"Who", "is", "John", "Galt"};
|
||||||
String[][] wordMatrix = {{"There", "is"}, {"no", "spoon"}};
|
String[][] wordMatrix = {{"There", "is"}, {"no", "spoon"}};
|
||||||
|
|
||||||
// BAD: This implicitly uses 'Object.toString' to convert the contents
|
// BAD: This implicitly uses 'Object.toString' to convert the contents
|
||||||
// of 'words[]', and prints out something similar to:
|
// of 'words[]', and prints out something similar to:
|
||||||
// [Ljava.lang.String;@459189e1
|
// [Ljava.lang.String;@459189e1
|
||||||
System.out.println(words);
|
System.out.println(words);
|
||||||
|
|
||||||
// GOOD: 'Arrays.toString' calls 'toString' on
|
// GOOD: 'Arrays.toString' calls 'toString' on
|
||||||
// each of the array's elements. The statement prints out:
|
// each of the array's elements. The statement prints out:
|
||||||
// [Who, is, John, Galt]
|
// [Who, is, John, Galt]
|
||||||
System.out.println(Arrays.toString(words));
|
System.out.println(Arrays.toString(words));
|
||||||
|
|
||||||
// ALMOST RIGHT: This calls 'toString' on each of the multi-dimensional
|
// ALMOST RIGHT: This calls 'toString' on each of the multi-dimensional
|
||||||
// array's elements. However, because the elements are arrays, the statement
|
// array's elements. However, because the elements are arrays, the statement
|
||||||
// prints out something similar to:
|
// prints out something similar to:
|
||||||
// [[Ljava.lang.String;@55f33675, [Ljava.lang.String;@527c6768]]
|
// [[Ljava.lang.String;@55f33675, [Ljava.lang.String;@527c6768]]
|
||||||
System.out.println(Arrays.toString(wordMatrix));
|
System.out.println(Arrays.toString(wordMatrix));
|
||||||
|
|
||||||
// GOOD: This properly prints out the contents of the multi-dimensional array:
|
// GOOD: This properly prints out the contents of the multi-dimensional array:
|
||||||
// [[There, is], [no, spoon]]
|
// [[There, is], [no, spoon]]
|
||||||
System.out.println(Arrays.deepToString(wordMatrix));
|
System.out.println(Arrays.deepToString(wordMatrix));
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?eclipse version="3.2"?>
|
<?eclipse version="3.2"?>
|
||||||
<plugin>
|
<plugin>
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="semmlecode-queries"/>
|
<name value="semmlecode-queries"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.java.library"/>
|
<name value="com.semmle.code.java.library"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.java.dbscheme"/>
|
<name value="com.semmle.code.java.dbscheme"/>
|
||||||
<path value="/config/semmlecode.dbscheme"/>
|
<path value="/config/semmlecode.dbscheme"/>
|
||||||
</extension>
|
</extension>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
1
java/ql/test/library-tests/comments/.gitattributes
vendored
Normal file
1
java/ql/test/library-tests/comments/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
TestWindows.java eol=crlf
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* A JavaDoc comment
|
* A JavaDoc comment
|
||||||
* with multiple lines.
|
* with multiple lines.
|
||||||
*/
|
*/
|
||||||
class TestWindows {
|
class TestWindows {
|
||||||
/** A JavaDoc comment with a single line. */
|
/** A JavaDoc comment with a single line. */
|
||||||
void m() {
|
void m() {
|
||||||
// a single-line comment
|
// a single-line comment
|
||||||
// another single-line comment
|
// another single-line comment
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A block comment
|
/* A block comment
|
||||||
* with multiple lines.
|
* with multiple lines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* A block comment with a single line. */
|
/* A block comment with a single line. */
|
||||||
|
|
||||||
// an end-of-line comment with a spurious trailing comment marker */
|
// an end-of-line comment with a spurious trailing comment marker */
|
||||||
// an end-of-line comment with trailing whitespace
|
// an end-of-line comment with trailing whitespace
|
||||||
//an end-of-line comment without a leading space
|
//an end-of-line comment without a leading space
|
||||||
void test() {} // an end-of-line comment with preceding code
|
void test() {} // an end-of-line comment with preceding code
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
public class CloseReaderTest {
|
public class CloseReaderTest {
|
||||||
public static String readPassword(File keyFile)
|
public static String readPassword(File keyFile)
|
||||||
{
|
{
|
||||||
// TODO: use Console.readPassword() when it's available.
|
// TODO: use Console.readPassword() when it's available.
|
||||||
System.out.print("Enter password for " + keyFile
|
System.out.print("Enter password for " + keyFile
|
||||||
+ " (password will not be hidden): ");
|
+ " (password will not be hidden): ");
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
BufferedReader stdin = new BufferedReader(new InputStreamReader(
|
BufferedReader stdin = new BufferedReader(new InputStreamReader(
|
||||||
System.in));
|
System.in));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return stdin.readLine();
|
return stdin.readLine();
|
||||||
} catch (IOException ex)
|
} catch (IOException ex)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
public class LoopVarReadTest {
|
public class LoopVarReadTest {
|
||||||
public static void testLoop()
|
public static void testLoop()
|
||||||
{
|
{
|
||||||
int x = 2;
|
int x = 2;
|
||||||
for (int y = 0; y < 10; y += x)
|
for (int y = 0; y < 10; y += x)
|
||||||
{
|
{
|
||||||
System.out.println("Foo");
|
System.out.println("Foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
int q = 10;
|
int q = 10;
|
||||||
|
|
||||||
System.out.println("foo");
|
System.out.println("foo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
|
||||||
public class SaveFileTest {
|
public class SaveFileTest {
|
||||||
public void saveFile(String path, String contentType,
|
public void saveFile(String path, String contentType,
|
||||||
long size, InputStream is) throws FileNotFoundException,
|
long size, InputStream is) throws FileNotFoundException,
|
||||||
IOException
|
IOException
|
||||||
{
|
{
|
||||||
|
|
||||||
String savePath = path;
|
String savePath = path;
|
||||||
if (path.startsWith("/"))
|
if (path.startsWith("/"))
|
||||||
{
|
{
|
||||||
savePath = path.substring(1);
|
savePath = path.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure uploads area exists for this weblog
|
// make sure uploads area exists for this weblog
|
||||||
File dirPath = new File("foo");
|
File dirPath = new File("foo");
|
||||||
File saveFile = new File(dirPath.getAbsolutePath() + File.separator
|
File saveFile = new File(dirPath.getAbsolutePath() + File.separator
|
||||||
+ savePath);
|
+ savePath);
|
||||||
|
|
||||||
byte[] buffer = new byte[8192];
|
byte[] buffer = new byte[8192];
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
OutputStream bos = null;
|
OutputStream bos = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bos = new FileOutputStream(saveFile);
|
bos = new FileOutputStream(saveFile);
|
||||||
while ((bytesRead = is.read(buffer, 0, 8192)) != -1)
|
while ((bytesRead = is.read(buffer, 0, 8192)) != -1)
|
||||||
{
|
{
|
||||||
bos.write(buffer, 0, bytesRead);
|
bos.write(buffer, 0, bytesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("The file has been written to ["
|
System.out.println("The file has been written to ["
|
||||||
+ saveFile.getAbsolutePath() + "]");
|
+ saveFile.getAbsolutePath() + "]");
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new IOException("ERROR uploading file", e);
|
throw new IOException("ERROR uploading file", e);
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bos.flush();
|
bos.flush();
|
||||||
bos.close();
|
bos.close();
|
||||||
} catch (Exception ignored)
|
} catch (Exception ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,86 +1,86 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
public class TestBreak {
|
public class TestBreak {
|
||||||
public void f()
|
public void f()
|
||||||
{
|
{
|
||||||
//loop breaks
|
//loop breaks
|
||||||
a:
|
a:
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
for (int q : new int[20])
|
for (int q : new int[20])
|
||||||
{
|
{
|
||||||
if (q == 1)
|
if (q == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
break a;
|
break a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int y = 12;
|
int y = 12;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (y == 1)
|
if (y == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (y == 2)
|
if (y == 2)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
y = y + 2;
|
y = y + 2;
|
||||||
} while (y == 1);
|
} while (y == 1);
|
||||||
y = 12;
|
y = 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
y = 13;
|
y = 13;
|
||||||
|
|
||||||
//switch breaks
|
//switch breaks
|
||||||
int x =12;
|
int x =12;
|
||||||
switch (x)
|
switch (x)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
case 2:
|
case 2:
|
||||||
x = x + 2;
|
x = x + 2;
|
||||||
y = y + 2;
|
y = y + 2;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
x = x + 3;
|
x = x + 3;
|
||||||
y = y + 4;
|
y = y + 4;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
x = x + 5;
|
x = x + 5;
|
||||||
y = y + 6;
|
y = y + 6;
|
||||||
default:
|
default:
|
||||||
x = y;
|
x = y;
|
||||||
y = x;
|
y = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
//no default
|
//no default
|
||||||
switch(x)
|
switch(x)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
x = 1;
|
x = 1;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
x = 2;
|
x = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +1,59 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
public class TestContinue {
|
public class TestContinue {
|
||||||
public void f()
|
public void f()
|
||||||
{
|
{
|
||||||
//loop breaks
|
//loop breaks
|
||||||
a:
|
a:
|
||||||
for (int p = 0; p < 10;)
|
for (int p = 0; p < 10;)
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
for (int q : new int[20])
|
for (int q : new int[20])
|
||||||
{
|
{
|
||||||
if (q == 1)
|
if (q == 1)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
} else if (q == 2)
|
} else if (q == 2)
|
||||||
{
|
{
|
||||||
continue a;
|
continue a;
|
||||||
}
|
}
|
||||||
q = 12;
|
q = 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int y = 12;
|
int y = 12;
|
||||||
while (y != 13)
|
while (y != 13)
|
||||||
{
|
{
|
||||||
if (y == 1)
|
if (y == 1)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (y == 2)
|
if (y == 2)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
y = y + 2;
|
y = y + 2;
|
||||||
} while (y == 1);
|
} while (y == 1);
|
||||||
y = 12;
|
y = 12;
|
||||||
}
|
}
|
||||||
y = 15;
|
y = 15;
|
||||||
}
|
}
|
||||||
y = 13;
|
y = 13;
|
||||||
while (y != 12)
|
while (y != 12)
|
||||||
{
|
{
|
||||||
if (y != 6)
|
if (y != 6)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,150 +1,150 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
public class TestFinally {
|
public class TestFinally {
|
||||||
public void f()
|
public void f()
|
||||||
{
|
{
|
||||||
int z = 12;
|
int z = 12;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("Try1");
|
System.out.println("Try1");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("Try1");
|
System.out.println("Try1");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Try2");
|
System.out.println("Try2");
|
||||||
} catch (Exception ex)
|
} catch (Exception ex)
|
||||||
{
|
{
|
||||||
System.out.println("Exception");
|
System.out.println("Exception");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("Finally");
|
System.out.println("Finally");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Finally2");
|
System.out.println("Finally2");
|
||||||
}
|
}
|
||||||
System.out.println("Try2");
|
System.out.println("Try2");
|
||||||
} catch (Exception ex)
|
} catch (Exception ex)
|
||||||
{
|
{
|
||||||
System.out.println("Exception");
|
System.out.println("Exception");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("Try1");
|
System.out.println("Try1");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Try2");
|
System.out.println("Try2");
|
||||||
} catch (Exception ex2)
|
} catch (Exception ex2)
|
||||||
{
|
{
|
||||||
System.out.println("Exception");
|
System.out.println("Exception");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("Finally");
|
System.out.println("Finally");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Finally2");
|
System.out.println("Finally2");
|
||||||
}
|
}
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("Finally");
|
System.out.println("Finally");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Finally2");
|
System.out.println("Finally2");
|
||||||
}
|
}
|
||||||
System.out.println("Foo");
|
System.out.println("Foo");
|
||||||
int y = 12 + 3;
|
int y = 12 + 3;
|
||||||
System.out.println("Bar");
|
System.out.println("Bar");
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
return;
|
return;
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("Try1");
|
System.out.println("Try1");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Try2");
|
System.out.println("Try2");
|
||||||
} catch (Exception ex)
|
} catch (Exception ex)
|
||||||
{
|
{
|
||||||
System.out.println("Exception");
|
System.out.println("Exception");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("Finally");
|
System.out.println("Finally");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Finally2");
|
System.out.println("Finally2");
|
||||||
}
|
}
|
||||||
int x = 1;
|
int x = 1;
|
||||||
System.out.println("Error: " + e);
|
System.out.println("Error: " + e);
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
int y = 12;
|
int y = 12;
|
||||||
System.out.println("Finally");
|
System.out.println("Finally");
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
}
|
}
|
||||||
z = z + 1;
|
z = z + 1;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("Try1");
|
System.out.println("Try1");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Try2");
|
System.out.println("Try2");
|
||||||
} catch (Exception ex)
|
} catch (Exception ex)
|
||||||
{
|
{
|
||||||
System.out.println("Exception");
|
System.out.println("Exception");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("Finally");
|
System.out.println("Finally");
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Finally2");
|
System.out.println("Finally2");
|
||||||
}
|
}
|
||||||
|
|
||||||
z = z + 2;
|
z = z + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,108 +1,108 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
public class TestFinallyBreakContinue {
|
public class TestFinallyBreakContinue {
|
||||||
public void f()
|
public void f()
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
a:
|
a:
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("finally");
|
System.out.println("finally");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("finally");
|
System.out.println("finally");
|
||||||
}
|
}
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
System.out.println("Exception");
|
System.out.println("Exception");
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("finally");
|
System.out.println("finally");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b:
|
b:
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (int i : new int[20])
|
for (int i : new int[20])
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
if (x == 1)
|
if (x == 1)
|
||||||
{
|
{
|
||||||
break b;
|
break b;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
continue b;
|
continue b;
|
||||||
}
|
}
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("finally");
|
System.out.println("finally");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
System.out.println("Exception");
|
System.out.println("Exception");
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
System.out.println("finally");
|
System.out.println("finally");
|
||||||
}
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,120 +1,120 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
public class TestLoopBranch {
|
public class TestLoopBranch {
|
||||||
int xx = 12;
|
int xx = 12;
|
||||||
int yy = 13;
|
int yy = 13;
|
||||||
|
|
||||||
public void f()
|
public void f()
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
int y = 2;
|
int y = 2;
|
||||||
System.out.println("foo");
|
System.out.println("foo");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
System.out.println("bar");
|
System.out.println("bar");
|
||||||
System.out.println("foobar");
|
System.out.println("foobar");
|
||||||
} while (x == 2);
|
} while (x == 2);
|
||||||
|
|
||||||
{
|
{
|
||||||
System.out.println("shazam");
|
System.out.println("shazam");
|
||||||
System.out.println("boogie");
|
System.out.println("boogie");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (x == 1)
|
while (x == 1)
|
||||||
{
|
{
|
||||||
System.out.println("wonderland");
|
System.out.println("wonderland");
|
||||||
System.out.println("shodan");
|
System.out.println("shodan");
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
System.out.println("rapture");
|
System.out.println("rapture");
|
||||||
y = x - 2;
|
y = x - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
|
|
||||||
for (int j : new int[20])
|
for (int j : new int[20])
|
||||||
{
|
{
|
||||||
System.out.println("Zero : " + j);
|
System.out.println("Zero : " + j);
|
||||||
j = j + x;
|
j = j + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y == -1)
|
if (y == -1)
|
||||||
{
|
{
|
||||||
System.out.println("i squared");
|
System.out.println("i squared");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x == 42)
|
if (x == 42)
|
||||||
{
|
{
|
||||||
System.out.println("rat");
|
System.out.println("rat");
|
||||||
x = 6 * 9;
|
x = 6 * 9;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
System.out.println("arr");
|
System.out.println("arr");
|
||||||
x = y * x;
|
x = y * x;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (x)
|
switch (x)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
case 2:
|
case 2:
|
||||||
x = x + 2;
|
x = x + 2;
|
||||||
y = y + 2;
|
y = y + 2;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
x = x + 3;
|
x = x + 3;
|
||||||
y = y + 4;
|
y = y + 4;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
x = x + 5;
|
x = x + 5;
|
||||||
y = y + 6;
|
y = y + 6;
|
||||||
default:
|
default:
|
||||||
x = y;
|
x = y;
|
||||||
y = x;
|
y = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
//no default
|
//no default
|
||||||
switch(x)
|
switch(x)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
x = 1;
|
x = 1;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
x = 2;
|
x = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Comparable<String> b = new Comparable<String>() {
|
Comparable<String> b = new Comparable<String>() {
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(String o)
|
public int compareTo(String o)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
b.compareTo("Foo");
|
b.compareTo("Foo");
|
||||||
|
|
||||||
x = x + y;
|
x = x + y;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestLoopBranch()
|
public TestLoopBranch()
|
||||||
{
|
{
|
||||||
xx = 33;
|
xx = 33;
|
||||||
yy = 44;
|
yy = 44;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestLoopBranch(int i)
|
public TestLoopBranch(int i)
|
||||||
{
|
{
|
||||||
xx = i;
|
xx = i;
|
||||||
yy = i;
|
yy = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,135 +1,135 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
public class TestThrow {
|
public class TestThrow {
|
||||||
private TestThrow() throws IOException
|
private TestThrow() throws IOException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void thrower() throws InvalidParameterException
|
private void thrower() throws InvalidParameterException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void f() throws Exception
|
public void f() throws Exception
|
||||||
{
|
{
|
||||||
int z = 0;
|
int z = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
} catch (RuntimeException e)
|
} catch (RuntimeException e)
|
||||||
{
|
{
|
||||||
z = 1;
|
z = 1;
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
z = 2;
|
z = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = -1;
|
z = -1;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
} else if (z == 2)
|
} else if (z == 2)
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
} else if (z == 3)
|
} else if (z == 3)
|
||||||
{
|
{
|
||||||
new TestThrow();
|
new TestThrow();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
thrower();
|
thrower();
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e)
|
} catch (RuntimeException e)
|
||||||
{
|
{
|
||||||
z = 1;
|
z = 1;
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
z = 2;
|
z = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = -1;
|
z = -1;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
else if (z == 2)
|
else if (z == 2)
|
||||||
{
|
{
|
||||||
new TestThrow();
|
new TestThrow();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
thrower();
|
thrower();
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e)
|
} catch (RuntimeException e)
|
||||||
{
|
{
|
||||||
z = 1;
|
z = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = -1;
|
z = -1;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
z = 1;
|
z = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
} else if (z == 2)
|
} else if (z == 2)
|
||||||
{
|
{
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
throw new IOException("Foo bar", null);
|
throw new IOException("Foo bar", null);
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e)
|
} catch (RuntimeException e)
|
||||||
{
|
{
|
||||||
z = 1;
|
z = 1;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
z = -2;
|
z = -2;
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
} else if (z == 2)
|
} else if (z == 2)
|
||||||
{
|
{
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
} else if (z == 3)
|
} else if (z == 3)
|
||||||
{
|
{
|
||||||
throw new IOException("Foo bar", null);
|
throw new IOException("Foo bar", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e)
|
} catch (IOException e)
|
||||||
{
|
{
|
||||||
z = 2;
|
z = 2;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
z = 3;
|
z = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z == 1)
|
if (z == 1)
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
z = -1;
|
z = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
package successors;
|
package successors;
|
||||||
|
|
||||||
public class TestTryCatch {
|
public class TestTryCatch {
|
||||||
public void f()
|
public void f()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("Foo");
|
System.out.println("Foo");
|
||||||
int y = 12 + 3;
|
int y = 12 + 3;
|
||||||
System.out.println("Bar");
|
System.out.println("Bar");
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
System.out.println("Error: " + e);
|
System.out.println("Error: " + e);
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
return;
|
return;
|
||||||
} finally
|
} finally
|
||||||
{
|
{
|
||||||
int y = 12;
|
int y = 12;
|
||||||
System.out.println("Finally");
|
System.out.println("Finally");
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
}
|
}
|
||||||
int z = 12;
|
int z = 12;
|
||||||
z = z + 1;
|
z = z + 1;
|
||||||
|
|
||||||
for (int q = 0; q < 10; q++)
|
for (int q = 0; q < 10; q++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.out.println("Foo");
|
System.out.println("Foo");
|
||||||
int y = 12 + 3;
|
int y = 12 + 3;
|
||||||
System.out.println("Bar");
|
System.out.println("Bar");
|
||||||
y = y + 1;
|
y = y + 1;
|
||||||
} catch (RuntimeException e)
|
} catch (RuntimeException e)
|
||||||
{
|
{
|
||||||
int x = 1;
|
int x = 1;
|
||||||
System.out.println("Error: " + e);
|
System.out.println("Error: " + e);
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
z = z + 2;
|
z = z + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
java/ql/test/query-tests/AlertSuppression/.gitattributes
vendored
Normal file
1
java/ql/test/query-tests/AlertSuppression/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
TestWindows.java eol=crlf
|
||||||
@@ -1,28 +1,28 @@
|
|||||||
class TestWindows {} // lgtm
|
class TestWindows {} // lgtm
|
||||||
// lgtm[java/confusing-method-name]
|
// lgtm[java/confusing-method-name]
|
||||||
// lgtm[java/confusing-method-name, java/non-short-circuit-evaluation]
|
// lgtm[java/confusing-method-name, java/non-short-circuit-evaluation]
|
||||||
// lgtm[@tag:exceptions]
|
// lgtm[@tag:exceptions]
|
||||||
// lgtm[@tag:exceptions,java/confusing-method-name]
|
// lgtm[@tag:exceptions,java/confusing-method-name]
|
||||||
// lgtm[@expires:2017-06-11]
|
// lgtm[@expires:2017-06-11]
|
||||||
// lgtm[java/confusing-method-name] does not seem confusing despite alert by lgtm
|
// lgtm[java/confusing-method-name] does not seem confusing despite alert by lgtm
|
||||||
// lgtm: blah blah
|
// lgtm: blah blah
|
||||||
// lgtm blah blah #falsepositive
|
// lgtm blah blah #falsepositive
|
||||||
//lgtm [java/confusing-method-name]
|
//lgtm [java/confusing-method-name]
|
||||||
/* lgtm */
|
/* lgtm */
|
||||||
// lgtm[]
|
// lgtm[]
|
||||||
// lgtmfoo
|
// lgtmfoo
|
||||||
//lgtm
|
//lgtm
|
||||||
// lgtm
|
// lgtm
|
||||||
// lgtm [java/confusing-method-name]
|
// lgtm [java/confusing-method-name]
|
||||||
// foolgtm[java/confusing-method-name]
|
// foolgtm[java/confusing-method-name]
|
||||||
// foolgtm
|
// foolgtm
|
||||||
// foo; lgtm
|
// foo; lgtm
|
||||||
// foo; lgtm[java/confusing-method-name]
|
// foo; lgtm[java/confusing-method-name]
|
||||||
// foo lgtm
|
// foo lgtm
|
||||||
// foo lgtm[java/confusing-method-name]
|
// foo lgtm[java/confusing-method-name]
|
||||||
// foo lgtm bar
|
// foo lgtm bar
|
||||||
// foo lgtm[java/confusing-method-name] bar
|
// foo lgtm[java/confusing-method-name] bar
|
||||||
// LGTM!
|
// LGTM!
|
||||||
// LGTM[java/confusing-method-name]
|
// LGTM[java/confusing-method-name]
|
||||||
//lgtm[java/confusing-method-name] and lgtm[java/non-short-circuit-evaluation]
|
//lgtm[java/confusing-method-name] and lgtm[java/non-short-circuit-evaluation]
|
||||||
//lgtm[java/confusing-method-name]; lgtm
|
//lgtm[java/confusing-method-name]; lgtm
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?eclipse version="3.2"?>
|
<?eclipse version="3.2"?>
|
||||||
<plugin>
|
<plugin>
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="semmlecode-javascript-queries"/>
|
<name value="semmlecode-javascript-queries"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.javascript.library"/>
|
<name value="com.semmle.code.javascript.library"/>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="com.semmle.plugin.qdt.ui.resources">
|
<extension point="com.semmle.plugin.qdt.ui.resources">
|
||||||
<name value="com.semmle.code.javascript.dbscheme"/>
|
<name value="com.semmle.code.javascript.dbscheme"/>
|
||||||
<path value="/semmlecode.javascript.dbscheme"/>
|
<path value="/semmlecode.javascript.dbscheme"/>
|
||||||
</extension>
|
</extension>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
Reference in New Issue
Block a user