-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LSP: A bunch of new OpenGOAL language features (#3437)
- Integrate the AST into the LSP, this makes parsing and tokenizing the files much easier - Consolidate most of the symbol info tracking in `goalc` to a single map. Fixed some issues where the old map would never evict symbols when re-compiling files. There is still some more to cleanup, but this now can be used as an incrementally updated source-of-truth for the LSP - re-compile files when they are saved. Ideally this would be done everytime they are changed but that: - may be too aggressive - goalc doesn't compile incrementally yet so it likely would be a worse UX Features added, see open-goal/opengoal-vscode#256 - Hover ![image](https://github.com/open-goal/jak-project/assets/13153231/58dadb5d-582c-4c1f-9ffe-eaa4c85a0255) ![image](https://github.com/open-goal/jak-project/assets/13153231/b383adde-57fc-462c-a256-b2de5c30ca9a) - LSP Status fixed - Type Hierarchy ![image](https://github.com/open-goal/jak-project/assets/13153231/8e681377-1d4e-4336-ad70-1695a4607340) - Document Color ![image](https://github.com/open-goal/jak-project/assets/13153231/4e48ccd8-0ed1-4459-a133-5277561e4201) - Document Symbols ![Screenshot 2024-03-27 004105](https://github.com/open-goal/jak-project/assets/13153231/8e655034-43c4-4261-b6e0-85de00cbfc7f) - Completions ![Screenshot 2024-03-30 004504](https://github.com/open-goal/jak-project/assets/13153231/d123a187-af90-466b-9eb7-561b2ee97cd1) --------- Co-authored-by: Hat Kid <[email protected]>
- Loading branch information
Showing
335 changed files
with
26,020 additions
and
9,736 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
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
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
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 |
---|---|---|
|
@@ -67,4 +67,4 @@ class Range { | |
private: | ||
T m_start = {}; | ||
T m_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#include "ast_util.h" | ||
|
||
namespace ast_util { | ||
std::string get_source_code(const std::string& source, const TSNode& node) { | ||
uint32_t start = ts_node_start_byte(node); | ||
uint32_t end = ts_node_end_byte(node); | ||
return source.substr(start, end - start); | ||
} | ||
|
||
void search_for_forms_that_begin_with(const std::string& source, | ||
const TSNode curr_node, | ||
const std::vector<std::string>& prefix, | ||
std::vector<TSNode>& results) { | ||
if (ts_node_child_count(curr_node) == 0) { | ||
return; | ||
} | ||
std::vector<std::string> node_elements; | ||
bool added = false; | ||
for (size_t i = 0; i < ts_node_child_count(curr_node); i++) { | ||
const auto child_node = ts_node_child(curr_node, i); | ||
const auto contents = get_source_code(source, child_node); | ||
node_elements.push_back(contents); | ||
// Check for a match | ||
if (node_elements == prefix && !added) { | ||
results.push_back(curr_node); | ||
added = true; | ||
} | ||
search_for_forms_that_begin_with(source, child_node, prefix, results); | ||
} | ||
} | ||
} // namespace ast_util |
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,15 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include "tree_sitter/api.h" | ||
|
||
namespace ast_util { | ||
std::string get_source_code(const std::string& source, const TSNode& node); | ||
void search_for_forms_that_begin_with(const std::string& source, | ||
const TSNode curr_node, | ||
const std::vector<std::string>& prefix, | ||
std::vector<TSNode>& results); | ||
|
||
} // namespace ast_util |
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,160 @@ | ||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <iostream> | ||
#include <memory> | ||
#include <string> | ||
#include <unordered_map> | ||
#include <vector> | ||
|
||
// TrieMap class | ||
template <typename T> | ||
class TrieMap { | ||
private: | ||
// TrieNode structure | ||
struct TrieNode { | ||
std::unordered_map<char, std::shared_ptr<TrieNode>> children; | ||
std::vector<std::shared_ptr<T>> elements; | ||
}; | ||
|
||
std::shared_ptr<TrieNode> root; | ||
|
||
public: | ||
TrieMap() : root(std::make_shared<TrieNode>()) {} | ||
|
||
// Insert an element with a key into the TrieMap and return the inserted element | ||
std::shared_ptr<T> insert(const std::string& key, const T& element) { | ||
std::shared_ptr<T> shared_element = std::make_shared<T>(element); | ||
std::shared_ptr<TrieNode> node = root; | ||
for (char c : key) { | ||
if (node->children.find(c) == node->children.end()) { | ||
node->children[c] = std::make_shared<TrieNode>(); | ||
} | ||
node = node->children[c]; | ||
} | ||
// Store element at the leaf node | ||
node->elements.push_back(shared_element); | ||
return shared_element; | ||
} | ||
|
||
// Retrieve elements with a given prefix | ||
std::vector<std::shared_ptr<T>> retrieve_with_prefix(const std::string& prefix) const { | ||
std::vector<std::shared_ptr<T>> result; | ||
std::shared_ptr<TrieNode> node = root; | ||
// Traverse to the node representing the prefix | ||
for (char c : prefix) { | ||
if (node->children.find(c) == node->children.end()) { | ||
return result; // No elements with the given prefix | ||
} | ||
node = node->children[c]; | ||
} | ||
// Gather all elements stored at or below this node | ||
retrieve_elements(node, result); | ||
return result; | ||
} | ||
|
||
// Retrieve elements with an exact key match | ||
std::vector<std::shared_ptr<T>> retrieve_with_exact(const std::string& key) const { | ||
std::vector<std::shared_ptr<T>> result; | ||
std::shared_ptr<TrieNode> node = root; | ||
// Traverse to the node representing the key | ||
for (char c : key) { | ||
if (node->children.find(c) == node->children.end()) { | ||
return result; // No elements with the given key | ||
} | ||
node = node->children[c]; | ||
} | ||
// Return elements stored at this node | ||
return node->elements; | ||
} | ||
|
||
// Remove the specified element from the TrieMap | ||
void remove(const std::shared_ptr<T>& element) { remove_element(root, element); } | ||
|
||
// Return the total number of elements stored in the TrieMap | ||
int size() const { | ||
int count = 0; | ||
count_elements(root, count); | ||
return count; | ||
} | ||
|
||
// Return a vector containing shared pointers to all elements stored in the TrieMap | ||
std::vector<std::shared_ptr<T>> get_all_elements() const { | ||
std::vector<std::shared_ptr<T>> result; | ||
get_all_elements_helper(root, result); | ||
return result; | ||
} | ||
|
||
private: | ||
// Recursive function to retrieve elements stored at or below the given node | ||
void retrieve_elements(std::shared_ptr<TrieNode> node, | ||
std::vector<std::shared_ptr<T>>& result) const { | ||
// Add elements stored at this node to the result | ||
for (const auto& element : node->elements) { | ||
result.push_back(element); | ||
} | ||
// Recursively traverse children | ||
for (const auto& child : node->children) { | ||
retrieve_elements(child.second, result); | ||
} | ||
} | ||
|
||
// Recursive function to remove the specified element from the TrieMap | ||
bool remove_element(std::shared_ptr<TrieNode> node, const std::shared_ptr<T>& element) { | ||
// Remove the element if it exists at this node | ||
auto& elements = node->elements; | ||
auto it = std::find(elements.begin(), elements.end(), element); | ||
if (it != elements.end()) { | ||
elements.erase(it); | ||
return true; | ||
} | ||
// Recursively search children | ||
for (auto& child : node->children) { | ||
if (remove_element(child.second, element)) { | ||
// Remove child node if it's empty after removal | ||
if (child.second->elements.empty() && child.second->children.empty()) { | ||
node->children.erase(child.first); | ||
} | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
// Recursive function to count elements stored at or below the given node | ||
void count_elements(std::shared_ptr<TrieNode> node, int& count) const { | ||
// Increment count by the number of elements stored at this node | ||
count += node->elements.size(); | ||
// Recursively traverse children | ||
for (const auto& child : node->children) { | ||
count_elements(child.second, count); | ||
} | ||
} | ||
|
||
// Recursive helper function to collect all elements stored in the TrieMap | ||
void get_all_elements_helper(std::shared_ptr<TrieNode> node, | ||
std::vector<std::shared_ptr<T>>& result) const { | ||
// Add elements stored at this node to the result | ||
for (const auto& element : node->elements) { | ||
result.push_back(element); | ||
} | ||
// Recursively traverse children | ||
for (const auto& child : node->children) { | ||
get_all_elements_helper(child.second, result); | ||
} | ||
} | ||
}; | ||
|
||
// TrieMap<std::string> trie_map; | ||
// | ||
//// Insert elements | ||
// std::shared_ptr<std::string> inserted_element_1 = trie_map.insert("apple", "A fruit"); | ||
// std::shared_ptr<std::string> inserted_element_2 = trie_map.insert("app", "An application"); | ||
// std::shared_ptr<std::string> inserted_element_3 = trie_map.insert("banana", "Another fruit"); | ||
// std::shared_ptr<std::string> inserted_element_4 = trie_map.insert("apple", "Another apple"); | ||
// | ||
//// Remove an element | ||
// trie_map.remove(inserted_element_1); | ||
// | ||
//// Retrieve elements with a prefix | ||
// std::vector<std::shared_ptr<std::string>> prefix_results = trie_map.retrieve_with_prefix("app"); |
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
Oops, something went wrong.