A Language/Platform agnostic Mutation & Analysis Language.
Useful for:
- Mutation Analysis
- Generating synthetic code data for DeepLearning models etc
- Analyzing interesting code points
git clone https://github.com/talalzone/DeepMutate
./gradlew clean shadowJar
- Java 17+
from (dir='/path/to/java-project')
mutate(lang='java', type='semantic', analyze='true')
out(store='mongodb', report='html') {
def mutators {
[method_call_returns_int][active='true']
match: 'int i = someNonVoidMethod();'
set: 'int i = 0;'
[method_call_returns_obj][active='true']
match: 'Object o = someNonVoidMethod();'
set: 'Object o = null;'
[method_call_only][active='false']
match: 'someVoidMethodCall()'
set: 'NO_OP'
[binaryop_switch][active='false']
match: 'if (a == b)'
set: 'if (a != b)'
}
}
To run sample.dm (containing above code)
java -jar deep-mutate-<version>.jar --run sample.dm
See all CLI commands:
java -jar deep-mutate-<version>.jar --help
Reports are generated under directory:
deep-mutate-report
DeepMutate consists of one or more Project Declarations.
A Project Declaration consists of FROM, MUTATE and OUTPUT statements.
This is followed by one or more Mutation Functions containing one or more Mutation Statements (clauses).
Read from project directory(s):
// Single project directory
FROM (dir='/path/to/project-dir', build='gradle')
// Multiple project directories
FROM (dir=['/path/to/project-1', '/path/to/project-2'], build_system='maven']
Read from code file(s):
// Read single file
FROM ( file='/path/to/ClassA.java' )
// Read multiple files
FROM ( files=['/path/to/ClassA.java', '/path/to/ClassB.java'] )'
Read from inline code:
FROM (code='ClassA { void someMethod() { /* some code etc */ } }'
Read from console:
FROM (console)
NOTE: build or build_system need to be set for mutation analysis (i.e., when analyze='true')
Type | Values |
---|---|
DIR | Dir path(s) e.g., 'java/project' or ['java/project-1', 'java/project-2'] |
FILE | File path(s) e.g., 'ClassA.java' or ['ClassA.java', 'ClassB.java'] |
CODE | Any syntactically correct code e.g., 'AnyClassA { void anyMethod() {/* method body */} } |
CONSOLE | Read input from console |
BUILD or BUILD_SYSTEM | Build System to use. Available: Maven, Gradle |
MUTATE (lang='java', type='semantic', analyze='true')
Type | Values | Default |
---|---|---|
LANG or LANGUAGE | 'java', 'python' etc | Not set |
TYPE | 'semantic' or 'syntactic' | 'semantic' |
ANALYZE | 'true' or 'false' | 'false' |
Sending mutations out to a datastore (e.g., MongoDB):
// Connects to default mongodb local instance
OUT (store='mongodb', report='true')
// Same statement but a bit verbose
OUTPUT (datastore='mongodb', report='html')
Type | Values | Default |
---|---|---|
STORE or DATASTORE | 'mongodb', 'arangodb', 'csv', 'cache' | Not set |
URI | 'mongodb://...', 'arangodb://' | Not set |
REPORT | 'csv', 'console', html', 'true', 'false' | 'false' |
DB or DATABASE | 'any_database_name' | 'deepmutate' |
COL or COLLECTION | 'any_collection_or_table_name' | 'mutations' |
ANALYZE | 'true' or 'false' | 'false' |
Mutation functions groups together different mutator statements.
def <some_mutation_function_identifier> {
/*
match: '<pattern>'
set: '<update>'
match: '<pattern>'
set: '<update>'
*/
}
def <another_mutation_function_identifier> {
/*
match: '<pattern>'
where: '<filter>'
set: '<update>'
match: '<pattern>'
where: '<filter>'
set: '<update>'
*/
}
A mutation statement consists of MATCH, WHERE and SET clauses.
['optional_mutation_identifier'][<optional configurations e.g., active='true'>]
match: 'return x;' // Pattern in code to match
// Any filter clause
where: 'x is java.util.Optional'
// Changes to be applied to the matched pattern
set: 'return Optional.empty()'
MATCH should have a syntactically correct expression, conditional, declaration etc.
DeepMutate checks for lexical type match in the sourcecode Abstract Syntax Tree (AST). The 'match' context is replaced by the 'set' context in the AST.
The variable names are kept as is.
Type | Values | Optional | Default |
---|---|---|---|
IDENTIFIER | 'any_string_identifier' without spaces | Yes | auto-generated |
ACTIVE | 'true' or 'false' | Yes | 'true' |
Comments can appear any where in the DeepMutate code.
Inline comments:
// This is an inline comments
Block comments:
/*
This is a block comment
*/
- Further languages can be added
- Support for Semantic & Syntactic mutations
- Support for Multi-model DBMS: SQL, NoSQL and Graph
- Generates mutations with several accessible data points:
- Source code
- Mutated code
- Mutation patterns
- Stack traces
- Java
- Future: Python, Javascript, Golang etc
- Gradle
- Maven
- MongoDB
- ArangoDB
- CSV
- HTML
- CSV
- Console
This project is licensed under the MIT License