mumuki / mulang Goto Github PK
View Code? Open in Web Editor NEW:bamboo: Universal, Multi Language, Multi Paradigm code analyzer
Home Page: https://mumuki.github.io/mulang
License: GNU General Public License v3.0
:bamboo: Universal, Multi Language, Multi Paradigm code analyzer
Home Page: https://mumuki.github.io/mulang
License: GNU General Public License v3.0
GHC 8 has very nice features, like custom pattern - pattern aliases, which would probably improve a lot of our pattern matching code.
For example, instead of doing
doSomethingWithBody p@(ProcedureDeclaration _ _) = f . simpleProcedureBody $ p
we could do the following:
doSomethingWithBody (SimpleProcedureDeclaration _ _ body) = f body
There are some frequent errors in collection usages. For example, getting the length of the result of a map - the map is meaningless.
We should think better about those scenarios and implement checks for them
We need expectations that checks for the presence of pattern matching in a functional equation
Pattern matching occurs when when any of the clauses of a functions contains a pattern that is not a variable pattern:
foo (x:_) = True
Add an inspection that tells whether an expression is the result of parsing a given piece of code.
Such expressions allows to:
It returns mulang: Maybe.fromJust: Nothing.
Original code:
procedure MoverSegunBolitas() {
if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde) > 10) {
Mover(Este)
} else {
Mover(Norte)
}
}
AST:
➜ echo "procedure MoverSegunBolitas() {\n if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde) > 10) {\n Mover(Este)\n }\nelse {\n Mover(Norte)\n }\n }" | rungs
[
{
"name": "MoverSegunBolitas",
"arity": "routine",
"alias": "procedureDeclaration",
"parameters": [],
"body": [
{
"alias": "if",
"condition": {
"alias": "GraterOperation",
"left": {
"alias": "SumOperation",
"left": {
"alias": "SumOperation",
"left": {
"alias": "SumOperation",
"left": {
"arity": "binary",
"alias": "numStones",
"parameters": [
{
"value": 0,
"alias": "Blue"
}
]
},
"right": {
"arity": "binary",
"alias": "numStones",
"parameters": [
{
"value": 2,
"alias": "Black"
}
]
},
"arity": "binary"
},
"right": {
"arity": "binary",
"alias": "numStones",
"parameters": [
{
"value": 1,
"alias": "Red"
}
]
},
"arity": "binary"
},
"right": {
"arity": "binary",
"alias": "numStones",
"parameters": [
{
"value": 3,
"alias": "Green"
}
]
},
"arity": "binary"
},
"right": {
"value": 10,
"alias": "NumericLiteral"
},
"arity": "binary"
},
"trueBranch": [
{
"arity": "statement",
"alias": "MoveClaw",
"parameters": [
{
"value": [
1,
0
],
"alias": "East"
}
]
}
],
"falseBranch": [
{
"arity": "statement",
"alias": "MoveClaw",
"parameters": [
{
"value": [
0,
1
],
"alias": "North"
}
]
}
]
}
]
}
]
Mulang command:
./mulang '{
"expectations":[{
"tag":"Basic",
"binding":"x",
"inspection":"HasBiniding"}],
"code": {
"content":"procedure MoverSegunBolitas() {\n if (nroBolitas(Azul) + nroBolitas(Negro) + nroBolitas(Rojo) + nroBolitas(Verde) > 10) {\n Mover(Este)\n }\nelse {\n Mover(Norte)\n }\n }",
"language":"GobstonesAst"}
}'
mulang: Maybe.fromJust: Nothing
Add support for InheritsFrom
inspection - e.g.:
Reactor
Not:InheritsFrom:List
: class Reactor
must not inherit from List
InheritsFrom:List
: there must be a class that inherits from from List
InheritsFrom:^Person
: there must be a class that is not a Person
Also we could add UsesInheritance
, to check that a class declaration indicates superclass.
usesUnifyOperator
usesUnificationOperator
usesIsInUnification
hasRedudantReduction
We need:
Raises
Catches
It would be nice to have an inspector for code like this:
if (condition) {
} else {
doSomething()
}
and this
if (condition) {
doSomething()
} else {
}
Ejercicio: La historia sin fin
Solución:
infinitosUnos = 1:infinitosUnos
u otra solución:
infinitosUnos = [1,1..]
Estado: errored
See http://algo2-undav.mumuki.io/guides/pdep-utn/mumuki-guia-funcional-recursividad
Error completo:
Invalid JSON :
A JSON text must at least contain two octets!:
/var/lib/gems/2.0.0/gems/mumukit-core-0.1.3/lib/mumukit/core/json.rb:7:in rescue in pretty_parse' /var/lib/gems/2.0.0/gems/mumukit-core-0.1.3/lib/mumukit/core/json.rb:5:in
pretty_parse'
/var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/templates/mulang_expectations_hook.rb:16:in post_process_file' /var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/templates/file_hook.rb:11:in
run!'
/var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/server/test_server.rb:86:in compile_and_run' /var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/server/test_server.rb:72:in
run_expectations!'
/var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/server/test_server.rb:36:in block in test!' /var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/server/test_server.rb:111:in
respond_to'
/var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/server/test_server.rb:34:in test!' /var/lib/gems/2.0.0/gems/mumukit-2.5.0/lib/mumukit/server/app.rb:51:in
block in class:App'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1611:in call' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1611:in
block in compile!'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:975:in []' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:975:in
block (3 levels) in route!'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:994:in route_eval' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:975:in
block (2 levels) in route!'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1015:in block in process_route' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1013:in
catch'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1013:in process_route' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:973:in
block in route!'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:972:in each' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:972:in
route!'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1085:in block in dispatch!' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in
block in invoke'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in catch' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in
invoke'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1082:in dispatch!' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:907:in
block in call!'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in block in invoke' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in
catch'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1067:in invoke' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:907:in
call!'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:895:in call' /var/lib/gems/2.0.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in
call'
/var/lib/gems/2.0.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in call' /var/lib/gems/2.0.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in
call'
/var/lib/gems/2.0.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in call' /var/lib/gems/2.0.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in
call'
/var/lib/gems/2.0.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in call' /var/lib/gems/2.0.0/gems/rack-1.6.4/lib/rack/logger.rb:15:in
call'
/var/lib/gems/2.0.0/gems/rack-1.6.4/lib/rack/commonlogger.rb:33:in call' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:219:in
call'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:212:in call' /var/lib/gems/2.0.0/gems/rack-1.6.4/lib/rack/head.rb:13:in
call'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/show_exceptions.rb:25:in call' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:182:in
call'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:2013:in call' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1487:in
block in call'
/var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1787:in synchronize' /var/lib/gems/2.0.0/gems/sinatra-1.4.7/lib/sinatra/base.rb:1487:in
call'
/var/lib/gems/2.0.0/gems/puma-3.6.0/lib/puma/configuration.rb:225:in call' /var/lib/gems/2.0.0/gems/puma-3.6.0/lib/puma/server.rb:578:in
handle_request'
/var/lib/gems/2.0.0/gems/puma-3.6.0/lib/puma/server.rb:415:in process_client' /var/lib/gems/2.0.0/gems/puma-3.6.0/lib/puma/server.rb:275:in
block in run'
/var/lib/gems/2.0.0/gems/puma-3.6.0/lib/puma/thread_pool.rb:116:in call' /var/lib/gems/2.0.0/gems/puma-3.6.0/lib/puma/thread_pool.rb:116:in
block in spawn_thread'
From issue mumuki/mumuki-laboratory#514
Suppose the expectation for f is HasUsage:g, the following solutions for f pass the expectation
f list x = elem (g x) list
f list = flip elem list.g
f list x= any (\y -> y == g x) list
But these ones (and similar where g is applied as part of the parameter of a higher order function) do not, and end up stating g is not used:
f list x= any (== g x) list
f list x= ((>0).length.filter (== g x)) list
We need two inspections for checking that a computation has N clauses or equations:
declaresWithEquationsCount
declaresWithClausesCount
It should be similar in type signature to declaresWithArity
:
Should be great disable particular smells for some exercises.
Add smell detection for expressiveness:
Perhaps we should be able to deactive such smells detection sometimes.
Our next goal should be implement a Mulang parser for Prolog, since it is very simple and lets us test logic expectations
We should be able to check for common patterns of logic duplication: similar functions, predicates, identical consult pairs, and so on.
It would be nice if mulang could support signatures generation. For example, given the following haskell code:
foo :: Int -> Int
foo x = x + 1
It should produce
[TypedSignature "foo" ["Int"] "Int"]
foo :: Int -> Int
And given the following Prolog code:
foo(X, X).
foo(X, Y) :- bar(Y).
It should produce
[UntypedSignature "foo" 2]
foo/2
It would really speed up process of adding native languages support if ANTLR - for which there are dozens of popular languages grammars https://github.com/antlr/grammars-v4 - could generate Haskell an AST encoded in data's.
We should investigate about that
Add support for classes, interfaces and mixins declarations, and checks about them:
declaresClass
declaresMixin
declaresInterface
inheritsFromClass
includesMixin
implementsInterface
associatesWith
Also, declares
should be extended to support them
Support wollok as an input language
Use GHC 8 custom patterns https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms
We should consider moving to stack
, which is getting a de-facto standard.
It would be nice if mulang could detect things like:
UsesDynamicPolymorphism
UsesStaticPolymorphism
They should include:
hasNegation
- it could also work for functional and imperative languageshasForAll
- checks if a universal quantifier existshasFindall
- I actually don't like that name...hasEmptyCatch
rethrowsAsIs
: when catch just rethrows what has catched it "is True when scoped in a class, through a superclass" $ do
scoped (declaresMethod (named "foo")) "B" (java "class B extends A {} class A { void foo() {} }") `shouldBe` True
We should move to the latest 0.6
language.javascript
package, since it contains a much simpler and easy-to-maintain JavaScript AST.
There are still some missing features, like try-catch.
Travis compilation times have increased from 5 minutes (https://travis-ci.org/mumuki/mulang/builds/144797541) some months ago to up to 20 minutes now.
It would be great to have an implicit inspection to raise attention to this sort of solutions:
promediosSinAplazos ((x:xs):ys) = (map average . filtrarAprobados) ((x:xs):ys)
Originally mumuki/mumuki-laboratory#497
We need two other combiners that allows to count the number of matches of a given Inspection:
countAtLeast :: Int -> Inspection -> Inspection
countAtMost :: Int -> Inspection -> Inspection
Both combiners should count them lazily.
Introducing this combiner may need a refactor that splits the current inspector functions into a core function and containsExpression
It should consider a type test only to string comparisons that are in an if
or case
expression.
See
franco@xinaiu:~/tmp/mumuki/mulang$ ./dist/build/mulang/mulang '{
"expectations":[{
"tag":"Basic",
"binding":"x",
"inspection":"HasBinding"}],
"code": {
"content":"x = \"¡\"",
"language":"Haskell"}
}'
mulang: "Error in $: Failed reading: Cannot decode byte '\\xa1': Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream"
It would be nice if Mulang could detect expressions like puts "foo"
, System.out.println("foo")
, console.log("foo")
, and so on.
Now when expectation is invallid, no json is generated . This breaks mumukit
It would be nice to have a way to check if some class implements some interface
For example, it would be nice that C-like languages produce the following code for a typed signature:
foo(A, B)
While haskell-like languages, produce the following code:
foo :: A -> B
Improve reporting of parsing errors: return an especial analysis result instead of returning an empty json, something like the following:
data AnalysisResult = SuccessfullAnalysis {
expectationResults :: [ExpectationResult],
detectedSmells :: [Expectation],
signatures :: [Code] }
| FailedAnalysis String
deconstructs
: for checking that a given argument is deconstructedusesAnd
, usesDistinct
We need more expectations and support for imperative languages.
usesSwitch
usesFor
declaresProcedure
declaresRecord
@faloi please suggest here what you need for Gobstones
@faloi please type here
It would be nice if mulang allowed code to be translated from one language into another for simple pieces of code, e.g. function signatures.
With this code...
esBisiesto anio = ((|| (cond2 anio)).cond1) anio
Throw...
esBisiesto tiene parámetros innecesarios (se pueden eliminar mediante point-free)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.