diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs
index 09c765ed416..0ff7e74cc1c 100644
--- a/src/absil/ilwritepdb.fs
+++ b/src/absil/ilwritepdb.fs
@@ -369,36 +369,63 @@ let generatePortablePdb (embedAllSource: bool) (embedSourceList: string list) (s
builder.WriteCompressedInteger( 0 )
builder.WriteCompressedInteger( MetadataTokens.GetRowNumber(DocumentHandle.op_Implicit(getDocumentHandle (sps.[i].Document))) )
else
+ //=============================================================================================================================================
// Sequence-point-record
- let offsetDelta =
- if i > 0 then sps.[i].Offset - sps.[i - 1].Offset // delta from previous offset
- else sps.[i].Offset // delta IL offset
-
- if i < 1 || offsetDelta <> 0 then // ILOffset must not be 0
+ // Validate these with magic numbers according to the portable pdb spec Sequence point dexcription:
+ // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#methoddebuginformation-table-0x31
+ //
+ // So the spec is actually bit iffy!!!!! (More like guidelines really. )
+ // It uses code similar to this to validate the values
+ // if (result < 0 || result >= ushort.MaxValue) // be errorfull
+ // Spec Says 0x10000 and value max = 0xFFFF but it can't even be = to maxvalue, and so the range is 0 .. 0xfffe inclusive
+ //=============================================================================================================================================
+
+ let capValue v maxValue =
+ if v < 0 then 0
+ elif v > maxValue then maxValue
+ else v
+
+ let capOffset v = capValue v 0xfffe
+ let capLine v = capValue v 0x1ffffffe
+ let capColumn v = capValue v 0xfffe
+
+ let offset = capOffset sps.[i].Offset
+ let startLine = capLine sps.[i].Line
+ let endLine = capLine sps.[i].EndLine
+ let startColumn = capColumn sps.[i].Column
+ let endColumn = capColumn sps.[i].EndColumn
+
+ let offsetDelta = // delta from previous offset
+ if i > 0 then offset - capOffset sps.[i - 1].Offset
+ else offset
+
+ if i < 1 || offsetDelta > 0 then
builder.WriteCompressedInteger(offsetDelta)
- if sps.[i].Line = 0xfeefee && sps.[i].EndLine = 0xfeefee then // Hidden-sequence-point-record
+ // Hidden-sequence-point-record
+ if startLine = 0xfeefee || endLine = 0xfeefee || (startColumn = 0 && endColumn = 0)
+ then
builder.WriteCompressedInteger(0)
builder.WriteCompressedInteger(0)
else // Non-hidden-sequence-point-record
- let deltaLines = sps.[i].EndLine - sps.[i].Line // lines
+ let deltaLines = endLine - startLine // lines
builder.WriteCompressedInteger(deltaLines)
- let deltaColumns = sps.[i].EndColumn - sps.[i].Column // Columns
+ let deltaColumns = endColumn - startColumn // Columns
if deltaLines = 0 then
builder.WriteCompressedInteger(deltaColumns)
else
builder.WriteCompressedSignedInteger(deltaColumns)
if previousNonHiddenStartLine < 0 then // delta Start Line & Column:
- builder.WriteCompressedInteger(sps.[i].Line)
- builder.WriteCompressedInteger(sps.[i].Column)
+ builder.WriteCompressedInteger(startLine)
+ builder.WriteCompressedInteger(startColumn)
else
- builder.WriteCompressedSignedInteger(sps.[i].Line - previousNonHiddenStartLine)
- builder.WriteCompressedSignedInteger(sps.[i].Column - previousNonHiddenStartColumn)
+ builder.WriteCompressedSignedInteger(startLine - previousNonHiddenStartLine)
+ builder.WriteCompressedSignedInteger(startColumn - previousNonHiddenStartColumn)
- previousNonHiddenStartLine <- sps.[i].Line
- previousNonHiddenStartColumn <- sps.[i].Column
+ previousNonHiddenStartLine <- startLine
+ previousNonHiddenStartColumn <- startColumn
getDocumentHandle singleDocumentIndex, metadata.GetOrAddBlob(builder)
diff --git a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
index 2c5f4d1abc5..2aa2ffd100f 100644
--- a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
+++ b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
@@ -14,14 +14,6 @@
$(OtherFlags) --warnon:1182 --maxerrors:20 --extraoptimizationloops:1
true
true
- true
- true
-
-
-
-
- full
- false
diff --git a/src/fsharp/ast.fs b/src/fsharp/ast.fs
index a5068dae2d6..561900cdb80 100644
--- a/src/fsharp/ast.fs
+++ b/src/fsharp/ast.fs
@@ -805,7 +805,10 @@ and
/// Get the syntactic range of source code covered by this construct.
member e.Range =
match e with
- | SynExpr.Paren (range=m)
+ | SynExpr.Paren (_, leftParenRange, rightParenRange, r) ->
+ match rightParenRange with
+ | Some rightParenRange when leftParenRange.FileIndex <> rightParenRange.FileIndex -> leftParenRange
+ | _ -> r
| SynExpr.Quote (range=m)
| SynExpr.Const (range=m)
| SynExpr.Typed (range=m)
diff --git a/src/utils/prim-parsing.fs b/src/utils/prim-parsing.fs
index c9ff1bb595f..9ce01bff907 100644
--- a/src/utils/prim-parsing.fs
+++ b/src/utils/prim-parsing.fs
@@ -361,38 +361,49 @@ module internal Implementation =
#if DEBUG
if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken)
#endif
- for i = 0 to n - 1 do
+ // For every range to reduce merge it
+ for i = 0 to n - 1 do
if valueStack.IsEmpty then failwith "empty symbol stack"
- let topVal = valueStack.Peep()
+ let topVal = valueStack.Peep() // Grab topVal
valueStack.Pop()
stateStack.Pop()
- ruleValues.[(n-i)-1] <- topVal.value
- ruleStartPoss.[(n-i)-1] <- topVal.startPos
- ruleEndPoss.[(n-i)-1] <- topVal.endPos
- if i = 0 then lhsPos.[1] <- topVal.endPos
- if i = n - 1 then lhsPos.[0] <- topVal.startPos
-
- // Use the lookahead token to populate the locations if the rhs is empty
- if n = 0 then
+
+ let ruleIndex = (n-i)-1
+ ruleValues.[ruleIndex] <- topVal.value
+ ruleStartPoss.[ruleIndex] <- topVal.startPos
+ ruleEndPoss.[ruleIndex] <- topVal.endPos
+
+ if i = 0 then
+ // Initial range
+ lhsPos.[0] <- topVal.startPos
+ lhsPos.[1] <- topVal.endPos
+ elif topVal.startPos.FileIndex = lhsPos.[1].FileIndex && topVal.startPos.Line <= lhsPos.[1].Line then
+ // Reduce range if same file as the initial end point
+ lhsPos.[0] <- topVal.startPos
+
+ // Use the lookahead token to populate the locations if the rhs is empty
+ if n = 0 then
if haveLookahead then
- lhsPos.[0] <- lookaheadStartPos
- lhsPos.[1] <- lookaheadEndPos
+ lhsPos.[0] <- lookaheadStartPos
+ lhsPos.[1] <- lookaheadEndPos
else
lhsPos.[0] <- lexbuf.StartPos
lhsPos.[1] <- lexbuf.EndPos
- try
- // printf "reduce %d\n" prod
- let redResult = reduction parseState
- valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1]))
+ try
+ // printf "reduce %d\n" prod
+ let redResult = reduction parseState
+ let valueInfo = ValueInfo(redResult, lhsPos.[0], lhsPos.[1])
+ valueStack.Push(valueInfo)
let currState = stateStack.Peep()
let newGotoState = gotoTable.Read(int tables.productionToNonTerminalTable.[prod], currState)
stateStack.Push(newGotoState)
+
#if DEBUG
if Flags.debug then Console.WriteLine(" goto state {0}", newGotoState)
#endif
- with
- | Accept res ->
- finished <- true
+ with
+ | Accept res ->
+ finished <- true
valueStack.Push(ValueInfo(res, lhsPos.[0], lhsPos.[1]))
| RecoverableParseError ->
#if DEBUG