-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
630a714
commit 29a3c83
Showing
3 changed files
with
521 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,397 @@ | ||
# Command Line Tool | ||
|
||
You can also use Mulang from the Command Line, without having to interact with Haskell code. This tool allows to perform most common analysis out of the box by using a JSON spec. It supports four different kinds of analysis: | ||
|
||
1. **Expectation analysis**: you can pass _inspections_ that will be tested against the provied program. Expectations answer questions like: _does the function X call the function Y?_ or _does the program use if's?_. | ||
4. **Smell analysis**: instead of asking explcit questions to the program, the smells analysis implicitly runs specific inspections - that denote bad code - in orden to know if any of them is matched. | ||
2. **Intermediate Language analysis**: you can ask the tool to generate the Mulang AST for a given source code. | ||
3. **Signature analysis**: report the signatures of the computations present in source code. | ||
|
||
|
||
## Examples | ||
|
||
Let's see some usage samples: | ||
|
||
### With intransitive expectations | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "Haskell", | ||
"content" : "x = 1" | ||
}, | ||
"spec" : { | ||
"expectations" : [ | ||
{ | ||
"binding" : ":Intransitive:x", | ||
"inspection" : "Uses:*" | ||
} | ||
], | ||
"smellsSet" : { "tag" : "NoSmells" } | ||
} | ||
} | ||
' | json_pp | ||
{ | ||
"expectationResults" : [ | ||
{ | ||
"expectation" : { | ||
"binding" : ":Intransitive:x", | ||
"inspection" : "Uses:*" | ||
}, | ||
"result" : false | ||
} | ||
], | ||
"smells" : [], | ||
"tag" : "AnalysisCompleted", | ||
"signatures" : [] | ||
} | ||
``` | ||
|
||
### With unscoped expectations | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "Haskell", | ||
"content" : "x = 1" | ||
}, | ||
"spec" : { | ||
"smellsSet" : { "tag" : "NoSmells" }, | ||
"expectations" : [ | ||
{ | ||
"binding" : "*", | ||
"inspection" : "Declares:x" | ||
} | ||
] | ||
} | ||
} | ||
' | json_pp | ||
{ | ||
"tag" : "AnalysisCompleted", | ||
"smells" : [], | ||
"expectationResults" : [ | ||
{ | ||
"result" : true, | ||
"expectation" : { | ||
"binding" : "*", | ||
"inspection" : "Declares:x" | ||
} | ||
} | ||
], | ||
"signatures" : [] | ||
} | ||
``` | ||
|
||
### With signature analysis | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "JavaScript", | ||
"content" : "function foo(x, y) { return x + y; }" | ||
}, | ||
"spec" : { | ||
"expectations" : [], | ||
"smellsSet" : { "tag" : "NoSmells" }, | ||
"signatureAnalysisType" : { | ||
"tag" : "StyledSignatures", | ||
"style" : "HaskellStyle" | ||
} | ||
} | ||
} | ||
' | json_pp | ||
{ | ||
"expectationResults" : [], | ||
"smells" : [], | ||
"signatures" : [ | ||
"-- foo x y" | ||
], | ||
"tag" : "AnalysisCompleted" | ||
} | ||
``` | ||
|
||
### With broken input | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "JavaScript", | ||
"content" : "function foo(x, y { return x + y; }" | ||
}, | ||
"spec" : { | ||
"expectations" : [], | ||
"smellsSet" : { "tag" : "NoSmells" }, | ||
"signatureAnalysisType" : { | ||
"tag" : "StyledSignatures", | ||
"style" : "HaskellStyle" | ||
} | ||
} | ||
}' | json_pp | ||
{ | ||
"tag" : "AnalysisFailed", | ||
"reason" : "Sample code parsing error" | ||
} | ||
``` | ||
|
||
### With AST as input | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "MulangSample", | ||
"ast" : { | ||
"tag" : "Sequence", | ||
"contents" : [ | ||
{ | ||
"tag" : "Variable", | ||
"contents" : [ | ||
"x", | ||
{ "tag" : "MuNumber", "contents" : 1 } | ||
] | ||
}, | ||
{ | ||
"tag" : "Variable", | ||
"contents" : [ | ||
"y", | ||
{ "tag" : "MuNumber", "contents" : 2 } | ||
] | ||
} | ||
] | ||
} | ||
}, | ||
"spec" : { | ||
"smellsSet" : { | ||
"tag" : "NoSmells" | ||
}, | ||
"signatureAnalysisType" : { | ||
"tag" : "StyledSignatures", | ||
"style" : "HaskellStyle" | ||
}, | ||
"expectations" : [] | ||
} | ||
} | ||
' | json_pp | ||
{ | ||
"expectationResults" : [], | ||
"smells" : [], | ||
"tag" : "AnalysisCompleted", | ||
"signatures" : [ | ||
"-- x", | ||
"-- y" | ||
] | ||
} | ||
``` | ||
|
||
### With Smell Analysis, by inclusion | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "JavaScript", | ||
"content" : "function foo(x, y) { return null; }" | ||
}, | ||
"spec" : { | ||
"expectations" : [], | ||
"smellsSet" : { | ||
"tag" : "NoSmells", | ||
"include" : [ | ||
"ReturnsNil", | ||
"DoesNullTest" | ||
] | ||
}, | ||
"signatureAnalysisType" : { | ||
"tag" : "StyledSignatures", | ||
"style" : "HaskellStyle" | ||
} | ||
} | ||
} | ||
' | json_pp | ||
{ | ||
"tag" : "AnalysisCompleted", | ||
"expectationResults" : [], | ||
"signatures" : [ | ||
"-- foo x y" | ||
], | ||
"smells" : [ | ||
{ | ||
"binding" : "foo", | ||
"inspection" : "ReturnsNil" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
### With Smell Analysis, by exclusion | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "JavaScript", | ||
"content" : "function foo(x, y) { return null; }" | ||
}, | ||
"spec" : { | ||
"expectations" : [], | ||
"smellsSet" : { | ||
"tag" : "AllSmells", | ||
"exclude" : [ | ||
"ReturnsNil" | ||
] | ||
}, | ||
"signatureAnalysisType" : { | ||
"tag" : "StyledSignatures", | ||
"style" : "HaskellStyle" | ||
} | ||
} | ||
} | ||
' | json_pp | ||
{ | ||
"smells" : [], | ||
"signatures" : [ | ||
"-- foo x y" | ||
], | ||
"tag" : "AnalysisCompleted", | ||
"expectationResults" : [] | ||
} | ||
``` | ||
|
||
### With expressiveness smells | ||
|
||
Expressivnes smells are like other smells - they can be included or excluded using the `smellsSet` settings. However, their behaviour is also controlled | ||
by the `domainLanguage` setting, which you _can_ configure: | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "Prolog", | ||
"content" : "son(Parent, Son):-parentOf(Son, Parent).parentOf(bart, homer)." | ||
}, | ||
"spec" : { | ||
"expectations" : [], | ||
"smellsSet" : { "tag" : "AllSmells" }, | ||
"domainLanguage" : { | ||
"caseStyle" : "SnakeCase", | ||
"minimumIdentifierSize" : 4, | ||
"jargon" : ["id"] | ||
} | ||
} | ||
}' | json_pp | ||
{ | ||
"tag" : "AnalysisCompleted", | ||
"signatures" : [], | ||
"smells" : [ | ||
{ | ||
"inspection" : "HasTooShortIdentifiers", | ||
"binding" : "son" | ||
}, | ||
{ | ||
"binding" : "parentOf", | ||
"inspection" : "HasWrongCaseIdentifiers" | ||
} | ||
], | ||
"expectationResults" : [] | ||
} | ||
``` | ||
|
||
Also, if you want to use `HasMisspelledIdentifiers` smell, you _need_ to specify a dictionary - with must be ordered, downcased and with unique words only: | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "JavaScript", | ||
"content" : "function foo(x, y) { return null; }" | ||
}, | ||
"spec" : { | ||
"expectations" : [], | ||
"smellsSet" : { "tag" : "AllSmells" }, | ||
"domainLanguage" : { "dictionaryFilePath" : "/usr/share/dict/words" } | ||
} | ||
}' | json_pp | ||
{ | ||
"tag" : "AnalysisCompleted", | ||
"expectationResults" : [], | ||
"signatures" : [], | ||
"smells" : [ | ||
{ | ||
"inspection" : "ReturnsNil", | ||
"binding" : "foo" | ||
}, | ||
{ | ||
"inspection" : "HasMisspelledIdentifiers", | ||
"binding" : "foo" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
|
||
### With Intermediate Language Generation | ||
|
||
```bash | ||
$ mulang ' | ||
{ | ||
"sample" : { | ||
"tag" : "CodeSample", | ||
"language" : "JavaScript", | ||
"content" : "function foo(x, y) { return null; }" | ||
}, | ||
"spec" : { | ||
"expectations" : [], | ||
"smellsSet" : { "tag" : "NoSmells" }, | ||
"includeIntermediateLanguage" : true | ||
} | ||
} | ||
' | json_pp | ||
{ | ||
"expectationResults" : [], | ||
"smells" : [], | ||
"tag" : "AnalysisCompleted", | ||
"signatures" : [], | ||
"intermediateLanguage" : { | ||
"tag" : "Function", | ||
"contents" : [ | ||
"foo", | ||
[ | ||
[ | ||
[ | ||
{ | ||
"tag" : "VariablePattern", | ||
"contents" : "x" | ||
}, | ||
{ | ||
"tag" : "VariablePattern", | ||
"contents" : "y" | ||
} | ||
], | ||
{ | ||
"tag" : "UnguardedBody", | ||
"contents" : { | ||
"contents" : { | ||
"tag" : "MuNil" | ||
}, | ||
"tag" : "Return" | ||
} | ||
} | ||
] | ||
] | ||
] | ||
} | ||
} | ||
|
||
``` |
Oops, something went wrong.