From 3037cd11207ce381532e17dcbadadc18a786264f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szikszai=20Guszt=C3=A1v?= Date: Tue, 12 Nov 2024 16:18:37 +0100 Subject: [PATCH] Refactor how location of nodes are calculated. Instead of calculating the location (line, column) of a node after the fact it is now part of the parser. --- benchmark/benchmark_core_parsing.cr | 14 +++ spec/ast/node_spec.cr | 21 ++--- src/ast.cr | 47 ++++------ src/ast/access.cr | 8 +- src/ast/argument.cr | 8 +- src/ast/array_destructuring.cr | 8 +- src/ast/array_literal.cr | 8 +- src/ast/await.cr | 8 +- src/ast/block.cr | 6 +- src/ast/bool_literal.cr | 8 +- src/ast/bracket_access.cr | 8 +- src/ast/builtin.cr | 8 +- src/ast/call.cr | 6 +- src/ast/case.cr | 6 +- src/ast/case_branch.cr | 6 +- src/ast/comment.cr | 8 +- src/ast/component.cr | 4 +- src/ast/connect.cr | 6 +- src/ast/connect_variable.cr | 8 +- src/ast/constant.cr | 8 +- src/ast/css_definition.cr | 6 +- src/ast/css_font_face.cr | 6 +- src/ast/css_keyframes.cr | 6 +- src/ast/css_nested_at.cr | 8 +- src/ast/css_selector.cr | 6 +- src/ast/dbg.cr | 8 +- src/ast/decode.cr | 8 +- src/ast/defer.cr | 8 +- src/ast/directives/file_based.cr | 6 +- src/ast/directives/format.cr | 8 +- src/ast/directives/highlight.cr | 8 +- src/ast/discard.cr | 6 +- src/ast/emit.cr | 8 +- src/ast/encode.cr | 8 +- src/ast/env.cr | 8 +- src/ast/field.cr | 8 +- src/ast/field_access.cr | 8 +- src/ast/for.cr | 6 +- src/ast/function.cr | 6 +- src/ast/get.cr | 8 +- src/ast/here_document.cr | 6 +- src/ast/html_attribute.cr | 8 +- src/ast/html_component.cr | 10 +- src/ast/html_element.cr | 10 +- src/ast/html_fragment.cr | 6 +- src/ast/html_style.cr | 8 +- src/ast/id.cr | 8 +- src/ast/if.cr | 8 +- src/ast/inline_function.cr | 6 +- src/ast/interpolation.cr | 8 +- src/ast/js.cr | 6 +- src/ast/locale.cr | 8 +- src/ast/locale_key.cr | 8 +- src/ast/map.cr | 6 +- src/ast/map_field.cr | 8 +- src/ast/module.cr | 4 +- src/ast/negated_expression.cr | 8 +- src/ast/next_call.cr | 8 +- src/ast/node.cr | 119 +++++------------------- src/ast/number_literal.cr | 8 +- src/ast/operation.cr | 8 +- src/ast/parenthesized_expression.cr | 8 +- src/ast/pipe.cr | 8 +- src/ast/property.cr | 8 +- src/ast/provider.cr | 4 +- src/ast/record.cr | 8 +- src/ast/record_update.cr | 8 +- src/ast/regexp_literal.cr | 8 +- src/ast/return_call.cr | 8 +- src/ast/route.cr | 6 +- src/ast/routes.cr | 6 +- src/ast/signal.cr | 8 +- src/ast/spread.cr | 8 +- src/ast/state.cr | 8 +- src/ast/state_setter.cr | 8 +- src/ast/statement.cr | 8 +- src/ast/store.cr | 4 +- src/ast/string_literal.cr | 6 +- src/ast/style.cr | 6 +- src/ast/suite.cr | 6 +- src/ast/test.cr | 8 +- src/ast/tuple_destructuring.cr | 6 +- src/ast/tuple_literal.cr | 6 +- src/ast/type.cr | 4 +- src/ast/type_definition.cr | 4 +- src/ast/type_definition_field.cr | 6 +- src/ast/type_destructuring.cr | 6 +- src/ast/type_variable.cr | 8 +- src/ast/type_variant.cr | 4 +- src/ast/unary_minus.cr | 8 +- src/ast/use.cr | 8 +- src/ast/variable.cr | 8 +- src/compilers/dbg.cr | 2 +- src/compilers/suite.cr | 8 +- src/compilers/test.cr | 8 +- src/errorable.cr | 10 +- src/formatter/processor.cr | 2 +- src/formatters/top_level.cr | 2 +- src/ls/code_actions/module_actions.cr | 2 +- src/ls/code_actions/provider_actions.cr | 2 +- src/ls/definitions.cr | 20 ++-- src/ls/definitions/variable.cr | 11 ++- src/ls/folding_range.cr | 17 ++-- src/ls/semantic_tokens.cr | 15 +-- src/parser.cr | 42 ++++++--- src/parser/location.cr | 30 ++++++ src/parsers/html_element.cr | 2 +- src/parsers/operator.cr | 4 +- src/parsers/type_destructuring.cr | 35 ++++--- src/scope.cr | 7 +- src/semantic_tokenizer.cr | 24 ++--- src/style_builder.cr | 2 +- src/test_runner/message.cr | 10 +- src/utils/source_map_generator.cr | 9 +- 114 files changed, 543 insertions(+), 548 deletions(-) create mode 100644 benchmark/benchmark_core_parsing.cr create mode 100644 src/parser/location.cr diff --git a/benchmark/benchmark_core_parsing.cr b/benchmark/benchmark_core_parsing.cr new file mode 100644 index 000000000..bf19a5c32 --- /dev/null +++ b/benchmark/benchmark_core_parsing.cr @@ -0,0 +1,14 @@ +require "benchmark" +require "../src/all" + +module Mint + Benchmark.ips(warmup: 4.seconds, calculation: 10.seconds) do |x| + x.report("Core parsing") do + Core.files.reduce(Ast.new) do |memo, file| + Parser.parse(file.read, file.path).try do |ast| + memo.merge(ast) + end + end + end + end +end diff --git a/spec/ast/node_spec.cr b/spec/ast/node_spec.cr index 03d1c8e12..0ab0ee116 100644 --- a/spec/ast/node_spec.cr +++ b/spec/ast/node_spec.cr @@ -12,32 +12,31 @@ describe Mint::Ast::Node do } MINT - location = + node = Mint::Parser .parse(example, "example.mint") .components .first .functions .first - .location - location.start.should eq({2, 2}) + {node.from.line, node.from.column}.should eq({2, 2}) # actually {4, 2} but all parsers go over by 1 - location.end.should eq({4, 3}) + {node.to.line, node.to.column}.should eq({4, 3}) # First line - location.contains?(2, 1).should eq(false) # space before `f` - location.contains?(2, 3).should eq(true) # `f` of `fun` + node.contains?(2, 1).should eq(false) # space before `f` + node.contains?(2, 3).should eq(true) # `f` of `fun` # Middle line - location.contains?(3, 0).should eq(true) - location.contains?(3, 9).should eq(true) - location.contains?(3, 1000).should eq(true) + node.contains?(3, 0).should eq(true) + node.contains?(3, 9).should eq(true) + node.contains?(3, 1000).should eq(true) # End line - location.contains?(4, 2).should eq(true) # `}` - location.contains?(4, 3).should eq(false) # space after `}` + node.contains?(4, 2).should eq(true) # `}` + node.contains?(4, 3).should eq(false) # space after `}` end end end diff --git a/src/ast.cr b/src/ast.cr index c2ffab43c..e97ddf98f 100644 --- a/src/ast.cr +++ b/src/ast.cr @@ -5,9 +5,9 @@ module Mint getter unified_modules, unified_locales - def initialize(@type_definitions = [] of TypeDefinition, - @operators = [] of Tuple(Int64, Int64), - @keywords = [] of Tuple(Int64, Int64), + def initialize(@operators = [] of {from: Parser::Location, to: Parser::Location}, + @keywords = [] of {from: Parser::Location, to: Parser::Location}, + @type_definitions = [] of TypeDefinition, @unified_modules = [] of Module, @unified_locales = [] of Locale, @components = [] of Component, @@ -21,26 +21,12 @@ module Mint @nodes = [] of Node) end - def main : Component? - @components.find(&.name.value.==("Main")) - end - def self.space_separated?(node1, node2) - node1.file.contents[node1.to, node2.from - node1.to].count('\n') > 1 + (node2.from.line - node1.to.line) > 1 end - def self.new_line?(node1, node2) - node1.file.contents[node1.from, node2.from - node1.from].includes?('\n') - end - - def new_line?(node1, node2) - start_position = - node1.from - - count = - node2.to - node1.from - - node1.file.contents[start_position, count].includes?('\n') + def main : Component? + @components.find(&.name.value.==("Main")) end def merge(ast) : self @@ -68,7 +54,7 @@ module Mint path : String, line : Int64 ) : Array(Ast::Node) - nodes_at_path(path).select!(&.location.contains?(line, column)) + nodes_at_path(path).select!(&.contains?(line, column)) end def nodes_at_path(path : String) : Array(Ast::Node) @@ -93,17 +79,16 @@ module Mint .group_by(&.name.value) .map do |_, modules| Module.new( - functions: modules.flat_map(&.functions), - constants: modules.flat_map(&.constants), - file: Parser::File.new(contents: "", path: ""), # TODO: We may need to store each modules name node for # future features, but for now we just store the first comment: modules.compact_map(&.comment).first?, + file: Parser::File.new(contents: "", path: ""), + functions: modules.flat_map(&.functions), + constants: modules.flat_map(&.constants), + from: Parser::Location.new, + to: Parser::Location.new, name: modules.first.name, - comments: [] of Comment, - from: 0, - to: 0, - ) + comments: [] of Comment) end @unified_locales = @@ -114,9 +99,9 @@ module Mint file: Parser::File.new(contents: "", path: ""), fields: locales.flat_map(&.fields), language: locales.first.language, - comment: nil, - from: 0, - to: 0) + from: Parser::Location.new, + to: Parser::Location.new, + comment: nil) end self diff --git a/src/ast/access.cr b/src/ast/access.cr index 81b6f00c1..bb47cda69 100644 --- a/src/ast/access.cr +++ b/src/ast/access.cr @@ -10,12 +10,12 @@ module Mint Dot end - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @expression : Node, @field : Variable, - @from : Int64, - @type : Type, - @to : Int64) + @type : Type) end end end diff --git a/src/ast/argument.cr b/src/ast/argument.cr index 3a7a1b6f3..d97ec2d79 100644 --- a/src/ast/argument.cr +++ b/src/ast/argument.cr @@ -3,12 +3,12 @@ module Mint class Argument < Node getter type, name, default - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @default : Node?, @name : Variable, - @from : Int64, - @type : Node, - @to : Int64) + @type : Node) end end end diff --git a/src/ast/array_destructuring.cr b/src/ast/array_destructuring.cr index 00e3d2ffa..879cd1c76 100644 --- a/src/ast/array_destructuring.cr +++ b/src/ast/array_destructuring.cr @@ -3,10 +3,10 @@ module Mint class ArrayDestructuring < Node getter items - def initialize(@file : Parser::File, - @items : Array(Node), - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @items : Array(Node)) end end end diff --git a/src/ast/array_literal.cr b/src/ast/array_literal.cr index f78c6c98b..f066c1aff 100644 --- a/src/ast/array_literal.cr +++ b/src/ast/array_literal.cr @@ -3,11 +3,11 @@ module Mint class ArrayLiteral < Node getter items, type - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @items : Array(Node), - @from : Int64, - @type : Node?, - @to : Int64) + @type : Node?) end end end diff --git a/src/ast/await.cr b/src/ast/await.cr index 2b2d8f1db..04cddb10c 100644 --- a/src/ast/await.cr +++ b/src/ast/await.cr @@ -3,10 +3,10 @@ module Mint class Await < Node getter body - def initialize(@file : Parser::File, - @from : Int64, - @body : Node, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @body : Node) end end end diff --git a/src/ast/block.cr b/src/ast/block.cr index d52ced77a..f70070ec5 100644 --- a/src/ast/block.cr +++ b/src/ast/block.cr @@ -4,9 +4,9 @@ module Mint getter expressions def initialize(@expressions : Array(Node), - @file : Parser::File, - @from : Int64, - @to : Int64) + @from : Parser::Location, + @to : Parser::Location, + @file : Parser::File) end end end diff --git a/src/ast/bool_literal.cr b/src/ast/bool_literal.cr index 7147eda79..1ea085efd 100644 --- a/src/ast/bool_literal.cr +++ b/src/ast/bool_literal.cr @@ -3,10 +3,10 @@ module Mint class BoolLiteral < Node getter value - def initialize(@file : Parser::File, - @value : Bool, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @value : Bool) end end end diff --git a/src/ast/bracket_access.cr b/src/ast/bracket_access.cr index 46a0ebac0..4d059f18d 100644 --- a/src/ast/bracket_access.cr +++ b/src/ast/bracket_access.cr @@ -3,11 +3,11 @@ module Mint class BracketAccess < Node getter index, expression - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @expression : Node, - @index : Node, - @from : Int64, - @to : Int64) + @index : Node) end end end diff --git a/src/ast/builtin.cr b/src/ast/builtin.cr index ed20be41b..1b3f188ff 100644 --- a/src/ast/builtin.cr +++ b/src/ast/builtin.cr @@ -3,10 +3,10 @@ module Mint class Builtin < Node getter value - def initialize(@file : Parser::File, - @value : String, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @value : String) end end end diff --git a/src/ast/call.cr b/src/ast/call.cr index f05681629..0d66f432f 100644 --- a/src/ast/call.cr +++ b/src/ast/call.cr @@ -4,11 +4,11 @@ module Mint getter arguments, expression, await def initialize(@arguments : Array(Field), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @expression : Node, - @await : Bool, - @from : Int64, - @to : Int64) + @await : Bool) end end end diff --git a/src/ast/case.cr b/src/ast/case.cr index ab0f41648..5e6296dc6 100644 --- a/src/ast/case.cr +++ b/src/ast/case.cr @@ -5,10 +5,10 @@ module Mint def initialize(@branches : Array(CaseBranch), @comments : Array(Comment), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @condition : Node, - @from : Int64, - @to : Int64) + @condition : Node) end end end diff --git a/src/ast/case_branch.cr b/src/ast/case_branch.cr index 81e53ba44..f1da8846d 100644 --- a/src/ast/case_branch.cr +++ b/src/ast/case_branch.cr @@ -4,10 +4,10 @@ module Mint getter pattern, expression def initialize(@expression : Node | Array(CssDefinition), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @pattern : Node?, - @from : Int64, - @to : Int64) + @pattern : Node?) end end end diff --git a/src/ast/comment.cr b/src/ast/comment.cr index 8a6ee314d..09d03ace7 100644 --- a/src/ast/comment.cr +++ b/src/ast/comment.cr @@ -8,12 +8,12 @@ module Mint Block end - def initialize(@next_comment : Comment?, + def initialize(@from : Parser::Location, + @next_comment : Comment?, + @to : Parser::Location, @file : Parser::File, @content : String, - @from : Int64, - @type : Type, - @to : Int64) + @type : Type) end def block? diff --git a/src/ast/component.cr b/src/ast/component.cr index bb80c210f..9096c626e 100644 --- a/src/ast/component.cr +++ b/src/ast/component.cr @@ -12,6 +12,8 @@ module Mint @functions : Array(Function), @comments : Array(Comment), @connects : Array(Connect), + @from : Parser::Location, + @to : Parser::Location, @states : Array(State), @styles : Array(Style), @file : Parser::File, @@ -21,8 +23,6 @@ module Mint @locales : Bool, @global : Bool, @async : Bool, - @from : Int64, - @to : Int64, @name : Id) end end diff --git a/src/ast/connect.cr b/src/ast/connect.cr index a395cdf81..57455cb8d 100644 --- a/src/ast/connect.cr +++ b/src/ast/connect.cr @@ -4,10 +4,10 @@ module Mint getter keys, store def initialize(@keys : Array(ConnectVariable), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @from : Int64, - @store : Id, - @to : Int64) + @store : Id) end end end diff --git a/src/ast/connect_variable.cr b/src/ast/connect_variable.cr index ac2d64fce..8882578f9 100644 --- a/src/ast/connect_variable.cr +++ b/src/ast/connect_variable.cr @@ -3,11 +3,11 @@ module Mint class ConnectVariable < Node getter target, name - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @target : Variable?, - @name : Variable, - @from : Int64, - @to : Int64) + @name : Variable) end end end diff --git a/src/ast/constant.cr b/src/ast/constant.cr index b903b8643..e433a20ac 100644 --- a/src/ast/constant.cr +++ b/src/ast/constant.cr @@ -3,12 +3,12 @@ module Mint class Constant < Node getter name, expression, comment - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @comment : Comment?, @expression : Node, - @name : Variable, - @from : Int64, - @to : Int64) + @name : Variable) end end end diff --git a/src/ast/css_definition.cr b/src/ast/css_definition.cr index cb492f457..59faf84ad 100644 --- a/src/ast/css_definition.cr +++ b/src/ast/css_definition.cr @@ -4,10 +4,10 @@ module Mint getter name, value def initialize(@value : Array(String | Node), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @name : String, - @from : Int64, - @to : Int64) + @name : String) end end end diff --git a/src/ast/css_font_face.cr b/src/ast/css_font_face.cr index 991ba36eb..51417c9f7 100644 --- a/src/ast/css_font_face.cr +++ b/src/ast/css_font_face.cr @@ -4,9 +4,9 @@ module Mint getter definitions def initialize(@definitions : Array(Node), - @file : Parser::File, - @from : Int64, - @to : Int64) + @from : Parser::Location, + @to : Parser::Location, + @file : Parser::File) end end end diff --git a/src/ast/css_keyframes.cr b/src/ast/css_keyframes.cr index 2cfad8d76..46f001653 100644 --- a/src/ast/css_keyframes.cr +++ b/src/ast/css_keyframes.cr @@ -4,10 +4,10 @@ module Mint getter selectors, name def initialize(@selectors : Array(Node), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @name : String, - @from : Int64, - @to : Int64) + @name : String) end end end diff --git a/src/ast/css_nested_at.cr b/src/ast/css_nested_at.cr index 95047cc22..4ec210c1c 100644 --- a/src/ast/css_nested_at.cr +++ b/src/ast/css_nested_at.cr @@ -3,12 +3,12 @@ module Mint class CssNestedAt < Node getter content, body, name - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @body : Array(Node), @content : String, - @name : String, - @from : Int64, - @to : Int64) + @name : String) end end end diff --git a/src/ast/css_selector.cr b/src/ast/css_selector.cr index dc375b831..bdd5285de 100644 --- a/src/ast/css_selector.cr +++ b/src/ast/css_selector.cr @@ -4,10 +4,10 @@ module Mint getter selectors, body def initialize(@selectors : Array(String), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @body : Array(Node), - @from : Int64, - @to : Int64) + @body : Array(Node)) end end end diff --git a/src/ast/dbg.cr b/src/ast/dbg.cr index 3ac9664c8..f23dfafe3 100644 --- a/src/ast/dbg.cr +++ b/src/ast/dbg.cr @@ -3,10 +3,10 @@ module Mint class Dbg < Node getter expression - def initialize(@file : Parser::File, - @expression : Node?, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @expression : Node?) end end end diff --git a/src/ast/decode.cr b/src/ast/decode.cr index 6c605772a..a4a8f0458 100644 --- a/src/ast/decode.cr +++ b/src/ast/decode.cr @@ -3,11 +3,11 @@ module Mint class Decode < Node getter expression, type - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @expression : Node?, - @from : Int64, - @type : Type, - @to : Int64) + @type : Type) end end end diff --git a/src/ast/defer.cr b/src/ast/defer.cr index b2a9f299b..ea61e2679 100644 --- a/src/ast/defer.cr +++ b/src/ast/defer.cr @@ -3,10 +3,10 @@ module Mint class Defer < Node getter body - def initialize(@file : Parser::File, - @from : Int64, - @body : Node, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @body : Node) end end end diff --git a/src/ast/directives/file_based.cr b/src/ast/directives/file_based.cr index 736d3793a..814d7c298 100644 --- a/src/ast/directives/file_based.cr +++ b/src/ast/directives/file_based.cr @@ -11,10 +11,10 @@ module Mint getter path : String def initialize( + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @path : String, - @from : Int64, - @to : Int64 + @path : String ) @real_path = Path[file.path].sibling(path).expand end diff --git a/src/ast/directives/format.cr b/src/ast/directives/format.cr index b5a870032..d8d1a91ca 100644 --- a/src/ast/directives/format.cr +++ b/src/ast/directives/format.cr @@ -4,10 +4,10 @@ module Mint class Format < Node getter content - def initialize(@file : Parser::File, - @content : Block, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @content : Block) end end end diff --git a/src/ast/directives/highlight.cr b/src/ast/directives/highlight.cr index b44cd67e9..c13cea1d0 100644 --- a/src/ast/directives/highlight.cr +++ b/src/ast/directives/highlight.cr @@ -4,10 +4,10 @@ module Mint class Highlight < Node getter content - def initialize(@file : Parser::File, - @content : Block, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @content : Block) end end end diff --git a/src/ast/discard.cr b/src/ast/discard.cr index 45828bd58..43ada431f 100644 --- a/src/ast/discard.cr +++ b/src/ast/discard.cr @@ -1,9 +1,9 @@ module Mint class Ast class Discard < Node - def initialize(@file : Parser::File, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File) end end end diff --git a/src/ast/emit.cr b/src/ast/emit.cr index 1cd7d41b8..6c54437d7 100644 --- a/src/ast/emit.cr +++ b/src/ast/emit.cr @@ -4,10 +4,10 @@ module Mint property signal : Signal? = nil getter expression - def initialize(@file : Parser::File, - @expression : Node, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @expression : Node) end end end diff --git a/src/ast/encode.cr b/src/ast/encode.cr index ffd865587..72d33a626 100644 --- a/src/ast/encode.cr +++ b/src/ast/encode.cr @@ -3,10 +3,10 @@ module Mint class Encode < Node getter expression - def initialize(@file : Parser::File, - @expression : Node, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @expression : Node) end end end diff --git a/src/ast/env.cr b/src/ast/env.cr index 51daa81a2..4635536c0 100644 --- a/src/ast/env.cr +++ b/src/ast/env.cr @@ -3,10 +3,10 @@ module Mint class Env < Node getter name - def initialize(@file : Parser::File, - @name : String, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @name : String) end end end diff --git a/src/ast/field.cr b/src/ast/field.cr index ff2d12d7d..d29f9ee9d 100644 --- a/src/ast/field.cr +++ b/src/ast/field.cr @@ -3,12 +3,12 @@ module Mint class Field < Node getter key, value, comment - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @comment : Comment?, @key : Variable?, - @value : Node, - @from : Int64, - @to : Int64) + @value : Node) end end end diff --git a/src/ast/field_access.cr b/src/ast/field_access.cr index ccdb022b4..7e4ec611b 100644 --- a/src/ast/field_access.cr +++ b/src/ast/field_access.cr @@ -3,11 +3,11 @@ module Mint class FieldAccess < Node getter name, type - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @name : Variable, - @from : Int64, - @type : Type, - @to : Int64) + @type : Type) end end end diff --git a/src/ast/for.cr b/src/ast/for.cr index b7f3f2672..87b805e21 100644 --- a/src/ast/for.cr +++ b/src/ast/for.cr @@ -4,12 +4,12 @@ module Mint getter subject, body, arguments, condition def initialize(@arguments : Array(Node), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @condition : Block?, @subject : Node, - @body : Block, - @from : Int64, - @to : Int64) + @body : Block) end end end diff --git a/src/ast/function.cr b/src/ast/function.cr index a8682169f..a84dcc2cf 100644 --- a/src/ast/function.cr +++ b/src/ast/function.cr @@ -4,13 +4,13 @@ module Mint getter arguments, comment, name, type, body def initialize(@arguments : Array(Argument), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @comment : Comment?, @name : Variable, @type : Node?, - @body : Block, - @from : Int64, - @to : Int64) + @body : Block) end end end diff --git a/src/ast/get.cr b/src/ast/get.cr index cd4aa3b9e..02352445d 100644 --- a/src/ast/get.cr +++ b/src/ast/get.cr @@ -3,13 +3,13 @@ module Mint class Get < Node getter comment, name, body, type - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @comment : Comment?, @name : Variable, @body : Block, - @from : Int64, - @type : Node?, - @to : Int64) + @type : Node?) end end end diff --git a/src/ast/here_document.cr b/src/ast/here_document.cr index 56b9d4ae3..529a120d7 100644 --- a/src/ast/here_document.cr +++ b/src/ast/here_document.cr @@ -4,12 +4,12 @@ module Mint getter highlight, modifier, token, value def initialize(@value : Array(String | Interpolation), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @highlight : Bool?, @modifier : Char, - @token : String, - @from : Int64, - @to : Int64) + @token : String) end end end diff --git a/src/ast/html_attribute.cr b/src/ast/html_attribute.cr index 1eaa04f7c..58c3752ff 100644 --- a/src/ast/html_attribute.cr +++ b/src/ast/html_attribute.cr @@ -3,11 +3,11 @@ module Mint class HtmlAttribute < Node getter value, name - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @name : Variable, - @value : Node, - @from : Int64, - @to : Int64) + @value : Node) end end end diff --git a/src/ast/html_component.cr b/src/ast/html_component.cr index 8a157a2a5..1eef31fea 100644 --- a/src/ast/html_component.cr +++ b/src/ast/html_component.cr @@ -7,15 +7,15 @@ module Mint property component_node : Ast::Component? = nil property? in_component : Bool = false - def initialize(@attributes : Array(HtmlAttribute), - @closing_tag_position : Int64?, + def initialize(@closing_tag_position : Parser::Location?, + @attributes : Array(HtmlAttribute), @comments : Array(Comment), + @from : Parser::Location, @children : Array(Node), + @to : Parser::Location, @file : Parser::File, @ref : Variable?, - @component : Id, - @from : Int64, - @to : Int64) + @component : Id) end end end diff --git a/src/ast/html_element.cr b/src/ast/html_element.cr index 256a5f8b7..286e0261c 100644 --- a/src/ast/html_element.cr +++ b/src/ast/html_element.cr @@ -6,16 +6,16 @@ module Mint property? in_component : Bool = false - def initialize(@attributes : Array(HtmlAttribute), - @closing_tag_position : Int64?, + def initialize(@closing_tag_position : Parser::Location?, + @attributes : Array(HtmlAttribute), @comments : Array(Comment), @styles : Array(HtmlStyle), + @from : Parser::Location, @children : Array(Node), + @to : Parser::Location, @file : Parser::File, @ref : Variable?, - @tag : Variable, - @from : Int64, - @to : Int64) + @tag : Variable) end end end diff --git a/src/ast/html_fragment.cr b/src/ast/html_fragment.cr index 5b1f4fd35..c36d631b0 100644 --- a/src/ast/html_fragment.cr +++ b/src/ast/html_fragment.cr @@ -4,10 +4,10 @@ module Mint getter comments, children, tag def initialize(@comments : Array(Comment), + @from : Parser::Location, @children : Array(Node), - @file : Parser::File, - @from : Int64, - @to : Int64) + @to : Parser::Location, + @file : Parser::File) end end end diff --git a/src/ast/html_style.cr b/src/ast/html_style.cr index 0e259ae36..eee62f36d 100644 --- a/src/ast/html_style.cr +++ b/src/ast/html_style.cr @@ -6,13 +6,13 @@ module Mint property style_node : Ast::Style? = nil def initialize(@arguments : Array(Field), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @name : Variable, - @from : Int64, - @to : Int64) + @name : Variable) end - # This is here to provide compatiblity for calls... + # NOTE: This is here to provide compatiblity for calls (functions)... def await nil end diff --git a/src/ast/id.cr b/src/ast/id.cr index fcd058a2a..2bb57e037 100644 --- a/src/ast/id.cr +++ b/src/ast/id.cr @@ -3,10 +3,10 @@ module Mint class Id < Node getter value - def initialize(@file : Parser::File, - @value : String, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @value : String) end end end diff --git a/src/ast/if.cr b/src/ast/if.cr index d17c3f814..2d2317945 100644 --- a/src/ast/if.cr +++ b/src/ast/if.cr @@ -7,11 +7,11 @@ module Mint Tuple(Block, Nil) | Tuple(Block, If) - def initialize(@branches : Branches, + def initialize(@from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @condition : Node, - @from : Int64, - @to : Int64) + @branches : Branches, + @condition : Node) end end end diff --git a/src/ast/inline_function.cr b/src/ast/inline_function.cr index d264f6f81..49109541f 100644 --- a/src/ast/inline_function.cr +++ b/src/ast/inline_function.cr @@ -4,11 +4,11 @@ module Mint getter arguments, body, type def initialize(@arguments : Array(Argument), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @body : Block, - @from : Int64, - @type : Node?, - @to : Int64) + @type : Node?) end end end diff --git a/src/ast/interpolation.cr b/src/ast/interpolation.cr index 843d0daa4..ec5385fe0 100644 --- a/src/ast/interpolation.cr +++ b/src/ast/interpolation.cr @@ -3,10 +3,10 @@ module Mint class Interpolation < Node getter expression - def initialize(@file : Parser::File, - @expression : Node, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @expression : Node) end end end diff --git a/src/ast/js.cr b/src/ast/js.cr index 17865f43b..9864f3c0c 100644 --- a/src/ast/js.cr +++ b/src/ast/js.cr @@ -4,10 +4,10 @@ module Mint getter value, type def initialize(@value : Array(String | Interpolation), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @from : Int64, - @type : Node?, - @to : Int64) + @type : Node?) end end end diff --git a/src/ast/locale.cr b/src/ast/locale.cr index d3036f5d9..bf2ebdc1a 100644 --- a/src/ast/locale.cr +++ b/src/ast/locale.cr @@ -3,12 +3,12 @@ module Mint class Locale < Node getter language, fields, comment - def initialize(@fields : Array(Field), + def initialize(@from : Parser::Location, + @to : Parser::Location, + @fields : Array(Field), @file : Parser::File, @comment : Comment?, - @language : String, - @from : Int64, - @to : Int64) + @language : String) end end end diff --git a/src/ast/locale_key.cr b/src/ast/locale_key.cr index c9171df1e..23d5a6304 100644 --- a/src/ast/locale_key.cr +++ b/src/ast/locale_key.cr @@ -3,10 +3,10 @@ module Mint class LocaleKey < Node getter value - def initialize(@file : Parser::File, - @value : String, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @value : String) end end end diff --git a/src/ast/map.cr b/src/ast/map.cr index bbd7514aa..35bee3802 100644 --- a/src/ast/map.cr +++ b/src/ast/map.cr @@ -5,9 +5,9 @@ module Mint def initialize(@types : Tuple(Ast::Node, Ast::Node)?, @fields : Array(MapField), - @file : Parser::File, - @from : Int64, - @to : Int64) + @from : Parser::Location, + @to : Parser::Location, + @file : Parser::File) end end end diff --git a/src/ast/map_field.cr b/src/ast/map_field.cr index 2735649d4..8c34d2938 100644 --- a/src/ast/map_field.cr +++ b/src/ast/map_field.cr @@ -3,12 +3,12 @@ module Mint class MapField < Node getter key, value, comment - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @comment : Comment?, - @from : Int64, @value : Node, - @key : Node, - @to : Int64) + @key : Node) end end end diff --git a/src/ast/module.cr b/src/ast/module.cr index a40be5bc3..e5ee76fc4 100644 --- a/src/ast/module.cr +++ b/src/ast/module.cr @@ -6,10 +6,10 @@ module Mint def initialize(@functions : Array(Function), @constants : Array(Constant), @comments : Array(Comment), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @comment : Comment?, - @from : Int64, - @to : Int64, @name : Id) end end diff --git a/src/ast/negated_expression.cr b/src/ast/negated_expression.cr index 8b81916e6..ea7650a39 100644 --- a/src/ast/negated_expression.cr +++ b/src/ast/negated_expression.cr @@ -3,11 +3,11 @@ module Mint class NegatedExpression < Node getter expression, negations - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @negations : String, - @expression : Node, - @from : Int64, - @to : Int64) + @expression : Node) end end end diff --git a/src/ast/next_call.cr b/src/ast/next_call.cr index 1666548a6..224eaf2d3 100644 --- a/src/ast/next_call.cr +++ b/src/ast/next_call.cr @@ -5,10 +5,10 @@ module Mint property entity : Ast::Node? = nil - def initialize(@file : Parser::File, - @data : Record, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @data : Record) end end end diff --git a/src/ast/node.cr b/src/ast/node.cr index b3de1313e..9ac7e24b3 100644 --- a/src/ast/node.cr +++ b/src/ast/node.cr @@ -1,117 +1,40 @@ module Mint class Ast class Node - # Line and column number pair. - alias Position = {Int64, Int64} - - struct Location - include JSON::Serializable - - # Relative file path of the `Node`, - # this `Location` belongs to. - getter filename : String - - # Starting line and column number of the `Node`, - # this `Location` belongs to. - getter start : Position - - # Ending line and column number of the `Node`, - # this `Location` belongs to. - getter end : Position - - def initialize(@filename, @start, @end) - end - - def contains?(line : Int64) - start[0] <= line <= end[0] - end - - def contains?(line : Int64, column : Int64) - case - when line == start[0] == end[0] # If on the only line - start[1] <= column < end[1] - when line == start[0] # If on the first line - column >= start[1] - when line == end[0] # If on the last line - column < end[1] - else - contains?(line) - end - end - end - - getter file : Parser::File + property from : Parser::Location property parent : Node? - property from : Int64 - getter to : Int64 - def initialize(@file, @from, @to) - end + getter to : Parser::Location + getter file : Parser::File - def to_tuple - {file: file, from: from, to: to} - end + @source : String? - def source - file.contents[from, to - from] + def initialize(@file, @from, @to) end - def new_line? - source.strip.includes?('\n') + def contains?(line : Int64) + from.line <= line <= to.line end - def self.compute_position(lines, needle) : Position - line_start_pos, line = begin - left, right = 0_i64, lines.size - 1_i64 - index = pos = 0_i64 - found = false - - while left <= right - middle = left + ((right - left) // 2) - - case pos = lines[middle] - when .< needle - left = middle + 1_i64 - when .> needle - right = middle - 1_i64 - else - index = middle - found = true - break - end - end - - unless found - index = left - 1_i64 - pos = lines[index] - end - - {pos, index} + def contains?(line : Int64, column : Int64) + case + when line == from.line == to.line # If on the only line + from.column <= column < to.column + when line == from.line # If on the first line + column >= from.column + when line == to.line # If on the last line + column < to.column + else + contains?(line) end - - # NOTE: for the line numbers use 1-based indexing - line += 1_i64 - column = needle - line_start_pos - - {line, column} end - def self.compute_location(file : Parser::File, from, to) - # TODO: avoid creating this array for every (initial) call to `Node#location` - lines = [0] - file.contents.each_char_with_index do |char, i| - lines << i + 1 if char == '\n' - end - - Location.new( - filename: file.path, - start: compute_position(lines, from), - end: compute_position(lines, to), - ) + def new_line? + to.line > from.line end - getter location : Location do - Node.compute_location(file, from, to) + def source + @source ||= file.contents[from.offset, to.offset - from.offset] end end end diff --git a/src/ast/number_literal.cr b/src/ast/number_literal.cr index cee7dbfc8..1898c312f 100644 --- a/src/ast/number_literal.cr +++ b/src/ast/number_literal.cr @@ -4,11 +4,11 @@ module Mint getter? float getter value - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @value : String, - @float : Bool, - @from : Int64, - @to : Int64) + @float : Bool) end end end diff --git a/src/ast/operation.cr b/src/ast/operation.cr index da5ba2d80..8ef59e03a 100644 --- a/src/ast/operation.cr +++ b/src/ast/operation.cr @@ -3,12 +3,12 @@ module Mint class Operation < Node getter operator, right, left - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @operator : String, @right : Node, - @from : Int64, - @left : Node, - @to : Int64) + @left : Node) end end end diff --git a/src/ast/parenthesized_expression.cr b/src/ast/parenthesized_expression.cr index 9bb94652d..26c02a475 100644 --- a/src/ast/parenthesized_expression.cr +++ b/src/ast/parenthesized_expression.cr @@ -3,10 +3,10 @@ module Mint class ParenthesizedExpression < Node getter expression - def initialize(@file : Parser::File, - @expression : Node, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @expression : Node) end end end diff --git a/src/ast/pipe.cr b/src/ast/pipe.cr index 8e6d3aa39..cb01b8050 100644 --- a/src/ast/pipe.cr +++ b/src/ast/pipe.cr @@ -3,11 +3,11 @@ module Mint class Pipe < Node getter expression, argument - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @expression : Node, - @argument : Node, - @from : Int64, - @to : Int64) + @argument : Node) end def call diff --git a/src/ast/property.cr b/src/ast/property.cr index d1e5b317d..17b370529 100644 --- a/src/ast/property.cr +++ b/src/ast/property.cr @@ -3,13 +3,13 @@ module Mint class Property < Node getter default, comment, type, name - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @comment : Comment?, @default : Node?, @name : Variable, - @from : Int64, - @type : Type?, - @to : Int64) + @type : Type?) end end end diff --git a/src/ast/provider.cr b/src/ast/provider.cr index d4a31877e..67d79eadf 100644 --- a/src/ast/provider.cr +++ b/src/ast/provider.cr @@ -8,13 +8,13 @@ module Mint @constants : Array(Constant), @comments : Array(Comment), @signals : Array(Signal), + @from : Parser::Location, + @to : Parser::Location, @states : Array(State), @file : Parser::File, @comment : Comment?, @subscription : Id, @gets : Array(Get), - @from : Int64, - @to : Int64, @name : Id) end end diff --git a/src/ast/record.cr b/src/ast/record.cr index 95c7207c4..cce9b6c3f 100644 --- a/src/ast/record.cr +++ b/src/ast/record.cr @@ -3,10 +3,10 @@ module Mint class Record < Node getter fields - def initialize(@fields : Array(Field), - @file : Parser::File, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @fields : Array(Field), + @file : Parser::File) end end end diff --git a/src/ast/record_update.cr b/src/ast/record_update.cr index dc46d3b4c..22712279e 100644 --- a/src/ast/record_update.cr +++ b/src/ast/record_update.cr @@ -3,11 +3,11 @@ module Mint class RecordUpdate < Node getter expression, fields - def initialize(@expression : Ast::Node, + def initialize(@from : Parser::Location, + @expression : Ast::Node, + @to : Parser::Location, @fields : Array(Field), - @file : Parser::File, - @from : Int64, - @to : Int64) + @file : Parser::File) end end end diff --git a/src/ast/regexp_literal.cr b/src/ast/regexp_literal.cr index 17cf7a212..939e8497b 100644 --- a/src/ast/regexp_literal.cr +++ b/src/ast/regexp_literal.cr @@ -3,11 +3,11 @@ module Mint class RegexpLiteral < Node getter value, flags - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @value : String, - @flags : String, - @from : Int64, - @to : Int64) + @flags : String) end end end diff --git a/src/ast/return_call.cr b/src/ast/return_call.cr index 144d1d1b3..da46785ab 100644 --- a/src/ast/return_call.cr +++ b/src/ast/return_call.cr @@ -5,10 +5,10 @@ module Mint getter expression - def initialize(@file : Parser::File, - @expression : Node, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @expression : Node) end end end diff --git a/src/ast/route.cr b/src/ast/route.cr index a8a6e3986..592f445b6 100644 --- a/src/ast/route.cr +++ b/src/ast/route.cr @@ -4,12 +4,12 @@ module Mint getter expression, arguments, url, await def initialize(@arguments : Array(Argument), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @expression : Block, - @from : Int64, @await : Bool, - @url : String, - @to : Int64) + @url : String) end end end diff --git a/src/ast/routes.cr b/src/ast/routes.cr index 693c2bec4..1477bc58b 100644 --- a/src/ast/routes.cr +++ b/src/ast/routes.cr @@ -4,10 +4,10 @@ module Mint getter comments, routes def initialize(@comments : Array(Comment), + @from : Parser::Location, + @to : Parser::Location, @routes : Array(Route), - @file : Parser::File, - @from : Int64, - @to : Int64) + @file : Parser::File) end end end diff --git a/src/ast/signal.cr b/src/ast/signal.cr index c3f4f3c1d..7278cea0b 100644 --- a/src/ast/signal.cr +++ b/src/ast/signal.cr @@ -3,13 +3,13 @@ module Mint class Signal < Node getter block, comment, type, name - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @comment : Comment?, @name : Variable, @block : Block, - @from : Int64, - @type : Type, - @to : Int64) + @type : Type) end end end diff --git a/src/ast/spread.cr b/src/ast/spread.cr index 8abadb4e9..fff8aaaa7 100644 --- a/src/ast/spread.cr +++ b/src/ast/spread.cr @@ -3,10 +3,10 @@ module Mint class Spread < Node getter variable - def initialize(@file : Parser::File, - @variable : Node, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @variable : Node) end end end diff --git a/src/ast/state.cr b/src/ast/state.cr index 550024181..b360dd0e1 100644 --- a/src/ast/state.cr +++ b/src/ast/state.cr @@ -3,13 +3,13 @@ module Mint class State < Node getter default, comment, type, name - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @comment : Comment?, @name : Variable, @default : Node, - @from : Int64, - @type : Type?, - @to : Int64) + @type : Type?) end end end diff --git a/src/ast/state_setter.cr b/src/ast/state_setter.cr index 351d53cf8..4d4aad71b 100644 --- a/src/ast/state_setter.cr +++ b/src/ast/state_setter.cr @@ -3,11 +3,11 @@ module Mint class StateSetter < Node getter entity, state - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @state : Variable, - @from : Int64, - @entity : Id?, - @to : Int64) + @entity : Id?) end end end diff --git a/src/ast/statement.cr b/src/ast/statement.cr index 80db670cf..fb3b8e033 100644 --- a/src/ast/statement.cr +++ b/src/ast/statement.cr @@ -5,12 +5,12 @@ module Mint getter return_value, expression, target - def initialize(@return_value : Node?, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @return_value : Node?, @file : Parser::File, @expression : Node, - @target : Node?, - @from : Int64, - @to : Int64) + @target : Node?) end def only_expression? diff --git a/src/ast/store.cr b/src/ast/store.cr index 8f7c8a741..1cbd9e605 100644 --- a/src/ast/store.cr +++ b/src/ast/store.cr @@ -8,12 +8,12 @@ module Mint @constants : Array(Constant), @comments : Array(Comment), @signals : Array(Signal), + @from : Parser::Location, + @to : Parser::Location, @states : Array(State), @file : Parser::File, @comment : Comment?, @gets : Array(Get), - @from : Int64, - @to : Int64, @name : Id) end end diff --git a/src/ast/string_literal.cr b/src/ast/string_literal.cr index 68378111e..a3c41de65 100644 --- a/src/ast/string_literal.cr +++ b/src/ast/string_literal.cr @@ -5,10 +5,10 @@ module Mint getter value def initialize(@value : Array(String | Interpolation), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @broken : Bool, - @from : Int64, - @to : Int64) + @broken : Bool) end end end diff --git a/src/ast/style.cr b/src/ast/style.cr index f2f5896b4..c589747de 100644 --- a/src/ast/style.cr +++ b/src/ast/style.cr @@ -4,11 +4,11 @@ module Mint getter arguments, body, name def initialize(@arguments : Array(Argument), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @body : Array(Node), - @name : Variable, - @from : Int64, - @to : Int64) + @name : Variable) end end end diff --git a/src/ast/suite.cr b/src/ast/suite.cr index 66a5a5125..3f5596669 100644 --- a/src/ast/suite.cr +++ b/src/ast/suite.cr @@ -6,11 +6,11 @@ module Mint def initialize(@constants : Array(Constant), @functions : Array(Function), @comments : Array(Comment), + @from : Parser::Location, + @to : Parser::Location, @name : StringLiteral, - @tests : Array(Test), @file : Parser::File, - @from : Int64, - @to : Int64) + @tests : Array(Test)) end end end diff --git a/src/ast/test.cr b/src/ast/test.cr index 131dafd8e..04559296e 100644 --- a/src/ast/test.cr +++ b/src/ast/test.cr @@ -3,11 +3,11 @@ module Mint class Test < Node getter expression, name - def initialize(@name : StringLiteral, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @name : StringLiteral, @file : Parser::File, - @expression : Block, - @from : Int64, - @to : Int64) + @expression : Block) end end end diff --git a/src/ast/tuple_destructuring.cr b/src/ast/tuple_destructuring.cr index 3a4baa2c7..fc5159846 100644 --- a/src/ast/tuple_destructuring.cr +++ b/src/ast/tuple_destructuring.cr @@ -3,10 +3,10 @@ module Mint class TupleDestructuring < Node getter items - def initialize(@items : Array(Node), + def initialize(@from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @from : Int64, - @to : Int64) + @items : Array(Node)) end end end diff --git a/src/ast/tuple_literal.cr b/src/ast/tuple_literal.cr index 4dfb0f668..2775cc84f 100644 --- a/src/ast/tuple_literal.cr +++ b/src/ast/tuple_literal.cr @@ -3,10 +3,10 @@ module Mint class TupleLiteral < Node getter items - def initialize(@items : Array(Node), + def initialize(@from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @from : Int64, - @to : Int64) + @items : Array(Node)) end end end diff --git a/src/ast/type.cr b/src/ast/type.cr index dbb9c237a..78cbb21e0 100644 --- a/src/ast/type.cr +++ b/src/ast/type.cr @@ -4,9 +4,9 @@ module Mint getter parameters, name def initialize(@parameters : Array(Node), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @from : Int64, - @to : Int64, @name : Id) end end diff --git a/src/ast/type_definition.cr b/src/ast/type_definition.cr index 04089ec56..72a58b24d 100644 --- a/src/ast/type_definition.cr +++ b/src/ast/type_definition.cr @@ -5,10 +5,10 @@ module Mint def initialize(@fields : Array(TypeDefinitionField) | Array(TypeVariant), @parameters : Array(TypeVariable), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @comment : Comment?, - @from : Int64, - @to : Int64, @name : Id) end end diff --git a/src/ast/type_definition_field.cr b/src/ast/type_definition_field.cr index 6be1e1eb5..95484fdc6 100644 --- a/src/ast/type_definition_field.cr +++ b/src/ast/type_definition_field.cr @@ -4,12 +4,12 @@ module Mint getter mapping, comment, type, key def initialize(@mapping : StringLiteral?, + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @comment : Comment?, @key : Variable, - @from : Int64, - @type : Node, - @to : Int64) + @type : Node) end end end diff --git a/src/ast/type_destructuring.cr b/src/ast/type_destructuring.cr index 138208da9..6e6193831 100644 --- a/src/ast/type_destructuring.cr +++ b/src/ast/type_destructuring.cr @@ -3,11 +3,11 @@ module Mint class TypeDestructuring < Node getter variant, items, name - def initialize(@items : Array(Node), + def initialize(@from : Parser::Location, + @to : Parser::Location, @file : Parser::File, - @from : Int64, + @items : Array(Node), @variant : Id, - @to : Int64, @name : Id?) end end diff --git a/src/ast/type_variable.cr b/src/ast/type_variable.cr index ae536cdf2..7004af2de 100644 --- a/src/ast/type_variable.cr +++ b/src/ast/type_variable.cr @@ -3,10 +3,10 @@ module Mint class TypeVariable < Node getter value - def initialize(@file : Parser::File, - @value : String, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @value : String) end end end diff --git a/src/ast/type_variant.cr b/src/ast/type_variant.cr index 57582bb12..f44b1ce8b 100644 --- a/src/ast/type_variant.cr +++ b/src/ast/type_variant.cr @@ -4,10 +4,10 @@ module Mint getter parameters, comment, value def initialize(@parameters : Array(Node), + @from : Parser::Location, + @to : Parser::Location, @file : Parser::File, @comment : Comment?, - @from : Int64, - @to : Int64, @value : Id) end diff --git a/src/ast/unary_minus.cr b/src/ast/unary_minus.cr index d6e951834..902af5573 100644 --- a/src/ast/unary_minus.cr +++ b/src/ast/unary_minus.cr @@ -3,10 +3,10 @@ module Mint class UnaryMinus < Node getter expression, negations - def initialize(@file : Parser::File, - @expression : Node, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @expression : Node) end end end diff --git a/src/ast/use.cr b/src/ast/use.cr index 34ea98b36..f3dd06c3a 100644 --- a/src/ast/use.cr +++ b/src/ast/use.cr @@ -3,12 +3,12 @@ module Mint class Use < Node getter provider, condition, data - def initialize(@file : Parser::File, + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, @condition : Node?, @provider : Id, - @data : Record, - @from : Int64, - @to : Int64) + @data : Record) end end end diff --git a/src/ast/variable.cr b/src/ast/variable.cr index 52338e82a..f07ec88d3 100644 --- a/src/ast/variable.cr +++ b/src/ast/variable.cr @@ -3,10 +3,10 @@ module Mint class Variable < Node getter value - def initialize(@file : Parser::File, - @value : String, - @from : Int64, - @to : Int64) + def initialize(@from : Parser::Location, + @to : Parser::Location, + @file : Parser::File, + @value : String) end end end diff --git a/src/compilers/dbg.cr b/src/compilers/dbg.cr index 41804e5e2..d6310e7c3 100644 --- a/src/compilers/dbg.cr +++ b/src/compilers/dbg.cr @@ -3,7 +3,7 @@ module Mint def compile(node : Ast::Dbg) : Compiled compile node do location = - js.string("#{node.file.path}:#{node.location.start[0]}:#{node.location.start[1]}") + js.string("#{node.file.path}:#{node.from.line}:#{node.from.column}") var = [Variable.new] of Item diff --git a/src/compilers/suite.cr b/src/compilers/suite.cr index 597f854c5..682d46803 100644 --- a/src/compilers/suite.cr +++ b/src/compilers/suite.cr @@ -3,7 +3,13 @@ module Mint def compile(node : Ast::Suite) : Compiled compile node do location = - [Raw.new(node.location.to_json)] + [ + Raw.new({ + start: {node.from.line, node.from.column}, + end: {node.to.line, node.to.column}, + filename: node.file.path, + }.to_json), + ] constants = resolve node.constants diff --git a/src/compilers/test.cr b/src/compilers/test.cr index c0bae5ff4..3984bde3e 100644 --- a/src/compilers/test.cr +++ b/src/compilers/test.cr @@ -3,7 +3,13 @@ module Mint def compile(node : Ast::Test) : Compiled compile node do location = - [Raw.new(node.location.to_json)] + [ + Raw.new({ + start: {node.from.line, node.from.column}, + end: {node.to.line, node.to.column}, + filename: node.file.path, + }.to_json), + ] name = compile node.name diff --git a/src/errorable.cr b/src/errorable.cr index 8581512f3..069738618 100644 --- a/src/errorable.cr +++ b/src/errorable.cr @@ -82,16 +82,16 @@ module Mint case value in Parser SnippetData.new( - to: value.position + value.word.to_s.size, + to: value.position.offset + value.word.to_s.size, + from: value.position.offset, input: value.file.contents, - filename: value.file.path, - from: value.position) + filename: value.file.path) in Ast::Node SnippetData.new( input: value.file.contents, filename: value.file.path, - from: value.from, - to: value.to) + from: value.from.offset, + to: value.to.offset) in SnippetData value in TypeChecker::Checkable diff --git a/src/formatter/processor.cr b/src/formatter/processor.cr index 8845b3ff5..b99e42d3c 100644 --- a/src/formatter/processor.cr +++ b/src/formatter/processor.cr @@ -102,7 +102,7 @@ module Mint result = [] of Processed last = nil - node.items.sort_by(&.first.from).each do |(item, nodes)| + node.items.sort_by(&.first.from.offset).each do |(item, nodes)| if last if separator = node.separator result += process([separator] of Node) diff --git a/src/formatters/top_level.cr b/src/formatters/top_level.cr index a4b8bc4b0..392534b88 100644 --- a/src/formatters/top_level.cr +++ b/src/formatters/top_level.cr @@ -12,7 +12,7 @@ module Mint ast.comments + ast.locales ) - .sort_by!(&.from) + .sort_by!(&.from.offset) .map { |node| format node } .intersperse([Line.new(2)] of Node) .flatten diff --git a/src/ls/code_actions/module_actions.cr b/src/ls/code_actions/module_actions.cr index 8272492fa..94462e852 100644 --- a/src/ls/code_actions/module_actions.cr +++ b/src/ls/code_actions/module_actions.cr @@ -8,7 +8,7 @@ module Mint # Save the original order of constants and functions order = (node.functions + node.constants) - .sort_by!(&.from) + .sort_by!(&.from.offset) .map(&.from) # Reorder by name and the appropriate order from the original order diff --git a/src/ls/code_actions/provider_actions.cr b/src/ls/code_actions/provider_actions.cr index 21111d8e2..eb60d14c5 100644 --- a/src/ls/code_actions/provider_actions.cr +++ b/src/ls/code_actions/provider_actions.cr @@ -8,7 +8,7 @@ module Mint # Save the original order of constants and functions order = (node.functions + node.constants + node.states + node.gets) - .sort_by!(&.from) + .sort_by!(&.from.offset) .map(&.from) # Reorder by name and the appropriate order from the original order diff --git a/src/ls/definitions.cr b/src/ls/definitions.cr index c4edaba25..b8092802f 100644 --- a/src/ls/definitions.cr +++ b/src/ls/definitions.cr @@ -14,7 +14,7 @@ module Mint end def cursor_intersects?(node : Ast::Node, position : LSP::Position) : Bool - node.location.contains?(position.line + 1, position.character) + node.contains?(position.line + 1, position.character) end def cursor_intersects?(node : Ast::Node, params : LSP::TextDocumentPositionParams) : Bool @@ -32,15 +32,15 @@ module Mint @type_checker.ast.components.find(&.name.value.== name) end - def to_lsp_range(location : Ast::Node::Location) : LSP::Range + def to_lsp_range(node : Ast::Node) : LSP::Range LSP::Range.new( start: LSP::Position.new( - line: location.start[0] - 1, - character: location.start[1] + character: node.from.column, + line: node.from.line - 1 ), end: LSP::Position.new( - line: location.end[0] - 1, - character: location.end[1] + character: node.to.column, + line: node.to.line - 1 ) ) end @@ -52,10 +52,10 @@ module Mint # would be the whole node, including function body and any comments def location_link(source : Ast::Node, target : Ast::Node, parent : Ast::Node) : LSP::LocationLink LSP::LocationLink.new( - origin_selection_range: to_lsp_range(source.location), - target_uri: "file://#{target.location.filename}", - target_range: to_lsp_range(parent.location), - target_selection_range: to_lsp_range(target.location) + origin_selection_range: to_lsp_range(source), + target_selection_range: to_lsp_range(target), + target_uri: "file://#{target.file.path}", + target_range: to_lsp_range(parent), ) end end diff --git a/src/ls/definitions/variable.cr b/src/ls/definitions/variable.cr index 1a6968b27..74da4aaab 100644 --- a/src/ls/definitions/variable.cr +++ b/src/ls/definitions/variable.cr @@ -41,9 +41,16 @@ module Mint # target Ast::Variable and not its containing node, so we must search for it return unless parent = @type_checker.artifacts.ast.nodes - .select { |other| other.is_a?(Ast::TypeDestructuring) || other.is_a?(Ast::Statement) || other.is_a?(Ast::For) } + .select do |other| + other.is_a?(Ast::TypeDestructuring) || + other.is_a?(Ast::Statement) || + other.is_a?(Ast::For) + end .select(&.file.path.==(variable.file.path)) - .find { |other| other.from < variable.from && other.to > variable.to } + .find do |other| + other.from.offset < variable.from.offset && + other.to.offset > variable.to.offset + end location_link node, variable, parent end diff --git a/src/ls/folding_range.cr b/src/ls/folding_range.cr index db524d21e..49a37bfbb 100644 --- a/src/ls/folding_range.cr +++ b/src/ls/folding_range.cr @@ -4,22 +4,23 @@ module Mint property params : LSP::FoldingRangeParams def range(node : Ast::Component) : Array(LSP::FoldingRange) - range(node.comment.try(&.location)) + range(node, node.comment) + range(node, node.comment) end def range(node : Ast::Module) : Array(LSP::FoldingRange) - range(node.comment.try(&.location)) + range(node, node.comment) + range(node, node.comment) end def range(node : Ast::Function) : Array(LSP::FoldingRange) - range(node.comment.try(&.location)) + range(node, node.comment) + range(node, node.comment) end def range(node : Ast::Node, comment : Ast::Comment?) : Array(LSP::FoldingRange) if comment - range(comment.location.end[0], node.location.end[0]) + range(comment.from.line, comment.to.line) + + range(comment.to.line, node.to.line) else - range(node.location) + range(node.from.line, node.to.line) end end @@ -27,10 +28,6 @@ module Mint [] of LSP::FoldingRange end - def range(location : Ast::Node::Location) : Array(LSP::FoldingRange) - range(location.start[0], location.end[0]) - end - def range(start_line, end_line) : Array(LSP::FoldingRange) [ LSP::FoldingRange.new( @@ -47,7 +44,7 @@ module Mint in TypeChecker type_checker.artifacts.ast .nodes_at_path(params.text_document.path) - .select { |node| node.location.start[0] != node.location.end[0] } + .reject { |node| node.from.line == node.to.line } .flat_map { |node| range(node) } in Error end diff --git a/src/ls/semantic_tokens.cr b/src/ls/semantic_tokens.cr index 259bc7363..eed885247 100644 --- a/src/ls/semantic_tokens.cr +++ b/src/ls/semantic_tokens.cr @@ -11,26 +11,19 @@ module Mint case ast = server.workspace(path).ast(path) when Ast - # This is used later on to convert the line/column of each token - file = - ast.nodes.first.file - tokenizer = SemanticTokenizer.new tokenizer.tokenize(ast) tokens = - tokenizer.tokens.sort_by(&.from).compact_map do |token| - location = - Ast::Node.compute_location(file, token.from, token.to) - + tokenizer.tokens.sort_by(&.from.offset).compact_map do |token| type = token.type.to_s.underscore if index = SemanticTokenizer::TOKEN_TYPES.index(type) [ - location.start[0] - 1, - location.start[1], - token.to - token.from, + token.from.line - 1, + token.from.column, + token.to.offset - token.from.offset, index.to_i64, 0_i64, ] diff --git a/src/parser.cr b/src/parser.cr index c098a4d16..99b8323c8 100644 --- a/src/parser.cr +++ b/src/parser.cr @@ -7,7 +7,7 @@ module Mint # The position of the cursor, which is at the character we are currently # parsing. - getter position : Int64 = 0 + getter position : Location = Location.new # The input which is an array of characters because this way it's faster in # cases where the original code contains multi-byte characters. @@ -54,12 +54,24 @@ module Mint # Moves the cursor forward by one character. def step - @position += 1 + position, line, column = + @position.to_tuple + + case char + when '\n' + column = 0_i64 + line += 1 + else + column += 1 + end + + @position = + Location.new(offset: position + 1, line: line, column: column) end # Returns whether or not the cursor is at the end of the file. def eof? : Bool - @position == input.size + @position.offset == input.size end # Checks if we reached the end of the file, adds an error otherwise. @@ -74,7 +86,7 @@ module Mint # Returns the current character. def char : Char - input[position]? || '\0' + input[position.offset]? || '\0' end # If the character is parsed with the given block, moves the cursor forward. @@ -89,17 +101,17 @@ module Mint # Returns the next character. def next_char : Char - input[position + 1]? || '\0' + input[position.offset + 1]? || '\0' end # Returns the previous character. def previous_char : Char - input[position - 1]? || '\0' + input[position.offset - 1]? || '\0' end # Returns the current word (sequence of ascii lowercase letters). def ascii_word : String - index = position + index = position.offset word = "" while (input[index]? || '\0').ascii_letter? @@ -138,12 +150,12 @@ module Mint # Starts to parse something, if the cursor moved during, return the parsed # string. def gather(&) : String? - start_position = position + start_position = position.offset yield - if position > start_position - result = file.contents[start_position, position - start_position] + if position.offset > start_position + result = file.contents[start_position, position.offset - start_position] result unless result.empty? end end @@ -172,14 +184,14 @@ module Mint # Returns whether or not the word is at the current position. def word?(word) : Bool word.chars.each_with_index.all? do |char, i| - input[position + i]? == char + input[position.offset + i]? == char end end # Consumes a word and steps the cursor forward if successful. def word!(expected : String) : Bool if word?(expected) - @position += expected.size + expected.size.times.each { step } true else false @@ -188,8 +200,10 @@ module Mint # Consumes a word and saves it as a keyword for syntax highlighting. def keyword!(expected : String) : Bool + start_position = position + word!(expected).tap do |result| - @ast.keywords << {position - expected.size, position} if result + @ast.keywords << {from: start_position, to: position} if result end end @@ -208,7 +222,7 @@ module Mint def whitespace! : Bool parse do |start_position| whitespace - next false if position == start_position + next false if position.offset == start_position true end end diff --git a/src/parser/location.cr b/src/parser/location.cr new file mode 100644 index 000000000..be1b1c883 --- /dev/null +++ b/src/parser/location.cr @@ -0,0 +1,30 @@ +module Mint + class Parser + # Offset (from the start of the file), line and column. + record Location, offset : Int64, line : Int64, column : Int64 do + def initialize + @offset = 0 + @column = 0 + @line = 1 + end + + def -(other : Int64) : Location + Location.new( + offset: offset - other, + column: column - other, + line: line) + end + + def +(other : Int64) : Location + Location.new( + offset: offset + other, + column: column + other, + line: line) + end + + def to_tuple + {offset, line, column} + end + end + end +end diff --git a/src/parsers/html_element.cr b/src/parsers/html_element.cr index 6ec3465ee..1a3e22072 100644 --- a/src/parsers/html_element.cr +++ b/src/parsers/html_element.cr @@ -11,7 +11,7 @@ module Mint styles = many(parse_whitespace: false) { html_style } # We need to consume the double colon for the error. - @position += 2 if word? "::" + word! "::" next error :html_element_expected_style do expected "the style for an HTML element", word diff --git a/src/parsers/operator.cr b/src/parsers/operator.cr index 2d3f7b9e9..49180d9e7 100644 --- a/src/parsers/operator.cr +++ b/src/parsers/operator.cr @@ -61,9 +61,9 @@ module Mint keyword! "return" end - ast.keywords << {saved_position, saved_position + operator.size} + ast.keywords << {from: saved_position, to: saved_position + operator.size} else - ast.operators << {saved_position, saved_position + operator.size} + ast.operators << {from: saved_position, to: saved_position + operator.size} end whitespace diff --git a/src/parsers/type_destructuring.cr b/src/parsers/type_destructuring.cr index 587d43877..f21cbe70a 100644 --- a/src/parsers/type_destructuring.cr +++ b/src/parsers/type_destructuring.cr @@ -28,19 +28,32 @@ module Mint parent_name = parts.join('.') + parent_size = + parent_name.size + + variant_size = + variant_name.size + + # It is safe to add the parents size to the column + # because it cannot be on a different line. parent_to = - start_position + parent_name.size + start_position + parent_size + + variant_to = + parent_to + (1 + variant_size) - {Ast::Id.new( - from: start_position, - value: parent_name, - to: parent_to, - file: file), - Ast::Id.new( - to: parent_to + 1 + variant_name.size, - value: variant_name, - from: parent_to, - file: file)} + { + Ast::Id.new( + from: start_position, + value: parent_name, + to: parent_to, + file: file), + Ast::Id.new( + value: variant_name, + from: parent_to, + to: variant_to, + file: file), + } else {nil, name} end diff --git a/src/scope.cr b/src/scope.cr index 9315acc1f..2f4f6e3c0 100644 --- a/src/scope.cr +++ b/src/scope.cr @@ -24,7 +24,12 @@ module Mint # We track the level of a node in here. getter nodes = {} of Ast::Node => Level - getter root = Level.new(Ast::Node.new(Parser::File.new("", ""), 0, 0)) + getter root = + Level.new( + Ast::Node.new( + Parser::File.new("", ""), + Parser::Location.new, + Parser::Location.new)) def initialize(@ast : Ast) (@ast.unified_locales + diff --git a/src/semantic_tokenizer.cr b/src/semantic_tokenizer.cr index 5976b6b3a..2532f21af 100644 --- a/src/semantic_tokenizer.cr +++ b/src/semantic_tokenizer.cr @@ -34,9 +34,9 @@ module Mint # Represents a semantic token using the positions of the token instead # of line / column (for the LSP it is converted to line /column). record Token, - type : TokenType, - from : Int64, - to : Int64 + from : Parser::Location, + to : Parser::Location, + type : TokenType # We keep a cache of all tokenized nodes to avoid duplications getter cache = Set(Ast::Node).new @@ -102,10 +102,10 @@ module Mint position = 0 - tokenizer.tokens.sort_by(&.from).each do |token| - parts << contents[position, token.from - position] if token.from > position - parts << {token.type, contents[token.from, token.to - token.from]} - position = token.to + tokenizer.tokens.sort_by(&.from.offset).each do |token| + parts << contents[position, token.from.offset - position] if token.from.offset > position + parts << {token.type, contents[token.from.offset, token.to.offset - token.from.offset]} + position = token.to.offset end if position < contents.size @@ -165,8 +165,8 @@ module Mint def tokenize(ast : Ast) : Nil # We add the operators and keywords directly from the AST - ast.operators.each { |(from, to)| add(from, to, :operator) } - ast.keywords.each { |(from, to)| add(from, to, :keyword) } + ast.operators.each { |item| add(item[:from], item[:to], :operator) } + ast.keywords.each { |item| add(item[:from], item[:to], :keyword) } tokenize(ast.nodes) end @@ -207,9 +207,9 @@ module Mint case node when Ast::HereDocument if node.highlight - node.from + node.token.size + 14 # The highlight keyword + node.from + (node.token.size + 14) # The highlight keyword else - node.from + node.token.size + 3 + node.from + (node.token.size + 3) end else node.from @@ -255,7 +255,7 @@ module Mint end end - def add(from : Int64, to : Int64, type : TokenType) + def add(from : Parser::Location, to : Parser::Location, type : TokenType) tokens << Token.new( type: type, from: from, diff --git a/src/style_builder.cr b/src/style_builder.cr index 207694a43..53f0343a7 100644 --- a/src/style_builder.cr +++ b/src/style_builder.cr @@ -158,7 +158,7 @@ module Mint conditions .flatten - .sort_by!(&.from) + .sort_by!(&.from.offset) .map do |item| proc = (Proc(String, String).new { |name| diff --git a/src/test_runner/message.cr b/src/test_runner/message.cr index f3aff2047..2bfbd4ac4 100644 --- a/src/test_runner/message.cr +++ b/src/test_runner/message.cr @@ -1,9 +1,17 @@ module Mint class TestRunner class Message + struct Location + include JSON::Serializable + + getter start : {Int64, Int64} + getter end : {Int64, Int64} + getter filename : String + end + include JSON::Serializable - property location : Ast::Node::Location? + property location : Location? property result : String? property suite : String? property name : String? diff --git a/src/utils/source_map_generator.cr b/src/utils/source_map_generator.cr index f77eca27a..6fcd800e8 100644 --- a/src/utils/source_map_generator.cr +++ b/src/utils/source_map_generator.cr @@ -58,16 +58,11 @@ module Mint VLQ.encode(column - last) if node = item[0] - # TODO: After the refactor of location remove - # this temporary variable. - location = - node.location - source_line = - location.start[0] - 1 + node.from.line - 1 source_column = - location.start[1] + node.from.column source_index = get_source_index(node.file)