[Pkg-cli-apps-commits] [fsharp] 32/60: This addresses : codeplex issue: https://visualfsharp.codeplex.com/workitem/72 [Regression] Indexer properties with more than 4 arguments cannot be accessed

Christopher Halse Rogers raof-guest at moszumanska.debian.org
Sun Sep 14 08:13:39 UTC 2014


This is an automated email from the git hooks/post-receive script.

raof-guest pushed a commit to branch master
in repository fsharp.

commit 809d8a984b45584776b15af08c777b47c1d1b765
Author: KevinRansom <kevinr at microsoft.com>
Date:   Thu Jul 31 09:57:25 2014 -0700

    This addresses :
        codeplex issue: https://visualfsharp.codeplex.com/workitem/72
        [Regression] Indexer properties with more than 4 arguments cannot be accessed
    
    Removes limit on indexer arguments, and allows unlimited slice dimensions. (changeset 1309219)
---
 src/fsharp/ast.fs                | 32 +++++++++-----------------------
 src/fsharp/pars.fsy              | 25 ++++++++++++-------------
 tests/fsharp/core/array/test.fsx | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 36 deletions(-)

diff --git a/src/fsharp/ast.fs b/src/fsharp/ast.fs
index 5de5272..d8f1b0f 100644
--- a/src/fsharp/ast.fs
+++ b/src/fsharp/ast.fs
@@ -1725,31 +1725,17 @@ let mkSynApp5 f x1 x2 x3 x4 x5 m = mkSynApp1 (mkSynApp4 f x1 x2 x3 x4 m) x5 m
 let mkSynDotParenSet  m a b c = mkSynTrifix m parenSet a b c
 let mkSynDotBrackGet  m mDot a b   = SynExpr.DotIndexedGet(a,[SynIndexerArg.One b],mDot,m)
 let mkSynQMarkSet m a b c = mkSynTrifix m qmarkSet a b c
-
 let mkSynDotBrackSliceGet  m mDot arr sliceArg = SynExpr.DotIndexedGet(arr,[sliceArg],mDot,m)
 
-let mkSlice m mDot arr sliceArgs = 
-    //let args = [ for arg in sliceArgs do
-    //                match arg with 
-    //                | SynIndexerArg.Range (x1,x2) -> yield x1; yield x2
-    //                | SynIndexerArg.One x -> yield x ]
-    SynExpr.DotIndexedGet(arr,sliceArgs,mDot,m)
-
-let mkSynDotBrackSlice2Get  m mDot arr sliceArg1 sliceArg2 = 
-    match sliceArg1, sliceArg2 with 
-    | SynIndexerArg.One x1, SynIndexerArg.One x2 -> mkSynDotBrackGet m mDot arr (SynExpr.Tuple([x1;x2],[],unionRanges x1.Range x2.Range))
-    | _ -> mkSlice m mDot arr [ sliceArg1; sliceArg2 ] 
-
-let mkSynDotBrackSlice3Get  m mDot arr sliceArg1 sliceArg2 sliceArg3 = 
-    match sliceArg1, sliceArg2, sliceArg3 with 
-    | SynIndexerArg.One x1, SynIndexerArg.One x2, SynIndexerArg.One x3 -> mkSynDotBrackGet m mDot arr (SynExpr.Tuple([x1;x2;x3],[],unionRanges x1.Range x3.Range))
-    | _ -> mkSlice m mDot arr [ sliceArg1; sliceArg2; sliceArg3 ] 
-
-let mkSynDotBrackSlice4Get  m mDot arr sliceArg1 sliceArg2 sliceArg3 sliceArg4 =
-    match sliceArg1, sliceArg2, sliceArg3, sliceArg4 with 
-    | SynIndexerArg.One x1, SynIndexerArg.One x2, SynIndexerArg.One x3, SynIndexerArg.One x4 -> mkSynDotBrackGet m mDot arr (SynExpr.Tuple([x1;x2;x3;x4],[],unionRanges x1.Range x4.Range))
-    | _ -> mkSlice m mDot arr [ sliceArg1; sliceArg2; sliceArg3; sliceArg4 ] 
-    
+let mkSynDotBrackSeqSliceGet  m mDot arr (argslist:list<SynIndexerArg>) = 
+    let notsliced=[ for arg in argslist do
+                       match arg with 
+                       | SynIndexerArg.One x -> yield x
+                       | _ -> () ]
+    if notsliced.Length = argslist.Length then
+        SynExpr.DotIndexedGet(arr,[SynIndexerArg.One (SynExpr.Tuple(notsliced,[],unionRanges (Seq.head notsliced).Range (Seq.last notsliced).Range))],mDot,m)
+    else
+        SynExpr.DotIndexedGet(arr,argslist,mDot,m)
 
 let mkSynDotParenGet lhsm dotm a b   = 
     match b with
diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy
index 35324df..98401c7 100644
--- a/src/fsharp/pars.fsy
+++ b/src/fsharp/pars.fsy
@@ -440,7 +440,6 @@ let rangeOfLongIdent(lid:LongIdent) =
 %left COMMA
 %nonassoc slice_expr  /* matrix.[e COMMA e] has higher precedence than "e COMMA e" */
 %nonassoc DOT_DOT /* for matrix.[1..2,3..4] the ".." has higher precedence than expression "2 COMMA 3" */
-%nonassoc slice_comma  /* for matrix.[1..2,3..4] the "," has higher precedence than ".." */
 %nonassoc paren_pat_colon
 %nonassoc paren_pat_attribs
 %left OR BAR_BAR JOIN_IN
@@ -2907,7 +2906,7 @@ typedSeqExpr:
   | seqExpr { $1 }
 
 seqExpr:
-  | declExpr seps seqExpr                 
+  | declExpr seps seqExpr
       { SynExpr.Sequential(SequencePointsAtSeq,true,$1,$3,unionRanges $1.Range $3.Range) } 
   | declExpr seps                         
       { $1 }  
@@ -3573,21 +3572,19 @@ atomicExprQualification:
             mlCompatWarning (FSComp.SR.parsParenFormIsForML()) (lhs parseState); 
             mkSynDotParenGet lhsm dotm e $2) }
 
-  |   LBRACK  typedSeqExpr RBRACK  
+  |   LBRACK  typedSeqExpr RBRACK
       { (fun e lhsm dotm -> mkSynDotBrackGet lhsm dotm e $2) }
-
+ 
   |   LBRACK  typedSeqExpr recover
       { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracket()); 
         (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackGet lhsm dotm e $2)) }
 
-  |   LBRACK optRange RBRACK   
-      { (fun e lhsm dotm -> mkSynDotBrackSliceGet lhsm dotm e $2) }
-  |   LBRACK optRange COMMA optRange RBRACK  %prec slice_comma
-      { (fun e lhsm dotm -> mkSynDotBrackSlice2Get lhsm dotm e $2 $4) }
-  |   LBRACK optRange COMMA optRange COMMA optRange RBRACK  %prec slice_comma
-      { (fun e lhsm dotm -> mkSynDotBrackSlice3Get lhsm dotm e $2 $4 $6) }
-  |   LBRACK optRange COMMA optRange COMMA optRange COMMA optRange RBRACK  %prec slice_comma
-      { (fun e lhsm dotm -> mkSynDotBrackSlice4Get lhsm dotm e $2 $4 $6 $8) }
+  |   LBRACK  optRangeSeqExpr RBRACK
+      { (fun e lhsm dotm -> mkSynDotBrackSeqSliceGet lhsm dotm e $2) }
+ 
+  |   LBRACK  optRangeSeqExpr recover
+      { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedBracket()); 
+        (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackSeqSliceGet lhsm dotm e $2)) }
 
   |   LBRACK  error RBRACK  
       { let mArg = rhs2 parseState 1 3
@@ -3598,6 +3595,9 @@ atomicExprQualification:
         let mArg = (rhs parseState 1).EndRange 
         (fun e lhsm dotm -> exprFromParseError (mkSynDotBrackGet lhsm dotm e (arbExpr("indexerExpr2",mArg)))) }
 
+optRangeSeqExpr: 
+  | optRange COMMA optRangeSeqExpr { $1::$3 } 
+  | optRange                       { [$1] }
 
 optRange:
   | declExpr DOT_DOT declExpr 
@@ -3610,7 +3610,6 @@ optRange:
       { SynIndexerArg.Two(mkSynOptionalExpr (rhs parseState 1) None, mkSynOptionalExpr (rhs parseState 1) None) }
   | declExpr %prec slice_expr
       { SynIndexerArg.One($1) }
-  
 
 /* the start et of atomicExprAfterType must not overlap with the valid postfix tokens of the type syntax, e.g. new List<T>(...) */
 atomicExprAfterType:
diff --git a/tests/fsharp/core/array/test.fsx b/tests/fsharp/core/array/test.fsx
index afd889f..794ce8e 100644
--- a/tests/fsharp/core/array/test.fsx
+++ b/tests/fsharp/core/array/test.fsx
@@ -1330,6 +1330,39 @@ module bug872632 =
 
     do check "bug872632" Foo.x.Length 8
 
+module manyIndexes =
+    open System
+    
+    // Bug in F# 3.1: Indexer Properties was incorrectly limited to 4 arguments. There were no limits in previous versions of F#, and shouldn't be in future versions
+    // Repro code for bug in F# 3.1.  This compiles perfectly in F# 3.0
+    
+    // ----------------------------------------------------------------------------
+    type Test () =
+        /// Variable number of arguments with indexer property
+        member x.Item with get ([<ParamArray>] objs: obj[]) = objs
+        
+        /// PASS: Variable number of arguments with member function
+        member x.Foo ([<ParamArray>] objs: obj[]) = objs
+
+    // ----------------------------------------------------------------------------
+    let CompileIndexerTest = 
+        let test = Test ()
+    
+        // No problems with method having vaiable number of parameters
+        let u1 = test.Foo(null, null, null, null)
+        let u2 = test.Foo(null, null, null, null, null)
+        let u3 = test.Foo(null, null, null, null, null, null, null, null, null)
+    
+        // Bug was that the indexer Property was limited to 4 parameters (Issue introduced by matrix slicing code)
+        let u4 = test.[null]
+        let u5 = test.[null, null]
+        let u6 = test.[null, null, null]
+        let u7 = test.[null, null, null, null]
+        let u8 = test.[null, null, null, null, null]                                                    // Ensure that F# 3.1 is not unhappy with more than 4 arguments
+        let u9 = test.[null, null, null, null, null, null, null, null, null, null, null, null, null]    // Ensure that F# 3.1 is not unhappy with many more than 4 arguments, 13 arguments would be really unlucky
+        0
+
+
 #if Portable
 #else    // this overload of CreateInstance doesn't exist in portable
 module bug6447 =

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-cli-apps/packages/fsharp.git



More information about the Pkg-cli-apps-commits mailing list