Skip to content

JSX #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v2.2.0-dev
* Enhancements:
* Added structs for JSX AST

# v2.1.2

* Bug fixes
Expand Down
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Defines structs that represent the JavaScript AST nodes from the ESTree spec.

[ESTree Spec](https://github.com/estree/estree)

[JSX AST Spec](https://github.com/facebook/jsx)

Also includes a JavaScript AST to JavaScript code generator.

```elixir
Expand All @@ -16,5 +18,23 @@ ast = Builder.array_expression([
])

Generator.generate(ast)
#"[1, a]"
```
# "[1, a]"

#jsx ast and generation
ast = Builder.jsx_element(
Builder.jsx_opening_element(
Builder.jsx_identifier(
"Test"
)
),
[],
Builder.jsx_closing_element(
Builder.jsx_identifier(
"Test"
)
)
)

Generator.generate(ast)
# "<Test></Test>"
```
9 changes: 9 additions & 0 deletions lib/es_tree/jsx_attribute.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule ESTree.JSXAttribute do
@type t :: %ESTree.JSXAttribute{
type: binary,
loc: ESTree.SourceLocation.t | nil,
name: ESTree.JSXIdentifier.t | ESTree.JSXNamespacedName.t,
value: ESTree.Literal.t | ESTree.JSXExpressionContainer.t | ESTree.JSXElement.t | nil
}
defstruct type: "JSXAttribute", loc: nil, name: nil, value: nil
end
8 changes: 8 additions & 0 deletions lib/es_tree/jsx_closing_element.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule ESTree.JSXClosingElement do
@type t :: %ESTree.JSXClosingElement{
type: binary,
loc: ESTree.SourceLocation.t | nil,
name: ESTree.JSXIdentifier.t | ESTree.JSXMemberExpression.t | ESTree.JSXNamespacedName.t
}
defstruct type: "JSXClosingElement", loc: nil, name: nil
end
10 changes: 10 additions & 0 deletions lib/es_tree/jsx_element.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule ESTree.JSXElement do
@type t :: %ESTree.JSXElement{
type: binary,
loc: ESTree.SourceLocation.t | nil,
openingElement: ESTree.JSXOpeningElement.t,
children: [ESTree.Literal.t | ESTree.JSXExpressionContainer.t | ESTree.JSXElement.t],
closingElement: ESTree.JSXClosingElement.t | nil
}
defstruct type: "JSXElement", loc: nil, openingElement: nil, children: [], closingElement: nil
end
4 changes: 4 additions & 0 deletions lib/es_tree/jsx_empty_expression.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
defmodule ESTree.JSXEmptyExpression do
@type t :: %ESTree.JSXEmptyExpression{ type: binary, loc: ESTree.SourceLocation.t | nil }
defstruct type: "JSXEmptyExpression", loc: nil
end
9 changes: 9 additions & 0 deletions lib/es_tree/jsx_expression_container.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule ESTree.JSXExpressionContainer do
@type t :: %ESTree.JSXExpressionContainer{
type: binary,
loc: ESTree.SourceLocation.t | nil,
expression: ESTree.Expression.t | JSXEmptyExpression.t
}

defstruct type: "JSXExpressionContainer", loc: nil, expression: %ESTree.JSXEmptyExpression{}
end
9 changes: 9 additions & 0 deletions lib/es_tree/jsx_identifier.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule ESTree.JSXIdentifier do
@type t :: %ESTree.JSXIdentifier{
type: binary,
loc: ESTree.SourceLocation.t | nil,
name: binary
}

defstruct type: "JSXIdentifier", loc: nil, name: nil
end
14 changes: 14 additions & 0 deletions lib/es_tree/jsx_member_expression.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule ESTree.JSXMemberExpression do
@type t :: %ESTree.JSXMemberExpression{
type: binary,
loc: ESTree.SourceLocation.t | nil,
object: ESTree.JSXMemberExpression.t | ESTree.JSXIdentifier.t,
property: ESTree.JSXIdentifier.t
}

defstruct type: "JSXMemberExpression",
loc: nil,
object: nil,
property: nil

end
14 changes: 14 additions & 0 deletions lib/es_tree/jsx_namespaced_name.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule ESTree.JSXNamespacedName do
@type t :: %ESTree.JSXNamespacedName{
type: binary,
loc: ESTree.SourceLocation.t | nil,
namespace: ESTree.JSXIdentifier.t,
name: ESTree.JSXIdentifier.t
}

defstruct type: "JSXNamespacedName",
loc: nil,
namespace: nil,
name: nil

end
10 changes: 10 additions & 0 deletions lib/es_tree/jsx_opening_element.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule ESTree.JSXOpeningElement do
@type t :: %ESTree.JSXOpeningElement{
type: binary,
loc: ESTree.SourceLocation.t | nil,
name: ESTree.JSXIdentifier.t | ESTree.JSXMemberExpression.t | ESTree.JSXNamespacedName.t,
attributes: [ ESTree.JSXAttribute.t | ESTree.JSXSpreadAttribute.t ],
selfClosing: boolean
}
defstruct type: "JSXOpeningElement", loc: nil, name: nil, attributes: [], selfClosing: false
end
10 changes: 10 additions & 0 deletions lib/es_tree/jsx_spread_attribute.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule ESTree.JSXSpreadAttribute do
@type t :: %ESTree.JSXSpreadAttribute{
type: binary,
loc: ESTree.SourceLocation.t | nil,
argument: ESTree.Expression.t
}
defstruct type: "JSXSpreadAttribute",
loc: nil,
argument: %ESTree.EmptyExpression{}
end
111 changes: 111 additions & 0 deletions lib/es_tree/tools/builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -770,4 +770,115 @@ defmodule ESTree.Tools.Builder do
argument: argument, loc: loc, delegate: delegate
}
end


@spec jsx_identifier(
binary,
ESTree.SourceLocation.t | nil
) :: ESTree.JSXIdentifier.t
def jsx_identifier(name, loc \\ nil) do
%ESTree.JSXIdentifier{
name: name, loc: loc
}
end


@spec jsx_member_expression(
ESTree.JSXMemberExpression.t | ESTree.JSXIdentifier.t,
ESTree.JSXIdentifier.t,
ESTree.SourceLocation.t | nil
) :: ESTree.MemberExpression.t
def jsx_member_expression(object, property, loc \\ nil) do
%ESTree.JSXMemberExpression{
object: object, property: property, loc: loc
}
end

@spec jsx_namespaced_name(
ESTree.JSXIdentifier.t,
ESTree.JSXIdentifier.t,
ESTree.SourceLocation.t | nil
) :: ESTree.JSXNamespacedName.t
def jsx_namespaced_name(namespace, name, loc \\ nil) do
%ESTree.JSXNamespacedName{
namespace: namespace, name: name, loc: loc
}
end

@spec jsx_empty_expression(
ESTree.SourceLocation.t | nil
) :: ESTree.JSXEmptyExpression.t
def jsx_empty_expression(loc \\ nil) do
%ESTree.JSXEmptyExpression{
loc: loc
}
end

@spec jsx_expression_container(
ESTree.Expression.t | ESTree.JSXEmptyExpression.t,
ESTree.SourceLocation.t | nil
) :: ESTree.JSXExpressionContainer.t
def jsx_expression_container(expression, loc \\ nil) do
%ESTree.JSXExpressionContainer{
expression: expression, loc: loc
}
end


@spec jsx_opening_element(
ESTree.JSXIdentifier.t | ESTree.JSXMemberExpression.t | ESTree.JSXNamespacedName.t,
[ ESTree.JSXAttribute.t | ESTree.JSXSpreadAttribute.t ],
boolean,
ESTree.SourceLocation.t | nil
) :: ESTree.JSXOpeningElement.t
def jsx_opening_element(name, attributes \\ [], selfClosing \\ false, loc \\ nil) do
%ESTree.JSXOpeningElement{
name: name, attributes: attributes, selfClosing: selfClosing, loc: loc
}
end


@spec jsx_closing_element(
ESTree.JSXIdentifier.t | ESTree.JSXMemberExpression.t | ESTree.JSXNamespacedName.t,
ESTree.SourceLocation.t | nil
) :: ESTree.JSXClosingElement.t
def jsx_closing_element(name, loc \\ nil) do
%ESTree.JSXClosingElement{
name: name, loc: loc
}
end


@spec jsx_attribute(
ESTree.JSXIdentifier.t | ESTree.JSXNamespacedName.t,
ESTree.Literal.t | ESTree.JSXExpressionContainer.t | ESTree.JSXElement.t | nil,
ESTree.SourceLocation.t | nil
) :: ESTree.JSXAttribute.t
def jsx_attribute(name, value \\ nil, loc \\ nil) do
%ESTree.JSXAttribute{
name: name, value: value, loc: loc
}
end

@spec jsx_spread_attribute(
ESTree.Expression.t | nil,
ESTree.SourceLocation.t | nil
) :: ESTree.SpreadElement.t
def jsx_spread_attribute(argument, loc \\ nil) do
%ESTree.JSXSpreadAttribute{
argument: argument, loc: loc
}
end

@spec jsx_element(
ESTree.JSXOpeningElement.t,
[ESTree.Literal.t | ESTree.JSXExpressionContainer.t | ESTree.JSXElement.t],
ESTree.JSXClosingElement.t | nil,
ESTree.SourceLocation.t | nil
) :: ESTree.JSXElement.t
def jsx_element(openingElement, children \\ [], closingElement \\ nil, loc \\ nil) do
%ESTree.JSXElement{
openingElement: openingElement, children: children, closingElement: closingElement, loc: loc
}
end
end
42 changes: 42 additions & 0 deletions lib/es_tree/tools/generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,48 @@ defmodule ESTree.Tools.Generator do
"await #{generate(argument)}"
end

def do_generate(%ESTree.JSXIdentifier{ name: name }, level) do
"#{name}"
end

def do_generate(%ESTree.JSXMemberExpression{ object: object, property: property }, level) do
"#{ generate(object) }.#{ generate(property) }"
end

def do_generate(%ESTree.JSXNamespacedName{ namespace: namespace, name: name }, level) do
"#{ generate(namespace) }:#{ generate(name) }"
end

def do_generate(%ESTree.JSXEmptyExpression{}, level) do
""
end

def do_generate(%ESTree.JSXExpressionContainer{ expression: expression }, level) do
"{#{ generate(expression) }}"
end

def do_generate(%ESTree.JSXOpeningElement{ name: name, attributes: attributes, selfClosing: selfClosing }, level) do
selfClosing = if selfClosing, do: "/", else: ""

"<#{generate(name)} #{ Enum.map(attributes, &generate(&1)) |> Enum.join(" ") }#{selfClosing}>"
end

def do_generate(%ESTree.JSXClosingElement{ name: name }, level) do
"</#{ generate(name) }>"
end

def do_generate(%ESTree.JSXAttribute{ name: name, value: value }, level) do
"#{ generate(name) }=#{ generate(value) }"
end

def do_generate(%ESTree.JSXSpreadAttribute{ argument: argument }, level) do
"{...#{ generate(argument) }}"
end

def do_generate(%ESTree.JSXElement{ openingElement: openingElement, children: children, closingElement: closingElement }, level) do
"#{ generate(openingElement) } #{ Enum.map(children, &generate(&1, level + 1)) |> Enum.join(" ") } #{ generate(closingElement) }"
end

defp convert_string_characters(str) do
String.replace(str, "\n", "\\n")
|> String.replace("\t", "\\t")
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule ESTree.Mixfile do

def project do
[app: :estree,
version: "2.1.2",
version: "2.2.0-dev",
elixir: "~> 1.0",
deps: deps,
description: description,
Expand Down
Loading