From 285b695a8db2b5f00057931af3e5c8550ac2730e Mon Sep 17 00:00:00 2001 From: Em Chu Date: Mon, 28 Apr 2025 14:09:52 -0700 Subject: [PATCH 1/3] Make `graph.attributes` a Dict --- src/syntax_graph.jl | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/syntax_graph.jl b/src/syntax_graph.jl index bada8ca1..952f8560 100644 --- a/src/syntax_graph.jl +++ b/src/syntax_graph.jl @@ -6,21 +6,14 @@ one or several syntax trees. TODO: Global attributes! """ -struct SyntaxGraph{Attrs} +struct SyntaxGraph edge_ranges::Vector{UnitRange{Int}} edges::Vector{NodeId} - attributes::Attrs + attributes::Dict{Symbol, Any} end -SyntaxGraph() = SyntaxGraph{Dict{Symbol,Any}}(Vector{UnitRange{Int}}(), - Vector{NodeId}(), Dict{Symbol,Any}()) - -# "Freeze" attribute names and types, encoding them in the type of the returned -# SyntaxGraph. -function freeze_attrs(graph::SyntaxGraph) - frozen_attrs = (; pairs(graph.attributes)...) - SyntaxGraph(graph.edge_ranges, graph.edges, frozen_attrs) -end +SyntaxGraph() = SyntaxGraph(Vector{UnitRange{Int}}(), + Vector{NodeId}(), Dict{Symbol,Any}()) function _show_attrs(io, attributes::Dict) show(io, MIME("text/plain"), attributes) @@ -56,7 +49,6 @@ end function ensure_attributes(graph::SyntaxGraph; kws...) g = SyntaxGraph(graph.edge_ranges, graph.edges, Dict(pairs(graph.attributes)...)) ensure_attributes!(g; kws...) - freeze_attrs(g) end function delete_attributes(graph::SyntaxGraph, attr_names...) @@ -64,7 +56,7 @@ function delete_attributes(graph::SyntaxGraph, attr_names...) for name in attr_names delete!(attributes, name) end - SyntaxGraph(graph.edge_ranges, graph.edges, (; pairs(attributes)...)) + SyntaxGraph(graph.edge_ranges, graph.edges, attributes) end function newnode!(graph::SyntaxGraph) @@ -103,14 +95,10 @@ function child(graph::SyntaxGraph, id::NodeId, i::Integer) graph.edges[graph.edge_ranges[id][i]] end -function getattr(graph::SyntaxGraph{<:Dict}, name::Symbol) +function getattr(graph::SyntaxGraph, name::Symbol) getfield(graph, :attributes)[name] end -function getattr(graph::SyntaxGraph{<:NamedTuple}, name::Symbol) - getfield(getfield(graph, :attributes), name) -end - function getattr(graph::SyntaxGraph, name::Symbol, default) get(getfield(graph, :attributes), name, default) end @@ -408,7 +396,7 @@ const SourceAttrType = Union{SourceRef,LineNumberNode,NodeId,Tuple} function SyntaxTree(graph::SyntaxGraph, node::SyntaxNode) ensure_attributes!(graph, kind=Kind, syntax_flags=UInt16, source=SourceAttrType, value=Any, name_val=String) - id = _convert_nodes(freeze_attrs(graph), node) + id = _convert_nodes(graph, node) return SyntaxTree(graph, id) end From dde4ac46a036d034c240c95a92b5b3896ff3eaf2 Mon Sep 17 00:00:00 2001 From: Em Chu Date: Wed, 30 Apr 2025 10:15:30 -0700 Subject: [PATCH 2/3] Allow `SyntaxGraph{<:NamedTuple}`, but don't use it for now --- src/syntax_graph.jl | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/syntax_graph.jl b/src/syntax_graph.jl index 952f8560..cf9b505a 100644 --- a/src/syntax_graph.jl +++ b/src/syntax_graph.jl @@ -6,14 +6,21 @@ one or several syntax trees. TODO: Global attributes! """ -struct SyntaxGraph +struct SyntaxGraph{Attrs} edge_ranges::Vector{UnitRange{Int}} edges::Vector{NodeId} - attributes::Dict{Symbol, Any} + attributes::Attrs end -SyntaxGraph() = SyntaxGraph(Vector{UnitRange{Int}}(), - Vector{NodeId}(), Dict{Symbol,Any}()) +SyntaxGraph() = SyntaxGraph{Dict{Symbol,Any}}(Vector{UnitRange{Int}}(), + Vector{NodeId}(), Dict{Symbol,Any}()) + +# "Freeze" attribute names and types, encoding them in the type of the returned +# SyntaxGraph. +function freeze_attrs(graph::SyntaxGraph) + frozen_attrs = (; pairs(graph.attributes)...) + SyntaxGraph(graph.edge_ranges, graph.edges, frozen_attrs) +end function _show_attrs(io, attributes::Dict) show(io, MIME("text/plain"), attributes) @@ -95,10 +102,14 @@ function child(graph::SyntaxGraph, id::NodeId, i::Integer) graph.edges[graph.edge_ranges[id][i]] end -function getattr(graph::SyntaxGraph, name::Symbol) +function getattr(graph::SyntaxGraph{<:Dict}, name::Symbol) getfield(graph, :attributes)[name] end +function getattr(graph::SyntaxGraph{<:NamedTuple}, name::Symbol) + getfield(getfield(graph, :attributes), name) +end + function getattr(graph::SyntaxGraph, name::Symbol, default) get(getfield(graph, :attributes), name, default) end From 11b3733eaa88b8159065e331c668e9233a9985f3 Mon Sep 17 00:00:00 2001 From: Em Chu Date: Fri, 2 May 2025 13:30:24 -0700 Subject: [PATCH 3/3] Mark `SyntaxGraph` and `SyntaxList` mutable instead --- src/syntax_graph.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/syntax_graph.jl b/src/syntax_graph.jl index cf9b505a..bdbf98e0 100644 --- a/src/syntax_graph.jl +++ b/src/syntax_graph.jl @@ -6,7 +6,7 @@ one or several syntax trees. TODO: Global attributes! """ -struct SyntaxGraph{Attrs} +mutable struct SyntaxGraph{Attrs} edge_ranges::Vector{UnitRange{Int}} edges::Vector{NodeId} attributes::Attrs @@ -56,6 +56,7 @@ end function ensure_attributes(graph::SyntaxGraph; kws...) g = SyntaxGraph(graph.edge_ranges, graph.edges, Dict(pairs(graph.attributes)...)) ensure_attributes!(g; kws...) + freeze_attrs(g) end function delete_attributes(graph::SyntaxGraph, attr_names...) @@ -63,7 +64,7 @@ function delete_attributes(graph::SyntaxGraph, attr_names...) for name in attr_names delete!(attributes, name) end - SyntaxGraph(graph.edge_ranges, graph.edges, attributes) + SyntaxGraph(graph.edge_ranges, graph.edges, (; pairs(attributes)...)) end function newnode!(graph::SyntaxGraph) @@ -407,7 +408,7 @@ const SourceAttrType = Union{SourceRef,LineNumberNode,NodeId,Tuple} function SyntaxTree(graph::SyntaxGraph, node::SyntaxNode) ensure_attributes!(graph, kind=Kind, syntax_flags=UInt16, source=SourceAttrType, value=Any, name_val=String) - id = _convert_nodes(graph, node) + id = _convert_nodes(freeze_attrs(graph), node) return SyntaxTree(graph, id) end @@ -631,7 +632,7 @@ end #------------------------------------------------------------------------------- # Lightweight vector of nodes ids with associated pointer to graph stored separately. -struct SyntaxList{GraphType, NodeIdVecType} <: AbstractVector{SyntaxTree} +mutable struct SyntaxList{GraphType, NodeIdVecType} <: AbstractVector{SyntaxTree} graph::GraphType ids::NodeIdVecType end