Created
March 4, 2017 16:24
-
-
Save andywer/a19b67fca9bea66ca71fce14a909800f to your computer and use it in GitHub Desktop.
Babylon plugin for elm/haskell-ish type declarations
This file contains hidden or 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
// src/plugins/dctypes.js | |
import { types as tt } from "../tokenizer/types"; | |
import { types as ct } from "../tokenizer/context"; | |
import Parser from "../parser"; | |
import "./flow"; | |
const pp = Parser.prototype; | |
export default function (instance) { | |
instance.extend("parseStatement", function (inner) { | |
return function (declaration, topLevel) { | |
const lookahead = this.lookahead(); | |
if (this.match(tt.name) && lookahead.type === tt.doubleColon) { | |
const declarationNode = this.startNode(); | |
const identifierNode = this.parseIdentifier(); | |
this.expect(tt.doubleColon); | |
return this.dctypesParseTypeDefinition(declarationNode, identifierNode); | |
} else { | |
return inner.call(this, declaration, topLevel); | |
} | |
}; | |
}); | |
// Slightly hacky solution to parse type declarations in class body: | |
// Make isClassProperty() return true on them, patch parseClassProperty() | |
instance.extend("isClassProperty", function (inner) { | |
return function () { | |
return inner.call(this) || this.match(tt.doubleColon); | |
}; | |
}); | |
instance.extend("parseClassProperty", function (inner) { | |
return function (node) { | |
if (this.match(tt.doubleColon)) { | |
const identifierNode = node.key; | |
delete node.key; | |
this.expect(tt.doubleColon); | |
return this.dctypesParseTypeDefinition(node, identifierNode); | |
} else { | |
return inner.call(this, node); | |
} | |
}; | |
}); | |
} | |
pp.dctypesParseTypeDefinition = function dctypesParseTypeDefinition (declarationNode, identifierNode) { | |
declarationNode.id = identifierNode; | |
declarationNode.typeAnnotation = this.flowParseType(); | |
this.semicolon(); | |
return this.finishNode(declarationNode, "TypeDeclaration"); | |
}; |
This file contains hidden or 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
--- a/src/index.js | |
+++ b/src/index.js | |
@@ -14,9 +14,11 @@ import "./tokenizer/context"; | |
import estreePlugin from "./plugins/estree"; | |
import flowPlugin from "./plugins/flow"; | |
import jsxPlugin from "./plugins/jsx"; | |
+import dctypesPlugin from "./plugins/dctypes"; | |
plugins.estree = estreePlugin; | |
plugins.flow = flowPlugin; | |
plugins.jsx = jsxPlugin; | |
+plugins.dctypes = dctypesPlugin; | |
export function parse(input, options) { | |
return new Parser(options, input).parse(); |
This file contains hidden or 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
// test.js | |
const babylon = require('./lib') | |
const code = ` | |
add :: (number, number) => number | |
class Foo { | |
print :: string => undefined | |
print (string) { | |
console.log(string) | |
} | |
} | |
` | |
const parserOptions = { | |
plugins: ['dctypes'] | |
} | |
parse() | |
function parse () { | |
const ast = babylon.parse(code, parserOptions) | |
console.log( | |
JSON.stringify(ast.program, null, 2) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment