Skip to content

Commit

Permalink
#132 Hide public fields
Browse files Browse the repository at this point in the history
  • Loading branch information
vityaman committed Aug 5, 2024
1 parent b481aaf commit da80278
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 64 deletions.
31 changes: 22 additions & 9 deletions ports/cpp/source/antlr4-c3/CodeCompletionCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -88,6 +89,18 @@ CodeCompletionCore::CodeCompletionCore(antlr4::Parser* parser)
, cancel(nullptr) {
}

void CodeCompletionCore::setIgnoredTokens(std::unordered_set<size_t>&& ignoredTokens) {
this->ignoredTokens = std::move(ignoredTokens);
}

void CodeCompletionCore::setPreferredRules(std::unordered_set<size_t>&& preferredRules) {
this->preferredRules = std::move(preferredRules);
}

void CodeCompletionCore::setTranslateRulesTopDown(bool isEnabled) {
this->translateRulesTopDown = isEnabled;
}

CandidatesCollection CodeCompletionCore::collectCandidates(
size_t caretTokenIndex, Parameters parameters
) {
Expand Down Expand Up @@ -131,7 +144,7 @@ CandidatesCollection CodeCompletionCore::collectCandidates(

processRule(atn.ruleToStartState[startRule], 0, callStack, 0, 0, candidates.isCancelled);

if (showResult) {
if (show.result) {
if (candidates.isCancelled) {
std::cout << "*** TIMED OUT ***\n";
}
Expand Down Expand Up @@ -266,7 +279,7 @@ bool CodeCompletionCore::translateToRuleIndex(
.startTokenIndex = rwst.startTokenIndex,
.ruleList = path,
};
if (showDebugOutput) {
if (show.debugOutput) {
std::cout << "=====> collected: " << ruleNames[rwst.ruleIndex] << "\n";
}
}
Expand Down Expand Up @@ -481,7 +494,7 @@ CodeCompletionCore::RuleEndStatus CodeCompletionCore::processRule( // NOLINT
// Check first if we've taken this path with the same input before.
std::unordered_map<size_t, RuleEndStatus>& positionMap = shortcutMap[startState->ruleIndex];
if (positionMap.contains(tokenListIndex)) {
if (showDebugOutput) {
if (show.debugOutput) {
std::cout << "=====> shortcut" << "\n";
}
return positionMap[tokenListIndex];
Expand Down Expand Up @@ -538,7 +551,7 @@ CodeCompletionCore::RuleEndStatus CodeCompletionCore::processRule( // NOLINT
if (!translateStackToRuleIndex(fullPath)) {
for (const size_t symbol : set.intervals.toList()) {
if (!ignoredTokens.contains(symbol)) {
if (showDebugOutput) {
if (show.debugOutput) {
std::cout << "=====> collected: " << vocabulary.getDisplayName(symbol) << "\n";
}
if (!candidates.tokens.contains(symbol)) {
Expand Down Expand Up @@ -602,14 +615,14 @@ CodeCompletionCore::RuleEndStatus CodeCompletionCore::processRule( // NOLINT
const size_t currentSymbol = tokens[currentEntry.tokenListIndex]->getType();

const bool atCaret = currentEntry.tokenListIndex >= tokens.size() - 1;
if (showDebugOutput) {
if (show.debugOutput) {
printDescription(
indentation,
currentEntry.state,
generateBaseDescription(currentEntry.state),
currentEntry.tokenListIndex
);
if (showRuleStack) {
if (show.ruleStack) {
printRuleState(callStack);
}
}
Expand Down Expand Up @@ -720,7 +733,7 @@ CodeCompletionCore::RuleEndStatus CodeCompletionCore::processRule( // NOLINT
const bool hasTokenSequence = list.size() == 1;
for (const size_t symbol : list) {
if (!ignoredTokens.contains(symbol)) {
if (showDebugOutput) {
if (show.debugOutput) {
std::cout << "=====> collected: " << vocabulary.getDisplayName(symbol)
<< "\n";
}
Expand All @@ -741,7 +754,7 @@ CodeCompletionCore::RuleEndStatus CodeCompletionCore::processRule( // NOLINT
}
} else {
if (set.contains(currentSymbol)) {
if (showDebugOutput) {
if (show.debugOutput) {
std::cout << "=====> consumed: " << vocabulary.getDisplayName(currentSymbol)
<< "\n";
}
Expand Down Expand Up @@ -794,7 +807,7 @@ void CodeCompletionCore::printDescription(
const auto indent = std::string(indentation * 2, ' ');

std::string transitionDescription;
if (debugOutputWithTransitions) {
if (show.debugOutputWithTransitions) {
for (const antlr4::atn::ConstTransitionPtr& transition : state->transitions) {
std::string labels;
std::vector<ptrdiff_t> symbols = transition->label().toList();
Expand Down
65 changes: 36 additions & 29 deletions ports/cpp/source/antlr4-c3/CodeCompletionCore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <chrono>
#include <cstddef>
#include <map>
#include <optional>
#include <string>
#include <typeindex>
#include <unordered_map>
Expand Down Expand Up @@ -128,44 +129,49 @@ class CodeCompletionCore {
* Tailoring of the result:
* Tokens which should not appear in the candidates set.
*/
std::unordered_set<size_t> ignoredTokens; // NOLINT: public field
void setIgnoredTokens(std::unordered_set<size_t>&& ignoredTokens);

/**
* Rules which replace any candidate token they contain.
* This allows to return descriptive rules (e.g. className, instead of
* ID/identifier).
*/
std::unordered_set<size_t> preferredRules; // NOLINT: public field
void setPreferredRules(std::unordered_set<size_t>&& preferredRules);

/**
* Specify if preferred rules should translated top-down (higher index rule
* returns first) or bottom-up (lower index rule returns first).
*/
bool translateRulesTopDown = false; // NOLINT: public field
void setTranslateRulesTopDown(bool isEnabled);

// --------------------------------------------------------
// Debugging Options
// --------------------------------------------------------
// Print human readable ATN state and other info.

/** Not dependent on showDebugOutput. Prints the collected rules + tokens to
* terminal. */
bool showResult = false; // NOLINT: public field

/** Enables printing ATN state info to terminal. */
bool showDebugOutput = false; // NOLINT: public field

/** Only relevant when showDebugOutput is true. Enables transition printing
* for a state. */
bool debugOutputWithTransitions = false; // NOLINT: public field

/** Also depends on showDebugOutput. Enables call stack printing for each rule
* recursion. */
bool showRuleStack = false; // NOLINT: public field

// --------------------------------------------------------
// Usage
// --------------------------------------------------------
/**
* Print human readable ATN state and other info.
* NB. This API is only for a debugging and so is volatile.
*/
struct {
/**
* Not dependent on showDebugOutput.
* Prints the collected rules + tokens to terminal.
*/
bool result = false;

/**
* Enables printing ATN state info to terminal.
*/
bool debugOutput = false;

/**
* Only relevant when showDebugOutput is true.
* Enables transition printing for a state.
*/
bool debugOutputWithTransitions = false;

/**
* Also depends on showDebugOutput.
* Enables call stack printing for each rule recursion.
*/
bool ruleStack = false;
} show; // NOLINT: public field, only for debugging

/**
* This is the main entry point. The caret token index specifies the token
Expand All @@ -183,13 +189,14 @@ class CodeCompletionCore {
*/
CandidatesCollection collectCandidates(size_t caretTokenIndex, Parameters parameters = {});

// --------------------------------------------------------
// Private
// --------------------------------------------------------
private:
static std::unordered_map<std::type_index, FollowSetsPerState> followSetsByATN;
static std::vector<std::string> atnStateTypeMap;

std::unordered_set<size_t> ignoredTokens;
std::unordered_set<size_t> preferredRules;
bool translateRulesTopDown = false;

antlr4::Parser* parser;
antlr4::atn::ATN const& atn; // NOLINT: reference field
antlr4::dfa::Vocabulary const& vocabulary; // NOLINT: reference field
Expand Down
31 changes: 15 additions & 16 deletions ports/cpp/test/cpp14/Cpp14Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ TEST(CPP14Parser, SimpleExample) { // NOLINT: complexity
CodeCompletionCore completion(&pipeline.parser);

// Ignore operators and the generic ID token.
completion.ignoredTokens = {
completion.setIgnoredTokens({
CPP14Lexer::Identifier,
CPP14Lexer::LeftParen,
CPP14Lexer::RightParen,
Expand All @@ -50,17 +50,17 @@ TEST(CPP14Parser, SimpleExample) { // NOLINT: complexity
CPP14Lexer::Ellipsis,
CPP14Lexer::Doublecolon,
CPP14Lexer::Semi,
};
});

// For a C++ grammar you can of course get many candidates of all kind. For
// this test we focus only on a few, namely namespace, class and variable
// references. For variable references there is no own rule, only an
// "idexpression" as part of the primary expression.
completion.preferredRules = {
completion.setPreferredRules({
CPP14Parser::RuleClassname,
CPP14Parser::RuleNamespacename,
CPP14Parser::RuleIdexpression,
};
});

{
// 1) At the input start.
Expand Down Expand Up @@ -154,7 +154,7 @@ TEST(CPP14Parser, SimpleExample) { // NOLINT: complexity
// 2) Within the method body.
// Note when counting token indexes: the C++14 grammar skips all
// whitespaces, hence there are no tokens for them.
completion.translateRulesTopDown = translateRulesTopDown;
completion.setTranslateRulesTopDown(translateRulesTopDown);
auto candidates = completion.collectCandidates(10); // NOLINT: magic

const std::vector idexpressionStack = {
Expand Down Expand Up @@ -239,7 +239,7 @@ TEST(CPP14Parser, SimpleExample) { // NOLINT: complexity
// 2) Within the method body.
// Note when counting token indexes: the C++14 grammar skips all
// whitespaces, hence there are no tokens for them.
completion.translateRulesTopDown = true;
completion.setTranslateRulesTopDown(true);
auto candidates = completion.collectCandidates(10); // NOLINT: magic

EXPECT_EQ(candidates.tokens.size(), 82);
Expand Down Expand Up @@ -281,7 +281,7 @@ TEST(CPP14Parser, SimpleCppExampleWithErrorsInInput) {
CodeCompletionCore completion(&pipeline.parser);

// Ignore operators and the generic ID token.
completion.ignoredTokens = {
completion.setIgnoredTokens({
CPP14Lexer::Identifier,
// Let parentheses show up in this test, so
// CPP14Lexer.LeftParen,
Expand All @@ -294,13 +294,13 @@ TEST(CPP14Parser, SimpleCppExampleWithErrorsInInput) {
CPP14Lexer::Ellipsis,
CPP14Lexer::Doublecolon,
CPP14Lexer::Semi,
};
});

completion.preferredRules = {
completion.setPreferredRules({
CPP14Parser::RuleClassname,
CPP14Parser::RuleNamespacename,
CPP14Parser::RuleIdexpression,
};
});

{
// At the opening parenthesis.
Expand Down Expand Up @@ -360,7 +360,7 @@ TEST(CPP14Parser, RealCppFile) { // NOLINT: complexity
CodeCompletionCore completion(&pipeline.parser);

// Ignore operators and the generic ID token.
completion.ignoredTokens = {
completion.setIgnoredTokens({
CPP14Lexer::Identifier,
CPP14Lexer::LeftParen,
CPP14Lexer::RightParen,
Expand All @@ -372,13 +372,12 @@ TEST(CPP14Parser, RealCppFile) { // NOLINT: complexity
CPP14Lexer::Ellipsis,
CPP14Lexer::Doublecolon,
CPP14Lexer::Semi,
};

completion.preferredRules = {
});
completion.setPreferredRules({
CPP14Parser::RuleClassname,
CPP14Parser::RuleNamespacename,
CPP14Parser::RuleIdexpression,
};
});

const std::vector idexpressionStack = {
CPP14Parser::RuleTranslationunit,
Expand Down Expand Up @@ -439,7 +438,7 @@ TEST(CPP14Parser, RealCppFile) { // NOLINT: complexity
{
// We should receive more specific rules when translating top down.

completion.translateRulesTopDown = true;
completion.setTranslateRulesTopDown(true);
auto candidates = completion.collectCandidates(3469); // NOLINT: magic

EXPECT_THAT(
Expand Down
20 changes: 10 additions & 10 deletions ports/cpp/test/expr/ExprTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,18 @@ TEST(SimpleExpressionParser, TypicalSetup) {
EXPECT_EQ(pipeline.listener.GetErrorCount(), 0);

c3::CodeCompletionCore completion(&pipeline.parser);
completion.ignoredTokens = {
completion.setIgnoredTokens({
ExprLexer::ID,
ExprLexer::PLUS,
ExprLexer::MINUS,
ExprLexer::MULTIPLY,
ExprLexer::DIVIDE,
ExprLexer::EQUAL,
};
completion.preferredRules = {
});
completion.setPreferredRules({
ExprParser::RuleFunctionRef,
ExprParser::RuleVariableRef,
};
});

{
// 1) At the input start.
Expand Down Expand Up @@ -141,7 +141,7 @@ TEST(SimpleExpressionParser, RecursivePreferredRule) {
EXPECT_EQ(pipeline.listener.GetErrorCount(), 0);

c3::CodeCompletionCore completion(&pipeline.parser);
completion.preferredRules = {ExprParser::RuleSimpleExpression};
completion.setPreferredRules({ExprParser::RuleSimpleExpression});

{
// 1) On the variable reference 'a'.
Expand All @@ -152,7 +152,7 @@ TEST(SimpleExpressionParser, RecursivePreferredRule) {
}
{
// 2) On the variable reference 'b'.
completion.translateRulesTopDown = false;
completion.setTranslateRulesTopDown(false);
auto candidates = completion.collectCandidates(10); // NOLINT: magic
EXPECT_THAT(Keys(candidates.rules), UnorderedElementsAre(ExprParser::RuleSimpleExpression));
// When translateRulesTopDown is false, startTokenIndex should match the
Expand All @@ -162,7 +162,7 @@ TEST(SimpleExpressionParser, RecursivePreferredRule) {
}
{
// 3) On the variable reference 'b' topDown preferred rules.
completion.translateRulesTopDown = true;
completion.setTranslateRulesTopDown(true);
auto candidates = completion.collectCandidates(10); // NOLINT: magic
EXPECT_THAT(Keys(candidates.rules), UnorderedElementsAre(ExprParser::RuleSimpleExpression));
// When translateRulesTopDown is true, startTokenIndex should match the
Expand All @@ -178,11 +178,11 @@ TEST(SimpleExpressionParser, CandidateRulesWithDifferentStartTokens) {
EXPECT_EQ(pipeline.listener.GetErrorCount(), 0);

c3::CodeCompletionCore completion(&pipeline.parser);
completion.preferredRules = {
completion.setPreferredRules({
ExprParser::RuleAssignment,
ExprParser::RuleVariableRef,
};
completion.translateRulesTopDown = true;
});
completion.setTranslateRulesTopDown(true);

{
// 1) On the token 'var'.
Expand Down

0 comments on commit da80278

Please sign in to comment.