in source/MarianaTrench.cpp [61:267]
Registry MarianaTrench::analyze(Context& context) {
context.artificial_methods =
std::make_unique<ArtificialMethods>(*context.kinds, context.stores);
Timer methods_timer;
LOG(1, "Storing methods...");
context.methods = std::make_unique<Methods>(context.stores);
if (context.options->dump_methods()) {
auto method_list = Json::Value(Json::arrayValue);
for (const auto* method : *context.methods) {
method_list.append(method->signature());
}
auto methods_path = context.options->methods_output_path();
LOG(1, "Writing methods to `{}`.", methods_path.native());
JsonValidation::write_json_file(methods_path, method_list);
}
LOG(1, "Stored all methods in {:.2f}s", methods_timer.duration_in_seconds());
Timer fields_timer;
LOG(1, "Storing fields...");
context.fields = std::make_unique<Fields>(context.stores);
LOG(1, "Stored all fields in {:.2f}s", fields_timer.duration_in_seconds());
Timer index_timer;
LOG(1, "Building source index...");
context.positions =
std::make_unique<Positions>(*context.options, context.stores);
context.statistics->log_time("source_index", index_timer);
LOG(1, "Built source index in {:.2f}s.", index_timer.duration_in_seconds());
Timer types_timer;
LOG(1, "Inferring types...");
context.types = std::make_unique<Types>(*context.options, context.stores);
context.statistics->log_time("types", types_timer);
LOG(1, "Inferred types in {:.2f}s.", types_timer.duration_in_seconds());
Timer class_hierarchies_timer;
LOG(1, "Building class hierarchies...");
context.class_hierarchies =
std::make_unique<ClassHierarchies>(*context.options, context.stores);
context.statistics->log_time("class_hierarchies", class_hierarchies_timer);
LOG(1,
"Built class hierarchies in {:.2f}s.",
class_hierarchies_timer.duration_in_seconds());
Timer field_cache_timer;
LOG(1, "Building fields cache...");
context.field_cache =
std::make_unique<FieldCache>(*context.class_hierarchies, context.stores);
context.statistics->log_time("fields", field_cache_timer);
LOG(1,
"Built fields cache in {:.2f}s.",
field_cache_timer.duration_in_seconds());
Timer lifecycle_methods_timer;
LOG(1, "Creating life-cycle wrapper methods...");
LifecycleMethods::run(
*context.options, *context.class_hierarchies, *context.methods);
context.statistics->log_time("lifecycle_methods", lifecycle_methods_timer);
LOG(1,
"Created lifecycle methods in {:.2f}s.",
lifecycle_methods_timer.duration_in_seconds());
Timer overrides_timer;
LOG(1, "Building override graph...");
context.overrides = std::make_unique<Overrides>(
*context.options, *context.methods, context.stores);
context.statistics->log_time("overrides", overrides_timer);
LOG(1,
"Built override graph in {:.2f}s.",
overrides_timer.duration_in_seconds());
Timer call_graph_timer;
LOG(1, "Building call graph...");
context.call_graph = std::make_unique<CallGraph>(
*context.options,
*context.methods,
*context.fields,
*context.types,
*context.class_hierarchies,
*context.overrides,
*context.features);
context.statistics->log_time("call_graph", call_graph_timer);
LOG(1,
"Built call graph in {:.2f}s.",
call_graph_timer.duration_in_seconds());
std::vector<Model> generated_models;
std::vector<FieldModel> generated_field_models;
if (!context.options->skip_model_generation()) {
Timer generation_timer;
LOG(1, "Generating models...");
auto model_generator_result = ModelGeneration::run(context);
generated_models = model_generator_result.method_models;
generated_field_models = model_generator_result.field_models;
context.statistics->log_time("models_generation", generation_timer);
LOG(1,
"Generated {} models and {} field models in {:.2f}s.",
generated_models.size(),
generated_field_models.size(),
generation_timer.duration_in_seconds());
} else {
LOG(1, "Skipped model generation.");
}
// Add models for artificial methods.
{
auto models = context.artificial_methods->models(context);
generated_models.insert(
generated_models.end(), models.begin(), models.end());
}
Timer registry_timer;
LOG(1, "Initializing models...");
auto registry = Registry::load(
context, *context.options, generated_models, generated_field_models);
context.statistics->log_time("registry_init", registry_timer);
LOG(1,
"Initialized {} models and {} field models in {:.2f}s.",
registry.models_size(),
registry.field_models_size(),
registry_timer.duration_in_seconds());
Timer rules_timer;
LOG(1, "Initializing rules...");
context.rules =
std::make_unique<Rules>(Rules::load(context, *context.options));
context.statistics->log_time("rules_init", rules_timer);
LOG(1,
"Initialized {} rules in {:.2f}s.",
context.rules->size(),
rules_timer.duration_in_seconds());
Timer kind_pruning_timer;
LOG(1, "Removing unused Kinds");
int num_removed = UnusedKinds::remove_unused_kinds(context, registry).size();
context.statistics->log_time("prune_kinds", rules_timer);
LOG(1,
"Removed {} kinds in {:.2f}s.",
num_removed,
kind_pruning_timer.duration_in_seconds());
Timer dependencies_timer;
LOG(1, "Building dependency graph...");
context.dependencies = std::make_unique<Dependencies>(
*context.options,
*context.methods,
*context.overrides,
*context.call_graph,
registry);
context.statistics->log_time("dependencies", dependencies_timer);
LOG(1,
"Built dependency graph in {:.2f}s.",
dependencies_timer.duration_in_seconds());
Timer class_properties_timer;
context.class_properties = std::make_unique<ClassProperties>(
*context.options,
context.stores,
*context.features,
*context.dependencies);
context.statistics->log_time("class_properties", class_properties_timer);
LOG(1,
"Created class properties in {:.2f}s.",
class_properties_timer.duration_in_seconds());
Timer scheduler_timer;
LOG(1, "Building the analysis schedule...");
context.scheduler =
std::make_unique<Scheduler>(*context.methods, *context.dependencies);
context.statistics->log_time("scheduler", scheduler_timer);
LOG(1,
"Built the analysis schedule in {:.2f}s.",
scheduler_timer.duration_in_seconds());
Timer analysis_timer;
LOG(1, "Analyzing...");
Interprocedural::run_analysis(context, registry);
context.statistics->log_time("fixpoint", analysis_timer);
LOG(1,
"Analyzed {} models in {:.2f}s. Found {} issues!",
registry.models_size(),
analysis_timer.duration_in_seconds(),
registry.issues_size());
Timer remove_collapsed_traces_timer;
LOG(2, "Removing invalid traces due to collapsing...");
PostprocessTraces::remove_collapsed_traces(registry, context);
context.statistics->log_time(
"remove_collapsed_traces", remove_collapsed_traces_timer);
LOG(2,
"Removed invalid traces in {:.2f}s.",
remove_collapsed_traces_timer.duration_in_seconds());
if (!context.options->skip_source_indexing()) {
Timer augment_positions_timer;
LOG(1, "Augmenting positions...");
Highlights::augment_positions(registry, context);
context.statistics->log_time("augment_positions", augment_positions_timer);
LOG(1,
"Augmented positions in {:.2f}s.",
augment_positions_timer.duration_in_seconds());
} else {
LOG(2, "Skipped augmenting positions.");
}
return registry;
}