Skip to content

Commit

Permalink
Reason v4 - Parse Hashtags for polymorphic variants.
Browse files Browse the repository at this point in the history
Summary:

Implements parsing for "hashtags" polymorphic variant constructors.
Since Reason Syntax still supports object syntax, we needed to rearrange
some syntactic real estate to make this work.

```reason
let red = #FF000;

let isRed = color => switch(color) {
  | #FF0000 => true
  | _ => false
};

let callAMethod = someObject::methodName(isRed, "testing red");

let templateLiteral = `
  String template literals are still using backticks.
  String template literals are still using backticks.
`;

```

Test Plan:

Reviewers:

CC:
  • Loading branch information
jordwalke committed Aug 6, 2020
1 parent ce9fac6 commit 54fafb2
Show file tree
Hide file tree
Showing 22 changed files with 824 additions and 380 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Even if you have an explicit v3.6 marker.
* This whole file wil be auto-upaded to 3.8 becase something uses
* angle brackets.
*/;
[@reason.version 3.8];
let watchThisIsOldStyle: list<int> = [1, 2];

let watchThisIsOldStylePoly = #hello;

/**
* This will cause the whole file to be promoted.
*/
let x: list<int> = [1, 3];
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[@reason.version 3.8];
/**
* Test auto-promotion based on feature inference even if no version
* tag. By default you're using the old 3.7.
*/
let watchThisIsOldStyle: list<int> = [1, 2];

let watchThisIsOldStylePoly = #hello;

/**
* This will cause the whole file to be promoted.
*/
let x: list<int> = [1, 3];
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[@reason.version 3.7];
/**
* This should just print a 3.7 version attr at the top.
*/
let watchThisIsOldStyle: list(int) = [1, 2];
50 changes: 41 additions & 9 deletions formatTest/typeCheckedTests/expected_output/oo_3_dot_8.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,36 @@

[@reason.version 3.8];

type canStillDefineConst =
| []
| ::(int, canStillDefineConst);

class virtual stack <'a> (init) = {
as self;
/*
* The "as this" is implicit and will be formatted away.
*/
val virtual dummy: unit;
val mutable v: list<'a> = init;
pub virtual implementMe: int => int;
pub is_empty = () =>
switch (v) {
| [] => true
| _ => false
};
pub is_empty_unitless =
switch (v) {
| [] => true
| _ => false
};
pub empty_unitless = {
v = [];
self;
};
pub empty = () => {
v = [];
self;
};
pub pop =
switch (v) {
| [hd, ...tl] =>
Expand Down Expand Up @@ -90,6 +113,15 @@ class extendedStackAcknowledgeOverride

let inst = (new extendedStack)([1, 2]);

let wasItFull =
!inst::empty()::empty_unitless::is_empty();
// this is the same
let wasItFull' =
!inst::empty()::empty_unitless::is_empty();

let orig_not = (!);
let (!) = o => o::empty();

/**
* Recursive classes.
*/
Expand Down Expand Up @@ -195,7 +227,7 @@ let acceptsOpenAnonObjAsArg =
y: int,
},
) =>
o#x + o#y;
o::x + o::y;
let acceptsClosedAnonObjAsArg =
(
o: {
Expand All @@ -204,7 +236,7 @@ let acceptsClosedAnonObjAsArg =
y: int,
},
) =>
o#x + o#y;
o::x + o::y;
let res =
acceptsOpenAnonObjAsArg({
pub x = 0;
Expand Down Expand Up @@ -346,13 +378,13 @@ let x: tupleClass<int, int> = {
pub pr = (10, 10)
};

let x: #tupleClass<int, int> = x;
let x: *tupleClass<int, int> = x;

let incrementMyClassInstance:
(int, #tupleClass<int, int>) =>
#tupleClass<int, int> =
(int, *tupleClass<int, int>) =>
*tupleClass<int, int> =
(i, inst) => {
let (x, y) = inst#pr;
let (x, y) = inst::pr;
{pub pr = (x + i, y + i)};
};

Expand All @@ -361,7 +393,7 @@ class myClassWithNoTypeParams = {};
* The #myClassWithNoTypeParams should be treated as "simple"
*/
type optionalMyClassSubtype<'a> =
option<#myClassWithNoTypeParams> as 'a;
option<*myClassWithNoTypeParams> as 'a;

/**
* Remember, "class type" is really "class_instance_type" (which is the type of
Expand Down Expand Up @@ -398,7 +430,7 @@ class addablePoint:
one: addablePointClassType,
two: addablePointClassType,
) =>
one#x + two#x + one#y + two#x;
one::x + two::x + one::y + two::x;
pub x: int = init;
pub y = init;
};
Expand All @@ -412,7 +444,7 @@ class addablePoint2:
one: addablePointClassType,
two: addablePointClassType,
) =>
one#x + two#x + one#y + two#x;
one::x + two::x + one::y + two::x;
pub x: int = init;
pub y = init;
};
Expand Down
36 changes: 18 additions & 18 deletions formatTest/typeCheckedTests/expected_output/typeParameters.re
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
/**
* Testing type parameters.
*/;
[@reason.version 3.7];
[@reason.version 3.8];

type threeThings('t) = ('t, 't, 't);
type listOf('t) = list('t);
type threeThings<'t> = ('t, 't, 't);
type listOf<'t> = list<'t>;

type underscoreParam(_) =
type underscoreParam<_> =
| Underscored;
type underscoreParamCovariance(+_) =
type underscoreParamCovariance<+_> =
| Underscored;
type underscoreParamContravariance(-_) =
type underscoreParamContravariance<-_> =
| Underscored;

type tickParamCovariance(+'a) =
type tickParamCovariance<+'a> =
| Underscored;
type tickParamContravariance(-'a) =
type tickParamContravariance<-'a> =
| Underscored;

let x: option(list('a)) = None;
type myFunctionType('a) = (
list(('a, 'a)),
int => option(list('a)),
let x: option<list<'a>> = None;
type myFunctionType<'a> = (
list<('a, 'a)>,
int => option<list<'a>>,
);
let funcAnnoted = (~a: list(int)=[0, 1], ()) => a;
let funcAnnoted = (~a: list<int>=[0, 1], ()) => a;

/**
* Syntax that would be likely to conflict with lexing parsing of < > syntax.
Expand All @@ -46,12 +46,12 @@ let isSuperGreaterThanEqNegFive3 = zero >>= (-5);

let jsx = (~children, ()) => 0;

type t('a) = 'a;
let optionArg = (~arg: option(t(int))=?, ()) => arg;
type t<'a> = 'a;
let optionArg = (~arg: option<t<int>>=?, ()) => arg;
let optionArgList =
(~arg: option(list(list(int)))=?, ()) => arg;
let defaultJsxArg = (~arg: t(int)=<jsx />, ()) => arg;
let defaultFalse = (~arg: t(bool)=!true, ()) => arg;
(~arg: option<list<list<int>>>=?, ()) => arg;
let defaultJsxArg = (~arg: t<int>=<jsx />, ()) => arg;
let defaultFalse = (~arg: t<bool>=!true, ()) => arg;
/* Doesn't work on master either let defaultTrue = (~arg:t<bool>= !!true) => arg; */

/**
Expand Down
14 changes: 14 additions & 0 deletions formatTest/typeCheckedTests/input/autoUpgradeAngleBrackets.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Even if you have an explicit v3.6 marker.
* This whole file wil be auto-upaded to 3.8 becase something uses
* angle brackets.
*/
[@reason.version 3.6];
let watchThisIsOldStyle : list(int) = [1, 2];

let watchThisIsOldStylePoly = `hello;

/**
* This will cause the whole file to be promoted.
*/
let x : list<int> = [1, 3];
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Test auto-promotion based on feature inference even if no version
* tag. By default you're using the old 3.7.
*/
let watchThisIsOldStyle : list(int) = [1, 2];

let watchThisIsOldStylePoly = `hello;

/**
* This will cause the whole file to be promoted.
*/
let x : list<int> = [1, 3];
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* This should just print a 3.7 version attr at the top.
*/
let watchThisIsOldStyle : list(int) = [1, 2];

50 changes: 41 additions & 9 deletions formatTest/typeCheckedTests/input/oo_3_dot_8.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,36 @@

[@reason.version 3.8];

type canStillDefineConst =
| []
| :: (int, canStillDefineConst);

class virtual stack('a) (init) = {
as self;
/*
* The "as this" is implicit and will be formatted away.
*/
val virtual dummy: unit;
val mutable v: list<'a> = init;
pub virtual implementMe: int => int;
pub is_empty = () =>
switch (v) {
| [] => true
| _ => false
};
pub is_empty_unitless =
switch (v) {
| [] => true
| _ => false
};
pub empty_unitless = {
v = [];
self
};
pub empty = () => {
v = [];
self;
};
pub pop =
switch (v) {
| [hd, ...tl] =>
Expand Down Expand Up @@ -90,6 +113,15 @@ class extendedStackAcknowledgeOverride

let inst = (new extendedStack)([1, 2]);

let wasItFull = !inst::empty()::empty_unitless::is_empty();
// this is the same
let wasItFull' = !(inst::empty()::empty_unitless::is_empty());

let orig_not = (!);
let (!) = o => o::empty();



/**
* Recursive classes.
*/
Expand Down Expand Up @@ -195,7 +227,7 @@ let acceptsOpenAnonObjAsArg =
y: int,
},
) =>
o#x + o#y;
o::x + o::y;
let acceptsClosedAnonObjAsArg =
(
o: {
Expand All @@ -204,7 +236,7 @@ let acceptsClosedAnonObjAsArg =
y: int,
},
) =>
o#x + o#y;
o::x + o::y;
let res =
acceptsOpenAnonObjAsArg({
pub x = 0;
Expand Down Expand Up @@ -346,13 +378,13 @@ let x: tupleClass<int, int> = {
pub pr = (10, 10)
};

let x: #tupleClass<int, int> = x;
let x: *tupleClass<int, int> = x;

let incrementMyClassInstance:
(int, #tupleClass<int, int>) =>
#tupleClass<int, int> =
(int, *tupleClass<int, int>) =>
*tupleClass<int, int> =
(i, inst) => {
let (x, y) = inst#pr;
let (x, y) = inst::pr;
{pub pr = (x + i, y + i)};
};

Expand All @@ -361,7 +393,7 @@ class myClassWithNoTypeParams = {};
* The #myClassWithNoTypeParams should be treated as "simple"
*/
type optionalMyClassSubtype<'a> =
option< #myClassWithNoTypeParams> as 'a;
option< *myClassWithNoTypeParams> as 'a;

/**
* Remember, "class type" is really "class_instance_type" (which is the type of
Expand Down Expand Up @@ -398,7 +430,7 @@ class addablePoint:
one: addablePointClassType,
two: addablePointClassType,
) =>
one#x + two#x + one#y + two#x;
one::x + two::x + one::y + two::x;
pub x: int = init;
pub y = init;
};
Expand All @@ -412,7 +444,7 @@ class addablePoint2:
one: addablePointClassType,
two: addablePointClassType,
) =>
one#x + two#x + one#y + two#x;
one::x + two::x + one::y + two::x;
pub x: int = init;
pub y = init;
};
Expand Down
12 changes: 12 additions & 0 deletions formatTest/unit_tests/expected_output/class_types.re
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,15 @@ class type t = {
class type t = {
open M;
};

class intTuplesTuples =
class tupleClass(
#tupleClass(int, int),
#tupleClass(int, int),
);

class intTuplesTuples =
class tupleClass(
#tupleClass(int, int),
#tupleClass(int, int),
);
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class type bzz = {

class type t = {
as 'a;
constraint 'a = #s;
constraint 'a = *s;
};

/* https://github.com/facebook/reason/issues/2037 */
Expand Down
Loading

0 comments on commit 54fafb2

Please sign in to comment.