From 58c2222f3b6d7f2d7bfc140042868a7b9542c369 Mon Sep 17 00:00:00 2001 From: AdamSpeight2008 Date: Sun, 28 May 2017 23:41:36 +0100 Subject: [PATCH 1/4] Initial work on the proposal TypeOf Many. --- proposals/proposal-typeof-many.md | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 proposals/proposal-typeof-many.md diff --git a/proposals/proposal-typeof-many.md b/proposals/proposal-typeof-many.md new file mode 100644 index 0000000..7414a87 --- /dev/null +++ b/proposals/proposal-typeof-many.md @@ -0,0 +1,74 @@ +# TypeOf Many + +* [x] Proposed +* [ ] Prototype: [Complete](https://github.com/PROTOTYPE_OWNER/roslyn/BRANCH_NAME) +* [ ] Implementation: [In Progress](https://github.com/dotnet/roslyn/BRANCH_NAME) +* [ ] Specification: [Not Started](pr/1) + +## Summary +[summary]: #summary +Extend the capability of `TypeOf obj Is ...` and `TypeOf obj IsNot ...` to check against many types. + +## Motivation +[motivation]: #motivation + +**What cases does it support?** + +This proposal is tightly focused on the two following forms, commonly used to check an object's type against multiple possible types. +```vb.net +dim result0 = (TypeOf obj Is T0) OrElse (TypeOf obj Is T1) OrElse (TypeOf obj Is T2) OrElse (TypeOf obj Is T3) +dim result1 = (TypeOf obj IsNot T0) AndAlso (TypeOf obj IsNot T1) AndAlso (TypeOf obj IsNot T2) AndAlso (TypeOf obj IsNot T3) +``` +**With Propose Syntax** +```vb.net +dim result0 = (TypeOf obj Is {T0,T1,T2,T3}) +dim result1 = (TypeOf obj IsNot {T0,T1,T2,T3}) +``` +**What is the expected outcome?** +The proposed syntax is semantically equivalent to writing the previous form. + +**Why are we doing this?** +Reduces the visual noise when expressing this intent. + +## Detailed design +[design]: #detailed-design +>*This is the bulk of the proposal. Explain the design in enough detail for somebody familiar +with the language to understand, and for somebody familiar with the compiler to implement, and include examples of how the feature is used. This section can start out light before the prototyping phase but should get into specifics and corner-cases as the feature is iteratively designed and implemented.* + +The grammar of a `TypeOf` expression is similar to the following BNF implementation +``` +TypeOfExpression ::= TypeOfKeyword ws+ Expression TypeOfOperand ws+ Target +TypeOfKeyword ::= "TypeOf" +TypeOfOperand ::= (IsOperand | IsNotOperand ) +IsOperand ::= "Is" +IsNotOperand ::= "IsNot" +Target ::= TypeIdentifer +``` +The proposal is to extend the rule `Target` to +``` +Target ::= TypeIdentifer | TypeArray +``` + + +#### TypeArray *(name may change)* + +A `typeArray` is `collection initializer list` consisting only `type identifiers`. +``` +TypeArray ::= BraceOpening ws* TypeIdentifer (WS* Comma WS* TypeIdentifer )* ws* Brace_Closing +Brace_Opening ::= '{' +Brace_Closing ::= '}' +Comma ::= ',' +``` + + +## Drawbacks +[drawbacks]: #drawbacks +> Why should we *not* do this? + +## Alternatives +[alternatives]: #alternatives +> What other designs have been considered? What is the impact of not doing this? + +## Unresolved questions +[unresolved]: #unresolved-questions +> What parts of the design are still TBD? \ No newline at end of file From e633e31075c90e96db8cd8489b1f516ceb040087 Mon Sep 17 00:00:00 2001 From: AdamSpeight2008 Date: Tue, 30 May 2017 18:20:34 +0100 Subject: [PATCH 2/4] Added link to prototype repo (Work In Progress) --- proposals/proposal-typeof-many.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/proposal-typeof-many.md b/proposals/proposal-typeof-many.md index 7414a87..37e4fa7 100644 --- a/proposals/proposal-typeof-many.md +++ b/proposals/proposal-typeof-many.md @@ -1,7 +1,7 @@ # TypeOf Many * [x] Proposed -* [ ] Prototype: [Complete](https://github.com/PROTOTYPE_OWNER/roslyn/BRANCH_NAME) +* [ ] Prototype: [Still A Work In Progress](https://github.com/AdamSpeight2008/roslyn-AdamSpeight2008/tree/master-typeof) * [ ] Implementation: [In Progress](https://github.com/dotnet/roslyn/BRANCH_NAME) * [ ] Specification: [Not Started](pr/1) From c32f2ce85394a6ae19f59343bd1b30a820ceeae4 Mon Sep 17 00:00:00 2001 From: AdamSpeight2008 Date: Tue, 13 Feb 2018 23:03:45 +0000 Subject: [PATCH 3/4] Updated the proposal --- proposals/proposal-typeof-many.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/proposals/proposal-typeof-many.md b/proposals/proposal-typeof-many.md index 37e4fa7..3b246f1 100644 --- a/proposals/proposal-typeof-many.md +++ b/proposals/proposal-typeof-many.md @@ -1,7 +1,13 @@ # TypeOf Many +* [x] VBLang Issue [#23](https://github.com/dotnet/vblang/issues/23) * [x] Proposed -* [ ] Prototype: [Still A Work In Progress](https://github.com/AdamSpeight2008/roslyn-AdamSpeight2008/tree/master-typeof) +* [x] Prototype: [Proof Of Concept](https://github.com/AdamSpeight2008/roslyn-AdamSpeight2008/tree/master_typeof2) + * [x] Syntax and Bound Nodes + * [x] Parser + * [x] Binder + * [x] Lowering + * [ ] Tooling Support * [ ] Implementation: [In Progress](https://github.com/dotnet/roslyn/BRANCH_NAME) * [ ] Specification: [Not Started](pr/1) @@ -42,7 +48,7 @@ TypeOfKeyword ::= "TypeOf" TypeOfOperand ::= (IsOperand | IsNotOperand ) IsOperand ::= "Is" IsNotOperand ::= "IsNot" -Target ::= TypeIdentifer +Target ::= TypeIdentifer ``` The proposal is to extend the rule `Target` to ``` From f58ce3faf6424a91ed251a45829ee1de78fe31db Mon Sep 17 00:00:00 2001 From: AdamSpeight2008 Date: Sun, 6 Oct 2019 03:50:34 +0100 Subject: [PATCH 4/4] Updated the TypeOfManyExpression proposal, with a different syntax. As well as new feature, IntoExpression. --- proposals/proposal-typeof-many.md | 101 +++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 24 deletions(-) diff --git a/proposals/proposal-typeof-many.md b/proposals/proposal-typeof-many.md index 3b246f1..83ca33b 100644 --- a/proposals/proposal-typeof-many.md +++ b/proposals/proposal-typeof-many.md @@ -1,8 +1,8 @@ -# TypeOf Many +# TypeOf Many & TypeOf Into Expressions * [x] VBLang Issue [#23](https://github.com/dotnet/vblang/issues/23) * [x] Proposed -* [x] Prototype: [Proof Of Concept](https://github.com/AdamSpeight2008/roslyn-AdamSpeight2008/tree/master_typeof2) +* [x] Prototype: [Proof Of Concept](https://github.com/AdamSpeight2008/roslyn-AdamSpeight2008/tree/TypeOf_Into) * [x] Syntax and Bound Nodes * [x] Parser * [x] Binder @@ -11,12 +11,14 @@ * [ ] Implementation: [In Progress](https://github.com/dotnet/roslyn/BRANCH_NAME) * [ ] Specification: [Not Started](pr/1) -## Summary -[summary]: #summary +--------- + +## TypeOfManyExpression Summary +[typeofmanyexpressionsummary]: #typeofmanyexpressionsummary Extend the capability of `TypeOf obj Is ...` and `TypeOf obj IsNot ...` to check against many types. ## Motivation -[motivation]: #motivation +[typeofmanyexpressionmotivation]: #typeofmanyexpressionmotivation **What cases does it support?** @@ -27,8 +29,8 @@ dim result1 = (TypeOf obj IsNot T0) AndAlso (TypeOf obj IsNot T1) AndAlso (TypeO ``` **With Propose Syntax** ```vb.net -dim result0 = (TypeOf obj Is {T0,T1,T2,T3}) -dim result1 = (TypeOf obj IsNot {T0,T1,T2,T3}) +dim result0 = (TypeOf obj Is (Of T0,T1,T2,T3)) +dim result1 = (TypeOf obj IsNot (Of T0,T1,T2,T3)) ``` **What is the expected outcome?** The proposed syntax is semantically equivalent to writing the previous form. @@ -37,7 +39,7 @@ The proposed syntax is semantically equivalent to writing the previous form. Reduces the visual noise when expressing this intent. ## Detailed design -[design]: #detailed-design +[typeofmanyexpressiondesign]: #typeofmanyexpressiondetailed-design >*This is the bulk of the proposal. Explain the design in enough detail for somebody familiar with the language to understand, and for somebody familiar with the compiler to implement, and include examples of how the feature is used. This section can start out light before the prototyping phase but should get into specifics and corner-cases as the feature is iteratively designed and implemented.* @@ -52,29 +54,80 @@ Target ::= TypeIdentifer ``` The proposal is to extend the rule `Target` to ``` -Target ::= TypeIdentifer | TypeArray +Target ::= TypeIdentifer | TypeArgumentList +``` + +`TypeArgumentList` is the form used for when specifying generic type arguments `(Of T0, T1 ...)`. + +------ + +## TypeOfIntoExpression Summary +[typeofintoexpressionsummary]: #typeofintoexpressionsummary +Extends `TypeOf expression Is type` to `TypeOf expression Is type Into variable`. +Where if the first part of the expression is true, also cast the expression to type. + +## Motivation + +```vbnet +Dim variable As T = Nothing +If TypeOf expression Is T Then + variable = DirectCast(expression, T) +End If +``` + +This also has the benefit of the allowing use the resultant cast further with in the expression. eg. +```vb +If TypeOf obj Is Int32 Into value AndAlso value > 0 Then + ``` +**What cases does it support?** -#### TypeArray *(name may change)* +The only form of `TypeOfExpression` supported is `TypeOf expression Is type`. -A `typeArray` is `collection initializer list` consisting only `type identifiers`. +*Question* +Should we also support `TypeOfManyExpression`, where the target type is dominate type, of the types in the list? +```vbnet + Dim variable As ExpressionSyntax + If TypeOf expression Is (Of TryCastExpression, DirectCastExpression) Into variable Then ``` -TypeArray ::= BraceOpening ws* TypeIdentifer (WS* Comma WS* TypeIdentifer )* ws* Brace_Closing -Brace_Opening ::= '{' -Brace_Closing ::= '}' -Comma ::= ',' + +## Lowering + +When lowering `IntoVariableExpression` that have `TypeOfExpression` on the left. +Then the one of the following lowerings are use. + +If the `targettype` is `String` the expression is equivalent to calling the following function +` If [Is](Of type)( expression, variable ) Then` +```vbnet +Function [Is](Of T As Class)( exression As Object, ByRef variable As T) As Boolean + variable = TryCast( expression, T) + Return variable IsNot Nothing +End Function +``` + +Otherwise +```vbnet +Function [Is](Of T As Structure)( expression As Object, variable As T ) As Boolean + Dim tmp As T? = DirectCast(expression, T?) + variable = tmp.GetValueOrDefault() + Return tmp IsNot Nothing +End Function ``` -## Drawbacks -[drawbacks]: #drawbacks -> Why should we *not* do this? +## Detailed design +[typeofintoexpressiondesign]: #detailed-design + +Strictly speaking `TypeOfIntoExpression` isnot an expression but an 'IntoVariableExpression` that has a `TypeOfExpression` as its `Expression` argument. + +**Grammar** ` IntoVariableExpression ::= expression "Info" expression ; ` + +Acts like a binary operator expression +` [Into](expression As ExpressionSyntax, ByRef variable As ExpressionSyntax ) As ExpressionSyntax ` + +The type of returned expression, is the same as the return type as the expression on the left. +This allows it to act transparently in expressions. -## Alternatives -[alternatives]: #alternatives -> What other designs have been considered? What is the impact of not doing this? +In the prototype its usage is restricted to typeofexpression. -## Unresolved questions -[unresolved]: #unresolved-questions -> What parts of the design are still TBD? \ No newline at end of file