-
-
Notifications
You must be signed in to change notification settings - Fork 84
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
f7c2bc0
commit d3c7f17
Showing
19 changed files
with
611 additions
and
24 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
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,38 @@ | ||
# frozen_string_literal: true | ||
|
||
module Fixtures | ||
module Compilation | ||
module VCall | ||
class WithStandardElement < Phlex::Component | ||
def template | ||
div | ||
end | ||
end | ||
|
||
class WithVoidElement < Phlex::Component | ||
def template | ||
img | ||
end | ||
end | ||
|
||
class WithAnotherMethodCall < Phlex::Component | ||
def template | ||
article | ||
some_other_method | ||
article | ||
end | ||
end | ||
|
||
class WithRedefinedTagMethod < Phlex::Component | ||
def template | ||
title | ||
article | ||
end | ||
|
||
def title | ||
h1 | ||
end | ||
end | ||
end | ||
end | ||
end |
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
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
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,50 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
def initialize(component) | ||
@component = component | ||
end | ||
|
||
def inspect | ||
"#{self.class.name} for #{@component.name} component class" | ||
end | ||
|
||
def call | ||
Visitors::File.new(self).visit(tree) | ||
end | ||
|
||
def redefined?(method_name) | ||
prototype = @component.allocate | ||
|
||
@component.instance_method(method_name).bind(prototype) != | ||
Phlex::Component.instance_method(method_name).bind(prototype) | ||
end | ||
|
||
def redefine(method) | ||
@component.class_eval(method) | ||
end | ||
|
||
def line | ||
location[1] | ||
end | ||
|
||
private | ||
|
||
def tree | ||
@tree ||= SyntaxTree.parse(source) | ||
end | ||
|
||
def source | ||
SyntaxTree.read(file) | ||
end | ||
|
||
def file | ||
location[0] | ||
end | ||
|
||
def location | ||
::Module.const_source_location(@component.name) | ||
end | ||
end | ||
end |
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,64 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
class Formatter < SyntaxTree::Formatter | ||
def genspace | ||
-> (n) { "\t" * (n / 2) } | ||
end | ||
|
||
def format(node, stackable: true) | ||
stack << node if stackable | ||
doc = node.format(self) | ||
stack.pop if stackable | ||
doc | ||
end | ||
|
||
def flush | ||
text "" if @open_append | ||
|
||
super | ||
end | ||
|
||
def breakable(*args, **kwargs) | ||
if !@texting && @open_append | ||
@broken = kwargs | ||
else | ||
super | ||
end | ||
end | ||
|
||
def append(&block) | ||
@appending = true | ||
|
||
unless @open_append | ||
text %(@_target << ") | ||
@open_append = true | ||
end | ||
|
||
yield(self) | ||
|
||
@appending = false | ||
end | ||
|
||
def text(value, ...) | ||
@texting = true | ||
|
||
unless @appending | ||
if @open_append | ||
super('"') | ||
@open_append = false | ||
end | ||
|
||
breakable(**@broken) if @broken | ||
end | ||
|
||
@broken = false | ||
|
||
super | ||
|
||
@texting = false | ||
end | ||
end | ||
end | ||
end |
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,30 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
module Generators | ||
class StandardElement | ||
def initialize(formatter, method_name:, arguments: nil) | ||
@formatter = formatter | ||
@method_name = method_name | ||
end | ||
|
||
def call | ||
@formatter.append do |f| | ||
f.text "<" | ||
f.text tag | ||
f.text ">" | ||
|
||
f.text "</" | ||
f.text tag | ||
f.text ">" | ||
end | ||
end | ||
|
||
def tag | ||
HTML::STANDARD_ELEMENTS[@method_name] | ||
end | ||
end | ||
end | ||
end | ||
end |
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,29 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
module Generators | ||
class VoidElement | ||
def initialize(formatter, method_name:, arguments: nil) | ||
@formatter = formatter | ||
@method_name = method_name | ||
@arguments = arguments | ||
end | ||
|
||
def call | ||
@formatter.append do |f| | ||
f.text "<" | ||
f.text tag | ||
f.text " />" | ||
end | ||
end | ||
|
||
private | ||
|
||
def tag | ||
HTML::VOID_ELEMENTS[@method_name] | ||
end | ||
end | ||
end | ||
end | ||
end |
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,23 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
module Optimizers | ||
module VCall | ||
module StandardElement | ||
def format(formatter) | ||
Generators::StandardElement.new(formatter, | ||
method_name: value.value.to_sym).call | ||
end | ||
end | ||
|
||
module VoidElement | ||
def format(formatter) | ||
Generators::VoidElement.new(formatter, | ||
method_name: value.value.to_sym).call | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
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,19 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
module Visitors | ||
class Base < SyntaxTree::Visitor | ||
def initialize(compiler = nil) | ||
@compiler = compiler | ||
end | ||
|
||
private | ||
|
||
def format(node) | ||
Formatter.format("", node) | ||
end | ||
end | ||
end | ||
end | ||
end |
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,28 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
module Visitors | ||
class Component < Base | ||
visit_method def visit_def(node) | ||
visitor = Visitors::ComponentMethod.new(@compiler) | ||
visitor.visit_all(node.child_nodes) | ||
|
||
if visitor.optimized_something? | ||
@compiler.redefine( | ||
format(node) | ||
) | ||
end | ||
end | ||
|
||
visit_method def visit_class(node) | ||
nil | ||
end | ||
|
||
visit_method def visit_module(node) | ||
nil | ||
end | ||
end | ||
end | ||
end | ||
end |
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,35 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
module Visitors | ||
class ComponentMethod < Base | ||
def optimized_something? | ||
!!@optimized_something | ||
end | ||
|
||
visit_method def visit_vcall(node) | ||
name = node.value.value.to_sym | ||
|
||
if HTML::STANDARD_ELEMENTS[name] && !@compiler.redefined?(name) | ||
@optimized_something = true | ||
node.extend(Optimizers::VCall::StandardElement) | ||
elsif HTML::VOID_ELEMENTS[name] && !@compiler.redefined?(name) | ||
@optimized_something = true | ||
node.extend(Optimizers::VCall::VoidElement) | ||
end | ||
|
||
super | ||
end | ||
|
||
visit_method def visit_class(node) | ||
nil | ||
end | ||
|
||
visit_method def visit_module(node) | ||
nil | ||
end | ||
end | ||
end | ||
end | ||
end |
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,17 @@ | ||
# frozen_string_literal: true | ||
|
||
module Phlex | ||
class Compiler | ||
module Visitors | ||
class File < Base | ||
visit_method def visit_class(node) | ||
if node.location.start_line == @compiler.line | ||
Visitors::Component.new(@compiler).visit_all(node.child_nodes) | ||
else | ||
super | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.