Diff from job 43567

to job 43568

#
# computing time of first use
# Section 5.1, Figure 3
# Section 5.2, histograms in Figures 5-6
#
# author: Robert Dyer <rdyer@bgsu.edu>
#
# Copyright 2013-2016 Iowa State University, Bowling Green State University.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY IOWA STATE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL IOWA STATE UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of Iowa State University.
#
ProjectUses: output sum[string][time] of int;
FileUses: output sum[string][string][time] of int;

Diamond: map[string] of time;
BinaryLit: map[string] of time;
Assert: map[string] of time;
AnnotUse: map[string] of time;
AnnotDefine: map[string] of time;
Enums: map[string] of time;
EnhancedFor: map[string] of time;
GenDefField: map[string] of time;
GenDefMethod: map[string] of time;
GenDefType: map[string] of time;
GenWildcard: map[string] of time;
GenExtends: map[string] of time;
GenSuper: map[string] of time;
MultiCatch: map[string] of time;
SafeVarargs: map[string] of time;
TryResources: map[string] of time;
UnderscoreLit: map[string] of time;
Varargs: map[string] of time;
RepeatedAnnot: map[string] of time;
#
# computing time of first use
# Section 5.1, Figure 3
# Section 5.2, histograms in Figures 5-6
#
# author: Robert Dyer <rdyer@bgsu.edu>
#
# Copyright 2013-2016 Iowa State University, Bowling Green State University.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY IOWA STATE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL IOWA STATE UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of Iowa State University.
#
ProjectUses: output sum[string][time] of int;
FileUses: output sum[string][string][time] of int;

Diamond: map[string] of time;
BinaryLit: map[string] of time;
Assert: map[string] of time;
AnnotUse: map[string] of time;
AnnotDefine: map[string] of time;
Enums: map[string] of time;
EnhancedFor: map[string] of time;
GenDefField: map[string] of time;
GenDefMethod: map[string] of time;
GenDefType: map[string] of time;
GenWildcard: map[string] of time;
GenExtends: map[string] of time;
GenSuper: map[string] of time;
MultiCatch: map[string] of time;
SafeVarargs: map[string] of time;
TryResources: map[string] of time;
UnderscoreLit: map[string] of time;
Varargs: map[string] of time;
RepeatedAnnot: map[string] of time;
MethRefNew: map[string] of time;
MethRefSuper: map[string] of time;
MethRefExpr: map[string] of time;
DefaultMeth: map[string] of time;
RcvParam: map[string] of time;

Diamond2: map[string] of ChangeKind;
BinaryLit2: map[string] of ChangeKind;
Assert2: map[string] of ChangeKind;
AnnotUse2: map[string] of ChangeKind;
AnnotDefine2: map[string] of ChangeKind;
Enums2: map[string] of ChangeKind;
EnhancedFor2: map[string] of ChangeKind;
GenDefField2: map[string] of ChangeKind;
GenDefMethod2: map[string] of ChangeKind;
GenDefType2: map[string] of ChangeKind;
GenWildcard2: map[string] of ChangeKind;
GenExtends2: map[string] of ChangeKind;
GenSuper2: map[string] of ChangeKind;
MultiCatch2: map[string] of ChangeKind;
SafeVarargs2: map[string] of ChangeKind;
TryResources2: map[string] of ChangeKind;
UnderscoreLit2: map[string] of ChangeKind;
Varargs2: map[string] of ChangeKind;
RepeatedAnnot2: map[string] of ChangeKind;
RcvParam: map[string] of time;

Diamond2: map[string] of ChangeKind;
BinaryLit2: map[string] of ChangeKind;
Assert2: map[string] of ChangeKind;
AnnotUse2: map[string] of ChangeKind;
AnnotDefine2: map[string] of ChangeKind;
Enums2: map[string] of ChangeKind;
EnhancedFor2: map[string] of ChangeKind;
GenDefField2: map[string] of ChangeKind;
GenDefMethod2: map[string] of ChangeKind;
GenDefType2: map[string] of ChangeKind;
GenWildcard2: map[string] of ChangeKind;
GenExtends2: map[string] of ChangeKind;
GenSuper2: map[string] of ChangeKind;
MultiCatch2: map[string] of ChangeKind;
SafeVarargs2: map[string] of ChangeKind;
TryResources2: map[string] of ChangeKind;
UnderscoreLit2: map[string] of ChangeKind;
Varargs2: map[string] of ChangeKind;
RepeatedAnnot2: map[string] of ChangeKind;
MethRefNew2: map[string] of ChangeKind;
MethRefSuper2: map[string] of ChangeKind;
MethRefExpr2: map[string] of ChangeKind;
DefaultMeth2: map[string] of ChangeKind;
RcvParam2: map[string] of ChangeKind;

record_feature_use := function(fileMap: map[string] of time, kinds: map[string] of ChangeKind, commit_date: time, f: ChangedFile) {
if (haskey(fileMap, f.name))
return;

fileMap[f.name] = commit_date;
kinds[f.name] = f.change;
};

cur_date: time;
cur_file: ChangedFile;
in_field: bool;

visit(input, visitor {
before node: ChangedFile -> {
if (!iskind("SOURCE_JAVA_JLS", node.kind) || node.change == ChangeKind.DELETED)
stop;
cur_file = node;
}
before node: Revision ->
if (int(node.commit_date) < 1) stop;
else cur_date = node.commit_date;
before node: Declaration -> {
found1 := false;
s1: set of string;
foreach (i: int; node.modifiers[i])
if (contains(s1, node.modifiers[i].annotation_name))
found1 = true;
else
add(s1, node.modifiers[i].annotation_name);
if (found1)
record_feature_use(RepeatedAnnot, RepeatedAnnot2, cur_date, cur_file);
if (node.kind == TypeKind.ANNOTATION)
record_feature_use(AnnotDefine, AnnotDefine2, cur_date, cur_file);
if (len(node.generic_parameters) > 0)
record_feature_use(GenDefType, GenDefType2, cur_date, cur_file);
if (node.kind == TypeKind.ENUM)
record_feature_use(Enums, Enums2, cur_date, cur_file);

in_field = true;
foreach (i: int; def(node.fields[i]))
visit(node.fields[i]);
in_field = false;
}
before node: Type -> {
if (strfind("?", node.name) > -1 && !match(`\?\s*super\s+.+`, node.name) && !match(`\?\s*extends\s+.+`, node.name))
record_feature_use(GenWildcard, GenWildcard2, cur_date, cur_file);
if (match(`\?\s*extends\s+.+`, node.name))
record_feature_use(GenExtends, GenExtends2, cur_date, cur_file);
if (match(`\?\s*super\s+.+`, node.name))
record_feature_use(GenSuper, GenSuper2, cur_date, cur_file);
if (in_field && strfind("<", node.name) > -1)
record_feature_use(GenDefField, GenDefField2, cur_date, cur_file);
}
before node: Method -> {
found2 := false;
s2: set of string;
foreach (i: int; node.modifiers[i])
if (contains(s2, node.modifiers[i].annotation_name))
found2 = true;
else
add(s2, node.modifiers[i].annotation_name);
if (found2)
record_feature_use(RepeatedAnnot, RepeatedAnnot2, cur_date, cur_file);
if (len(node.arguments) > 0 && node.arguments[0].variable_type.name == "this")
record_feature_use(RcvParam, RcvParam2, cur_date, cur_file);
if (len(node.generic_parameters) > 0)
record_feature_use(GenDefMethod, GenDefMethod2, cur_date, cur_file);
# @SafeVarargs
if (has_annotation(node, "SafeVarargs")) {
record_feature_use(SafeVarargs, SafeVarargs2, cur_date, cur_file);
} else {
# @SuppressWarnings({"unchecked", "varargs"})
mod := get_annotation(node, "SuppressWarnings");
if (def(mod))
foreach (i: int; mod.annotation_members[i] == "value") {
e := mod.annotation_values[i];
if (e.kind == ExpressionKind.ARRAYINIT) {
foundUnchecked := false;
foundVarargs := false;
foreach (j: int; e.expressions[j].kind == ExpressionKind.LITERAL) {
if (e.expressions[j].literal == "unchecked")
foundUnchecked = true;
if (e.expressions[j].literal == "varargs")
foundVarargs = true;
}
if (foundUnchecked && foundVarargs)
record_feature_use(SafeVarargs, SafeVarargs2, cur_date, cur_file);
}
break;
}
}
if (len(node.arguments) > 0 && strfind("...", node.arguments[len(node.arguments) - 1].variable_type.name) > -1)
record_feature_use(Varargs, Varargs2, cur_date, cur_file);
}
before node: Variable -> {
found3 := false;
s3: set of string;
foreach (i: int; node.modifiers[i])
if (contains(s3, node.modifiers[i].annotation_name))
found3 = true;
else
add(s3, node.modifiers[i].annotation_name);
if (found3)
record_feature_use(RepeatedAnnot, RepeatedAnnot2, cur_date, cur_file);
}
before node: Statement -> {
switch (node.kind) {
case StatementKind.ASSERT:
record_feature_use(Assert, Assert2, cur_date, cur_file);
break;
case StatementKind.CATCH:
if (strfind("|", node.variable_declaration.variable_type.name) > -1)
record_feature_use(MultiCatch, MultiCatch2, cur_date, cur_file);
break;
case StatementKind.TRY:
if (len(node.initializations) > 0)
record_feature_use(TryResources, TryResources2, cur_date, cur_file);
break;
case StatementKind.FOR:
if (def(node.variable_declaration))
record_feature_use(EnhancedFor, EnhancedFor2, cur_date, cur_file);
break;
default:
break;
}
}
before node: Expression ->
RcvParam2: map[string] of ChangeKind;

record_feature_use := function(fileMap: map[string] of time, kinds: map[string] of ChangeKind, commit_date: time, f: ChangedFile) {
if (haskey(fileMap, f.name))
return;

fileMap[f.name] = commit_date;
kinds[f.name] = f.change;
};

cur_date: time;
cur_file: ChangedFile;
in_field: bool;

visit(input, visitor {
before node: ChangedFile -> {
if (!iskind("SOURCE_JAVA_JLS", node.kind) || node.change == ChangeKind.DELETED)
stop;
cur_file = node;
}
before node: Revision ->
if (int(node.commit_date) < 1) stop;
else cur_date = node.commit_date;
before node: Declaration -> {
found1 := false;
s1: set of string;
foreach (i: int; node.modifiers[i])
if (contains(s1, node.modifiers[i].annotation_name))
found1 = true;
else
add(s1, node.modifiers[i].annotation_name);
if (found1)
record_feature_use(RepeatedAnnot, RepeatedAnnot2, cur_date, cur_file);
if (node.kind == TypeKind.ANNOTATION)
record_feature_use(AnnotDefine, AnnotDefine2, cur_date, cur_file);
if (len(node.generic_parameters) > 0)
record_feature_use(GenDefType, GenDefType2, cur_date, cur_file);
if (node.kind == TypeKind.ENUM)
record_feature_use(Enums, Enums2, cur_date, cur_file);

in_field = true;
foreach (i: int; def(node.fields[i]))
visit(node.fields[i]);
in_field = false;
}
before node: Type -> {
if (strfind("?", node.name) > -1 && !match(`\?\s*super\s+.+`, node.name) && !match(`\?\s*extends\s+.+`, node.name))
record_feature_use(GenWildcard, GenWildcard2, cur_date, cur_file);
if (match(`\?\s*extends\s+.+`, node.name))
record_feature_use(GenExtends, GenExtends2, cur_date, cur_file);
if (match(`\?\s*super\s+.+`, node.name))
record_feature_use(GenSuper, GenSuper2, cur_date, cur_file);
if (in_field && strfind("<", node.name) > -1)
record_feature_use(GenDefField, GenDefField2, cur_date, cur_file);
}
before node: Method -> {
found2 := false;
s2: set of string;
foreach (i: int; node.modifiers[i])
if (contains(s2, node.modifiers[i].annotation_name))
found2 = true;
else
add(s2, node.modifiers[i].annotation_name);
if (found2)
record_feature_use(RepeatedAnnot, RepeatedAnnot2, cur_date, cur_file);
if (len(node.arguments) > 0 && node.arguments[0].variable_type.name == "this")
record_feature_use(RcvParam, RcvParam2, cur_date, cur_file);
if (len(node.generic_parameters) > 0)
record_feature_use(GenDefMethod, GenDefMethod2, cur_date, cur_file);
# @SafeVarargs
if (has_annotation(node, "SafeVarargs")) {
record_feature_use(SafeVarargs, SafeVarargs2, cur_date, cur_file);
} else {
# @SuppressWarnings({"unchecked", "varargs"})
mod := get_annotation(node, "SuppressWarnings");
if (def(mod))
foreach (i: int; mod.annotation_members[i] == "value") {
e := mod.annotation_values[i];
if (e.kind == ExpressionKind.ARRAYINIT) {
foundUnchecked := false;
foundVarargs := false;
foreach (j: int; e.expressions[j].kind == ExpressionKind.LITERAL) {
if (e.expressions[j].literal == "unchecked")
foundUnchecked = true;
if (e.expressions[j].literal == "varargs")
foundVarargs = true;
}
if (foundUnchecked && foundVarargs)
record_feature_use(SafeVarargs, SafeVarargs2, cur_date, cur_file);
}
break;
}
}
if (len(node.arguments) > 0 && strfind("...", node.arguments[len(node.arguments) - 1].variable_type.name) > -1)
record_feature_use(Varargs, Varargs2, cur_date, cur_file);
}
before node: Variable -> {
found3 := false;
s3: set of string;
foreach (i: int; node.modifiers[i])
if (contains(s3, node.modifiers[i].annotation_name))
found3 = true;
else
add(s3, node.modifiers[i].annotation_name);
if (found3)
record_feature_use(RepeatedAnnot, RepeatedAnnot2, cur_date, cur_file);
}
before node: Statement -> {
switch (node.kind) {
case StatementKind.ASSERT:
record_feature_use(Assert, Assert2, cur_date, cur_file);
break;
case StatementKind.CATCH:
if (strfind("|", node.variable_declaration.variable_type.name) > -1)
record_feature_use(MultiCatch, MultiCatch2, cur_date, cur_file);
break;
case StatementKind.TRY:
if (len(node.initializations) > 0)
record_feature_use(TryResources, TryResources2, cur_date, cur_file);
break;
case StatementKind.FOR:
if (def(node.variable_declaration))
record_feature_use(EnhancedFor, EnhancedFor2, cur_date, cur_file);
break;
default:
break;
}
}
before node: Expression ->
if (node.kind == ExpressionKind.METHOD_REFERENCE) {
if (def(node.new_type))
record_feature_use(MethRefNew, MethRefNew2, cur_date, cur_file);
else if (match(`super$`, node.literal))
record_feature_use(MethRefSuper, MethRefSuper2, cur_date, cur_file);
else
record_feature_use(MethRefExpr, MethRefExpr2, cur_date, cur_file);
} else if (node.kind == ExpressionKind.LITERAL && def(node.literal)) {
if (node.kind == ExpressionKind.LITERAL && def(node.literal)) {
if (match(`^0[bB][01]([01_]*[01])?[Ll]?$`, node.literal))
record_feature_use(BinaryLit, BinaryLit2, cur_date, cur_file);
if (strfind("_", node.literal) > -1 && match(`^(0[bBx])?([0-9]+.[0-9]+)?[0-9A-Fa-f]([0-9A-Fa-f_]*[0-9A-Fa-f])?[FfLl]?$`, node.literal))
record_feature_use(UnderscoreLit, UnderscoreLit2, cur_date, cur_file);
} else if (node.kind == ExpressionKind.NEW && def(node.new_type) && strfind("<>", node.new_type.name) > -1)
record_feature_use(Diamond, Diamond2, cur_date, cur_file);
before node: Modifier ->
if (node.kind == ModifierKind.ANNOTATION)
record_feature_use(AnnotUse, AnnotUse2, cur_date, cur_file);
if (match(`^0[bB][01]([01_]*[01])?[Ll]?$`, node.literal))
record_feature_use(BinaryLit, BinaryLit2, cur_date, cur_file);
if (strfind("_", node.literal) > -1 && match(`^(0[bBx])?([0-9]+.[0-9]+)?[0-9A-Fa-f]([0-9A-Fa-f_]*[0-9A-Fa-f])?[FfLl]?$`, node.literal))
record_feature_use(UnderscoreLit, UnderscoreLit2, cur_date, cur_file);
} else if (node.kind == ExpressionKind.NEW && def(node.new_type) && strfind("<>", node.new_type.name) > -1)
record_feature_use(Diamond, Diamond2, cur_date, cur_file);
before node: Modifier ->
if (node.kind == ModifierKind.ANNOTATION)
record_feature_use(AnnotUse, AnnotUse2, cur_date, cur_file);
else if (node.other == "default")
record_feature_use(DefaultMeth, DefaultMeth2, cur_date, cur_file);
});

changekind_to_string := function(kind: ChangeKind) : string {
if (kind == ChangeKind.ADDED)
return "Add";
return "Change";
};

output_feature_first_use := function(name: string, fileMap: map[string] of time, kinds: map[string] of ChangeKind) {
keyset := keys(fileMap);
if (len(keyset) == 0) return;

minval:time = now();

for (i := 0; i < len(keyset); i++) {
minval = min(minval, fileMap[keyset[i]]);
FileUses[name][changekind_to_string(kinds[keyset[0]])][fileMap[keyset[i]]] << 1;
}

ProjectUses[name][minval] << 1;
};

output_feature_first_use("Diamond", Diamond, Diamond2);
output_feature_first_use("BinaryLit", BinaryLit, BinaryLit2);
output_feature_first_use("Assert", Assert, Assert2);
output_feature_first_use("AnnotUse", AnnotUse, AnnotUse2);
output_feature_first_use("AnnotDefine", AnnotDefine, AnnotDefine2);
output_feature_first_use("Enums", Enums, Enums2);
output_feature_first_use("EnhancedFor", EnhancedFor, EnhancedFor2);
output_feature_first_use("GenDefField", GenDefField, GenDefField2);
output_feature_first_use("GenDefMethod", GenDefMethod, GenDefMethod2);
output_feature_first_use("GenDefType", GenDefType, GenDefType2);
output_feature_first_use("GenWildcard", GenWildcard, GenWildcard2);
output_feature_first_use("GenExtends", GenExtends, GenExtends2);
output_feature_first_use("GenSuper", GenSuper, GenSuper2);
output_feature_first_use("MultiCatch", MultiCatch, MultiCatch2);
output_feature_first_use("SafeVarargs", SafeVarargs, SafeVarargs2);
output_feature_first_use("TryResources", TryResources, TryResources2);
output_feature_first_use("UnderscoreLit", UnderscoreLit, UnderscoreLit2);
output_feature_first_use("Varargs", Varargs, Varargs2);
output_feature_first_use("RepeatedAnnot", RepeatedAnnot, RepeatedAnnot2);
output_feature_first_use("RcvParam", RcvParam, RcvParam2);
});

changekind_to_string := function(kind: ChangeKind) : string {
if (kind == ChangeKind.ADDED)
return "Add";
return "Change";
};

output_feature_first_use := function(name: string, fileMap: map[string] of time, kinds: map[string] of ChangeKind) {
keyset := keys(fileMap);
if (len(keyset) == 0) return;

minval:time = now();

for (i := 0; i < len(keyset); i++) {
minval = min(minval, fileMap[keyset[i]]);
FileUses[name][changekind_to_string(kinds[keyset[0]])][fileMap[keyset[i]]] << 1;
}

ProjectUses[name][minval] << 1;
};

output_feature_first_use("Diamond", Diamond, Diamond2);
output_feature_first_use("BinaryLit", BinaryLit, BinaryLit2);
output_feature_first_use("Assert", Assert, Assert2);
output_feature_first_use("AnnotUse", AnnotUse, AnnotUse2);
output_feature_first_use("AnnotDefine", AnnotDefine, AnnotDefine2);
output_feature_first_use("Enums", Enums, Enums2);
output_feature_first_use("EnhancedFor", EnhancedFor, EnhancedFor2);
output_feature_first_use("GenDefField", GenDefField, GenDefField2);
output_feature_first_use("GenDefMethod", GenDefMethod, GenDefMethod2);
output_feature_first_use("GenDefType", GenDefType, GenDefType2);
output_feature_first_use("GenWildcard", GenWildcard, GenWildcard2);
output_feature_first_use("GenExtends", GenExtends, GenExtends2);
output_feature_first_use("GenSuper", GenSuper, GenSuper2);
output_feature_first_use("MultiCatch", MultiCatch, MultiCatch2);
output_feature_first_use("SafeVarargs", SafeVarargs, SafeVarargs2);
output_feature_first_use("TryResources", TryResources, TryResources2);
output_feature_first_use("UnderscoreLit", UnderscoreLit, UnderscoreLit2);
output_feature_first_use("Varargs", Varargs, Varargs2);
output_feature_first_use("RepeatedAnnot", RepeatedAnnot, RepeatedAnnot2);
output_feature_first_use("RcvParam", RcvParam, RcvParam2);
output_feature_first_use("DefaultMeth", DefaultMeth, DefaultMeth2);
output_feature_first_use("MethRefNew", MethRefNew, MethRefNew2);
output_feature_first_use("MethRefSuper", MethRefSuper, MethRefSuper2);
output_feature_first_use("MethRefExpr", MethRefExpr, MethRefExpr2);