slackhq / hack-sql-fake

A library for testing database driven code in Hack

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Is each TokenType as valid Operator?

lexidor opened this issue · comments

Issue template for hack-sql-fake

  • [ X ] Question

Question

This line https://github.com/slackhq/hack-sql-fake/blob/master/src/Expressions/FunctionExpression.php#L21 takes a $this->type TokenType::enum and casts it to a string. It then assigns it to a property called $this->operator string. I presume that this property must have the type ?Operator::enum (new in #21). It seems very weird that these values are valid members of Operator::enum.

  • Should I add the to these values Operator::enum too? If no, what should I do with this assignment? HH_FIXME will be required.
  • If not, adding them to the Operator::enum will make the code less maintainable, since Hack does not support this.
enum ONE: int { ONE = 1; }
enum TWO_AND_ONE: int { use ONE; TWO = 2; }

TokenType for reference.

enum TokenType: string {
  NUMERIC_CONSTANT = "Number";
  STRING_CONSTANT = "String";
  CLAUSE = "Clause";
  OPERATOR = "Operator";
  RESERVED = "Reserved";
  PAREN = "Paren";
  SEPARATOR = "Separator";
  SQLFUNCTION = "Function";
  IDENTIFIER = "Identifier";
  NULL_CONSTANT = "Null";
}

Good point! I think $this->operator should be nullable and should be left null on FunctionExpression and the other classes that set it to random string values. There are quite a few expression types, including this one, for which Operator is not a relevant thing. It's really only a thing for BinaryOperatorExpression and UnaryExpression, I believe.

Yeah, those are the only two Expression types that actually use ->operator at all, so it can remain null for all other expression types.

$this->operator was already set to an empty string in the super class Expression. I mapped the value to null during this conversion.

Okay so I would be thinking of doing this.

function operator_try(?string $operatorish): ?Operator{
  if($operatorish is Operator){
    return $operatorish;
  }
  if(!Str\is_empty($operatorish)){
    trigger_error("Expected to turn {$operatorish} into an operator, but failed. Defaulting to null.");
  }
  return null;
}

What would be the Slack analoge for trigger_error?

Just throw new Exception I think. It's ok to use an exception for this, since it shouldn't be possible other than due to a coding error.

However, other than the logging I think you could avoid the function call entirely with $operatorish ?as Operator?

The operation is more analogous to $opish !== '' ? $opish as ?Operator : null. Are exceptions that are uncaught something that is tolerated in this codebase? In that case I'll use an InvariantException or and UnexpectedValueException. Pick your favorite.

I think ?as will do the right thing? It will become null if it's not a valid Operator, no matter the type. Note this is ?as not as so no exception will be thrown.

The docs for enums seem to be gone but I think this replaces Operator::coerce() whereas as without the leading question mark is like Operator::assert();

Uncaught exceptions aren't tolerated, they are rethrown.

There only ended up being one use site.