# # computing feature uses # Section 5.2, Figure 4 # # author: Robert Dyer # # Copyright 2013-2014 Iowa 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. # p:Project = input; Uses: output sum[string] of int; ProjectUses: output sum[string] of int; FileUses: output sum[string] of int; Diamond: map[string] of int; BinaryLit: map[string] of int; Assert: map[string] of int; AnnotUse: map[string] of int; AnnotDefine: map[string] of int; Enums: map[string] of int; EnhancedFor: map[string] of int; GenDefField: map[string] of int; GenDefMethod: map[string] of int; GenDefType: map[string] of int; GenWildcard: map[string] of int; GenExtends: map[string] of int; GenSuper: map[string] of int; MultiCatch: map[string] of int; SafeVarargs: map[string] of int; TryResources: map[string] of int; UnderscoreLit: map[string] of int; Varargs: map[string] of int; cur_file: ChangedFile; in_field: bool; record_feature_use := function(uses: map[string] of int) { if (!haskey(uses, cur_file.name)) uses[cur_file.name] = 0; uses[cur_file.name] = uses[cur_file.name] + 1; }; visit(p, visitor { before node: CodeRepository -> { snapshot := getsnapshot(node, "SOURCE_JAVA_JLS"); foreach (i: int; def(snapshot[i])) visit(snapshot[i]); stop; } before node: ChangedFile -> cur_file = node; before node: Declaration -> { if (node.kind == TypeKind.ANNOTATION) record_feature_use(AnnotDefine); if (len(node.generic_parameters) > 0) record_feature_use(GenDefType); if (node.kind == TypeKind.ENUM) record_feature_use(Enums); 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); if (match(`\?\s*extends\s+.+`, node.name)) record_feature_use(GenExtends); if (match(`\?\s*super\s+.+`, node.name)) record_feature_use(GenSuper); if (in_field && strfind("<", node.name) > -1) record_feature_use(GenDefField); } before node: Method -> { if (len(node.generic_parameters) > 0) record_feature_use(GenDefMethod); # @SafeVarargs if (has_annotation(node, "SafeVarargs")) { record_feature_use(SafeVarargs); } 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); } break; } } if (len(node.arguments) > 0 && strfind("...", node.arguments[len(node.arguments) - 1].variable_type.name) > -1) record_feature_use(Varargs); } before node: Statement -> { switch (node.kind) { case StatementKind.ASSERT: record_feature_use(Assert); break; case StatementKind.CATCH: if (strfind("|", node.variable_declaration.variable_type.name) > -1) record_feature_use(MultiCatch); break; case StatementKind.TRY: if (len(node.initializations) > 0) record_feature_use(TryResources); break; case StatementKind.FOR: if (def(node.variable_declaration)) record_feature_use(EnhancedFor); break; default: break; } } before node: Expression -> if (node.kind == ExpressionKind.LITERAL && def(node.literal)) { if (match(`^0[bB][01][01_]*[01][L]?$`, node.literal)) record_feature_use(BinaryLit); if (strfind("_", node.literal) > -1 && match(`^(0[bBx])?([0-9]+.[0-9]+)?[0-9A-Fa-f]([0-9A-Fa-f_])*[0-9A-Fa-f][FL]?$`, node.literal)) record_feature_use(UnderscoreLit); } else if (node.kind == ExpressionKind.NEW && def(node.new_type) && strfind("<>", node.new_type.name) > -1) record_feature_use(Diamond); before node: Modifier -> if (node.kind == ModifierKind.ANNOTATION) record_feature_use(AnnotUse); }); output_feature_use := function(name: string, uses: map[string] of int) { if (len(uses) == 0) return; ProjectUses[name] << 1; FileUses[name] << len(uses); keyset := keys(uses); for (i := 0; i < len(keyset); i++) { Uses[name] << uses[keyset[i]]; } }; output_feature_use("Diamond", Diamond); output_feature_use("BinaryLit", BinaryLit); output_feature_use("Assert", Assert); output_feature_use("AnnotUse", AnnotUse); output_feature_use("AnnotDefine", AnnotDefine); output_feature_use("Enums", Enums); output_feature_use("EnhancedFor", EnhancedFor); output_feature_use("GenDefField", GenDefField); output_feature_use("GenDefMethod", GenDefMethod); output_feature_use("GenDefType", GenDefType); output_feature_use("GenWildcard", GenWildcard); output_feature_use("GenExtends", GenExtends); output_feature_use("GenSuper", GenSuper); output_feature_use("MultiCatch", MultiCatch); output_feature_use("SafeVarargs", SafeVarargs); output_feature_use("TryResources", TryResources); output_feature_use("UnderscoreLit", UnderscoreLit); output_feature_use("Varargs", Varargs);