From 3c5ec9785b03be715624e22873951a48b2aa035a Mon Sep 17 00:00:00 2001 From: AsnelChristian Date: Fri, 12 May 2017 20:42:29 +0100 Subject: [PATCH] cEP-0010.md: Convert bears to use aspects --- cEP-0010.md | 336 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 cEP-0010.md diff --git a/cEP-0010.md b/cEP-0010.md new file mode 100644 index 000000000..47783ac1d --- /dev/null +++ b/cEP-0010.md @@ -0,0 +1,336 @@ +# Convert bears to use aspects + +| Metadata | | +| ------------ |------------------------------------------------| +| cEP | 10 | +| Version | 1.0 | +| Title | Convert bears to use aspects | +| Authors | Asnel Christian Ngoulla | +| Status | Implementation Due | +| Type | Feature | + +## Abstract + +This document describes how `aspects` will be defined for and connected with +bears and how their results will be annotated with them. + +This cEP also provides a list of the `aspects` to be implemented with their +correspponding `tastes` where taste are customization `settings` for `aspects`. + +## Introduction + +An `aspect` is an analysis we want to run over a piece of code. As stated in +[cEP-0005](https://github.com/coala/cEPs/blob/master/cEP-0005.md), one of the +main problems coala faces is its configuration due to the huge number of bears +it offers, which are capable of analyzing several aspects of code and are +sometimes highly configurable with numerous settings; whereby the user has to +be aware of which bear does what and which setting has be to set to analyze +the aspect he wants analyzed; resulting in a coala difficult to learn and use. + +To make things easier for user the concept of `aspects` was created as proposed +in [cEP-0005](https://github.com/coala/cEPs/blob/master/cEP-0005.md). Our goal +here is to list all the aspects for covering all the code anlysis features the +coala bears are capable of, annotating bears' results with them. + +## The aspests + +The bears offered by coala are usually capable of handling several aspects. +`aspects` will be implemented in a tree-like form starting with the +[Root aspect](https://github.com/coala/coala/blob/master/coalib/bearlib/aspects/root.py). +Here is the list of aspects to be implemented along with their corresponding +`subaspects` and tastes(which are the leaves of the tree written +in snake_case). + + +``` + Root + |--- Formatting + |--- |--- UseSpaces + |--- |--- TrailingSpace + |--- |--- EmtpyLines + |--- |--- |--- num_newlines_after_class_def + |--- |--- |--- num_newlines_after_func_def + |--- |--- Quotation + |--- |--- |--- prefered_quotation + |--- |--- Length + |--- |--- |--- LineLength + |--- |--- |--- |--- max_line_length + |--- |--- |--- Ignore + |--- |--- |--- |--- ignore_links + |--- |--- |--- |--- ignore_line + |--- |--- |--- FileLength + |--- |--- |--- |--- max_file_length + |--- |--- Indentation + |--- |--- |--- size + |--- |--- ParenthesesFormatting + |--- |--- BracesFormatting + |--- |--- SpaceAroundOperators + |--- Smell + |--- |--- Complexity + |--- |--- |--- cyclomatic_complexity + |--- |--- ClassSmell + |--- |--- |--- ClassLength + |--- |--- |--- |--- max_class_length + |--- |--- |--- |--- min_class_length + |--- |--- |--- FeatureEnvy + |--- |--- MethodSmell + |--- |--- |--- max_method_length + |--- |--- |--- max_parameter + |--- |--- Naming + |--- |--- |--- variable_naming_convention + |--- |--- |--- function_naming_convention + |--- |--- |--- class_naming_convention + |--- |--- |--- max_indentifier_name_length + |--- |--- |--- min_indentifier_name_length + |--- Security + |--- |--- buffer_overflow + |--- |--- unallocated_memory + |--- Redundancy + |--- |--- Clone + |--- |--- |--- min_clone_tokens + |--- |--- |--- ignore_using + |--- |--- UnusedImport + |--- |--- UnreachableCode + |--- |--- UnusedFunction + |--- |--- UnreachableStatement + |--- |--- UnusedParameter + |--- |--- UnusedLocalVariable + |--- |--- UnusedGlobalVariablee + |--- Spelling + |--- |--- aspectsYEAH + |--- |--- coala + |--- UndefinedElement + |--- |--- UndefinedVariable + |--- |--- UndefinedParameter + |--- |--- UndefinedFunction + |--- Documentation + |--- Grammar + |--- |--- Language + |--- Metadata + |--- |--- CommitMessage + |--- |--- | --- Shortlog + |--- |--- | --- |--- Emptiness + |--- |--- | --- |--- ColonExistence + |--- |--- | --- |--- TrailingPeriod + |--- |--- | --- |--- Tense + |--- |--- | --- |--- Length + |--- |--- | --- |--- |--- max_shortlog_length + |--- |--- | --- |--- FirstCharacter + |--- |--- | --- |--- |--- shortlog_starts_upper_case + |--- |--- | --- Body + |--- |--- | --- |--- Existence + |--- |--- | --- |--- Length + |--- |--- | --- |--- |--- max_body_length + +``` +* `Root.Formatting`: This aspect checks on the format (the structure) of your +codebase. +* `Root.Formatting.UseSpaces`: This aspect enforces the use of spaces over +tabs. +* `Root.Formatting.TrailingSpace`: This aspect detects trailing spaces in the +code. +* `Root.Formatting.EmptyLines`: This aspect checks on empty lines. +* `Root.Formatting.EmptyLines.num_newlines_after_class_def`: +This taste represents the number of newlines that should be added after a class +definition. +* `Root.Formatting.EmptyLines.num_newlines_after_func_def`: +This taste represents the number of newlines that should be added after a +function definition. +* `Root.Formatting.Quotation`: This aspect checks on the quotations being used +in your files given `Root.Formatting.Quotation.prefered_quotation`. +* `Root.Formatting.Quotation.prefered_quotation`: This taste represents the +user's preferred quotation. +* `Root.Formatting.LineLength`: This aspect checks on lines' length in your +codebase. +* `Root.Formatting.LineLength.max_line_length`: This taste represents that +maximum length for line. +* `Root.Formatting.LineLength.Ignore`: This aspect represents all the +elements to be ignored. +* `Root.Formatting.LineLength.Ignore.ignore_links`: this taste is to determine +whether links should be ignored while checking on lines' length. +* `Root.Formatting.LineLength.Ignore.ignore_line`: this taste is to which line +should be ignored while checking on lines' length. +* `Root.Formatting.FileLength`: This aspect checks on files' length given +`Root.Formatting.FileLength.max_file_length`. +* `Root.Formatting.FileLength.max_file_length`: this taste represents the +maximum length for a file. +* `Root.Formatting.Indentation`: This taste checks on the number of space +used for indentation given `Root.Formatting.Indentation.size`. +* `Root.Smell`: This aspect describes `code smells` (smells refer to +structures that violate design principles) in your codebase. +* `Root.Smell.Complexity`: describes the complexity of your code given the +value `cyclomatic_complexity`. +* `Root.Smell.Complexity.cyclomatic_complexity`: Variable reprensing the +maximum number of embedded branches or embedded loops. +* `Root.Smell.ClassSmell`: This aslpect describes `code smells` related to +classes' definition in your codebase. +* `Root.Smell.ClassSmell.ClassLength`: This aspect deals with the length of +classes' definition. +* `Root.Smell.ClassSmell.ClassLength.max_class_length`: This taste represents +the maximum length for a class's definition. +* `Root.Smell.ClassSmell.ClassLength.min_class_length`: This taste represents +the minimum length for a class's definition. +* `Root.Smell.ClassSmell.FeatureEnvy`: This aspect describes classes that use +other classes' methods excessively. +* `Root.Smell.ClassSmell.DataClump`: This aspect describes variables +are passed around together in various parts of the program, suggesting +that they should pass as a single object. +* `Root.Smell.MethodSmell`: This aspect describes code smells +related to functions' (and or methods') definition. +* `Root.Smell.MethodSmell.max_method_length`: variable representing the +maximum length for a method or a function definition. +* `Root.Smell.MethodSmell.max_parameter`: This taste represents maximum number +of paramters for a function. +* `Root.Smell.Naming`: This aspect deals with identifiers' names(their +length, the naming convention in use ...) +* `Root.Smell.Naming.variable_naming_convention`: This taste represents the +naming convention used for variables' and functions' parameters' identifiers. +* `Root.Smell.Naming.function_naming_convention`: This taste +represents the naming convention used for functions' or methods'. +* `Root.Smell.Naming.class_naming_convention`: This taste represents the +naming convention being used for classes. +* `Root.Smell.Naming.max_identifier_length`: This taste represents the max +length for an identifier. +* `Root.Smell.Naming.max_identifier_length`: This taste represents the min +length for an identifier. +* `Root.Redundancy`: This aspect describes redundancy in your source code. +* `Root.Redundancy.Clone`: This aspect detects code +clones or more specifically very similar blocks of code in your codebase. +* `Root.Redundancy.Clone.min_clone_tokens`(a taste of the `Clone` aspect): +Thsi taste represents the minimun number of token that have to be equal to be +considered as a clone. +* `Root.Redundancy.UnusedImport`: This taste describes useless import/include +that is not needed. +* `Root.Redundancy.UnreachableCode`: This taste describes source code that +can never be executed during the program execution. +* `Root.Redundancy.UnusedFunction`: This taste describes functions that +are never called during code execution +* `Root.Redundancy.UnreachableStatement`: This taste describes statement that +are never executed during code execution. +* `Root.Redundancy.UnusedParameter`: This taste describes functions' +parameters which are never used. +* `Root.Redundancy.UnusedLocalVariable`: This taste describes variables which +are defined locally but never used. +* `Root.Redundancy.UnusedGlobalVariable`: this taste describes variables which +have a global scope but are never used. +* `Root.Spelling`: This aspect checks on the spelling of specific words. +* `Root.Spelling.coala`: This aspect checks on the spelling of `coala`. +* `Root.Spelling.aspectsYEAH`: This aspect checks on the spelling of +`aspect[s]` and `aspectsYEAH`. +* `Root.UndefinedElement`: This aspect checks on undefined element in your +codebase. +* `Root.UndefinedElement.UndefinedVariable`: This aspect detects undefined +variables in your code. +* `Root.UndefinedElement.UndefinedParameter`: This aspect detects undefined +parameters in functions' definitions. +* `Root.UndefinedElement.UndefinedFunction`: This aspect detects undefined +functions in your codebase. +* `Root.Metadata`: This describes any aspect that is related to metadata that +is not inside your source code. +* `Root.Metadata.CommitMessage`. +* `Root.Metadata.CommitMessage.Emptiness`: This aspect is to detect and +prevent from using empty commit message. +* `Root.Metadata.CommitMessage.Shortlog`: This aspect checks on the first line +of your commit message. +* `Root.Metadata.CommitMessage.Shortlog.ColonExistence`: This aspect checks +your commit shortlog to see whether or not there is a colon (given that the +usage of colon is compulsory in your project). +* `Root.Metadata.CommitMessage.Shortlog.TrailingPeriod`: This aspect checks +for trailing period. +* `Root.Metadata.CommitMessage.Shortlog.Tense`: This aspect checks on the +tense used in commit message shortlog. +* `Root.Metadata.CommitMessage.Shortlog.Length`: This aspect checks on the +length of your commit message shortlog given the value of +`Root.Metadata.CommitMessage.Shortlog.Length.max_shortlog_length`. +* `Root.Metadata.CommitMessage.Shortlog.FirstCharacter`: This aspect detects +inconsistent casing for the first character of your commit message shortlog( +and the the first character following the colon if there is one) given the +value of +`Root.Metadata.CommitMessage.Shortlog.FirstCharacter.shortlog_starts_upper_case` +[taste representing the case to use for the first character of your +commit message shortlog and the first character following the colon]. +* `Root.Metadata.CommitMessage.Body`: Parent aspect for all of the aspects +related to your commit message body. +* `Root.Metadata.CommitMessage.Body.Existence`: Checks on the existence of +your commit message body (it enforces its usage). +* `Root.Metadata.CommitMessage.Body.Length`: Checks on the length of your +commit message body given the value of +`Root.Metadata.CommitMessage.Body.Length.max_body_length`. + +## Implementation + +As stated previously the aspects will be implemented in a tree like form, +with the Root aspect at the root of the tree. Some classes, metaclasses +and some few methods were define so far to make that possible including: + +* [the aspectbase class](https://github.com/coala/coala/blob/master/coalib/bearlib/aspects/base.py) +* [the Documentation class for documenting aspects](https://github.com/coala/coala/blob/master/coalib/bearlib/aspects/docs.py) +* [the aspectclass metaclass](https://github.com/coala/coala/blob/master/coalib/bearlib/aspects/meta.py) +* [the TasteMeta class](https://github.com/coala/coala/blob/master/coalib/bearlib/aspects/taste.py) +* [the Taste class](https://github.com/coala/coala/blob/master/coalib/bearlib/aspects/taste.py) + +`aspects` will simply be defined this way: +```python +from coalib.bearlib.aspects import Root, Taste + + +@Root.subaspect +class SomeAspect: + + # This will serve as documentation for the aspect + class docs: + example = 'an example of this aspect of code' + example_language = 'the programming language of the example' + importance_reason = 'the reason why this is important' + fix_suggestions = '' + + # Here we define the different tastes for this aspect + # aspects are not compelled to have tastes + some_taste = Taste[Taste_type]( + 'Documentation about this taste', + list('Possible value for this taste',), + default='Default value for this taste') +``` +The documentation of each of the implemented aspects will be added to +the [coala/aspect-docs](https://github.com/coala/aspect-docs) repository. + +Concerning bears' results annotation, so far, the `.aspect` attr was added to +the [Result class](https://github.com/coala/coala/blob/master/coalib/results/Result.py) +(where a Result object is what is yielded by a bear when through executing). +So annotating a bear's result with aspects simply consists of setting this +variable to the appropriate aspect of code. +Here is how bears' will be defined in as presented in +[cEP-0005](https://github.com/coala/cEPs/blob/master/cEP-0005.md). + +```python +from coalib.bears.LocalBear import LocalBear +from coalib.results.Result import Result +from coalib.bearlib.aspects import Root + + +class RedundancyBear(LocalBear, aspects={ + # This represents all the aspects this bear can detect. + 'detect': [Root.Redundancy.Clone], + # This represents all the aspects this bear can fix. + 'fix': [Root.Redundancy.UnusedImport]}, + languages=['C', 'Python']): + + def run(self, filename, file, aspects): + # No documentation required anymore for the bears. + + if unused_imports(file): + # A bear may yield results for any aspect even if it's not selected. + # coala will filter out only selected aspects. + yield Result.from_values(aspect=Root.Redundancy.UnusedImport, ...) + + # Bears can save performance by only performing needed checks + aspect = aspects.get(Root.Redundancy.Clone, False) + if aspect: + # Bears can access tastes right from the aspect instance + min_clone_tokens = aspect.min_clone_tokens + + # The aspect is tied to the result. coala now knows everything from + # the aspect documentation! + yield Result.from_values(aspect=aspect, ...) +``` +