Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trivia information to SynConst.Measure #15614

Merged
merged 16 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ let ForNewConstructors tcSink (env: TcEnv) mObjTy methodName meths =
/// Typecheck rational constant terms in units-of-measure exponents
let rec TcSynRationalConst c =
match c with
| SynRationalConst.Integer i -> intToRational i
| SynRationalConst.Integer(value = i) -> intToRational i
| SynRationalConst.Negate c2 -> NegRational (TcSynRationalConst c2)
| SynRationalConst.Rational(p, q, _) -> DivRational (intToRational p) (intToRational q)

Expand All @@ -762,7 +762,7 @@ let TcConst (cenv: cenv) (overallTy: TType) m env synConst =
let g = cenv.g
let rec tcMeasure ms =
match ms with
| SynMeasure.One -> Measure.One
| SynMeasure.One _ -> Measure.One
| SynMeasure.Named(tc, m) ->
let ad = env.eAccessRights
let _, tcref = ForceRaise(ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.Use OpenQualified env.eNameResEnv ad tc TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No)
Expand All @@ -774,9 +774,11 @@ let TcConst (cenv: cenv) (overallTy: TType) m env synConst =
| SynMeasure.Product(ms1, ms2, _) -> Measure.Prod(tcMeasure ms1, tcMeasure ms2)
| SynMeasure.Divide(ms1, (SynMeasure.Seq (_ :: _ :: _, _) as ms2), m) ->
warning(Error(FSComp.SR.tcImplicitMeasureFollowingSlash(), m))
Measure.Prod(tcMeasure ms1, Measure.Inv (tcMeasure ms2))
let factor1 = ms1 |> Option.defaultValue (SynMeasure.One Range.Zero)
Measure.Prod(tcMeasure factor1, Measure.Inv (tcMeasure ms2))
| SynMeasure.Divide(ms1, ms2, _) ->
Measure.Prod(tcMeasure ms1, Measure.Inv (tcMeasure ms2))
let factor1 = ms1 |> Option.defaultValue (SynMeasure.One Range.Zero)
Measure.Prod(tcMeasure factor1, Measure.Inv (tcMeasure ms2))
| SynMeasure.Seq(mss, _) -> ProdMeasures (List.map tcMeasure mss)
| SynMeasure.Anon _ -> error(Error(FSComp.SR.tcUnexpectedMeasureAnon(), m))
| SynMeasure.Var(_, m) -> error(Error(FSComp.SR.tcNonZeroConstantCannotHaveGenericUnit(), m))
Expand All @@ -787,10 +789,10 @@ let TcConst (cenv: cenv) (overallTy: TType) m env synConst =
let unifyMeasureArg iszero tcr =
let measureTy =
match synConst with
| SynConst.Measure(_, _, SynMeasure.Anon _) ->
| SynConst.Measure(synMeasure = SynMeasure.Anon _) ->
(mkAppTy tcr [TType_measure (Measure.Var (NewAnonTypar (TyparKind.Measure, m, TyparRigidity.Anon, (if iszero then TyparStaticReq.None else TyparStaticReq.HeadType), TyparDynamicReq.No)))])

| SynConst.Measure(_, _, ms) -> mkAppTy tcr [TType_measure (tcMeasure ms)]
| SynConst.Measure(synMeasure = ms) -> mkAppTy tcr [TType_measure (tcMeasure ms)]
| _ -> mkAppTy tcr [TType_measure Measure.One]
unif measureTy

Expand Down Expand Up @@ -843,43 +845,43 @@ let TcConst (cenv: cenv) (overallTy: TType) m env synConst =
| SynConst.UIntPtr i ->
unif g.unativeint_ty
Const.UIntPtr i
| SynConst.Measure(SynConst.Single f, _, _) ->
| SynConst.Measure(constant = SynConst.Single f) ->
unifyMeasureArg (f=0.0f) g.pfloat32_tcr
Const.Single f
| SynConst.Measure(SynConst.Double f, _, _) ->
| SynConst.Measure(constant = SynConst.Double f) ->
unifyMeasureArg (f=0.0) g.pfloat_tcr
Const.Double f
| SynConst.Measure(SynConst.Decimal f, _, _) ->
| SynConst.Measure(constant = SynConst.Decimal f) ->
unifyMeasureArg false g.pdecimal_tcr
Const.Decimal f
| SynConst.Measure(SynConst.SByte i, _, _) ->
| SynConst.Measure(constant = SynConst.SByte i)->
unifyMeasureArg (i=0y) g.pint8_tcr
Const.SByte i
| SynConst.Measure(SynConst.Int16 i, _, _) ->
| SynConst.Measure(constant = SynConst.Int16 i) ->
unifyMeasureArg (i=0s) g.pint16_tcr
Const.Int16 i
| SynConst.Measure(SynConst.Int32 i, _, _) ->
| SynConst.Measure(constant = SynConst.Int32 i) ->
unifyMeasureArg (i=0) g.pint_tcr
Const.Int32 i
| SynConst.Measure(SynConst.Int64 i, _, _) ->
| SynConst.Measure(constant = SynConst.Int64 i) ->
unifyMeasureArg (i=0L) g.pint64_tcr
Const.Int64 i
| SynConst.Measure(SynConst.IntPtr i, _, _) when expandedMeasurablesEnabled ->
| SynConst.Measure(constant = SynConst.IntPtr i) when expandedMeasurablesEnabled ->
unifyMeasureArg (i=0L) g.pnativeint_tcr
Const.IntPtr i
| SynConst.Measure(SynConst.Byte i, _, _) when expandedMeasurablesEnabled ->
| SynConst.Measure(constant = SynConst.Byte i) when expandedMeasurablesEnabled ->
unifyMeasureArg (i=0uy) g.puint8_tcr
Const.Byte i
| SynConst.Measure(SynConst.UInt16 i, _, _) when expandedMeasurablesEnabled ->
| SynConst.Measure(constant = SynConst.UInt16 i) when expandedMeasurablesEnabled ->
unifyMeasureArg (i=0us) g.puint16_tcr
Const.UInt16 i
| SynConst.Measure(SynConst.UInt32 i, _, _) when expandedMeasurablesEnabled ->
| SynConst.Measure(constant = SynConst.UInt32 i) when expandedMeasurablesEnabled ->
unifyMeasureArg (i=0u) g.puint_tcr
Const.UInt32 i
| SynConst.Measure(SynConst.UInt64 i, _, _) when expandedMeasurablesEnabled ->
| SynConst.Measure(constant = SynConst.UInt64 i) when expandedMeasurablesEnabled ->
unifyMeasureArg (i=0UL) g.puint64_tcr
Const.UInt64 i
| SynConst.Measure(SynConst.UIntPtr i, _, _) when expandedMeasurablesEnabled ->
| SynConst.Measure(constant = SynConst.UIntPtr i) when expandedMeasurablesEnabled ->
unifyMeasureArg (i=0UL) g.punativeint_tcr
Const.UIntPtr i
| SynConst.Char c ->
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/ServiceInterfaceStubGenerator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ type InterfaceData =
| InterfaceData.ObjExpr (StripParenTypes ty, _) ->
let rec (|RationalConst|) =
function
| SynRationalConst.Integer i -> string i
| SynRationalConst.Integer(value = i) -> string i
| SynRationalConst.Rational (numerator, denominator, _) -> sprintf "(%i/%i)" numerator denominator
| SynRationalConst.Negate (RationalConst s) -> sprintf "- %s" s

Expand Down
10 changes: 6 additions & 4 deletions src/Compiler/Service/ServiceParsedInputOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1832,21 +1832,23 @@ module ParsedInput =
List.iter walkType ts
walkMemberSig sign
walkExpr e
| SynExpr.Const (SynConst.Measure (_, _, m), _) -> walkMeasure m
| SynExpr.Const(constant = SynConst.Measure (synMeasure = m)) -> walkMeasure m
| _ -> ()

and walkMeasure measure =
match measure with
| SynMeasure.Product (m1, m2, _)
| SynMeasure.Divide (m1, m2, _) ->
| SynMeasure.Product (m1, m2, _) ->
walkMeasure m1
walkMeasure m2
| SynMeasure.Divide (m1, m2, _) ->
m1 |> Option.iter walkMeasure
walkMeasure m2
| SynMeasure.Named (longIdent, _) -> addLongIdent longIdent
| SynMeasure.Seq (ms, _) -> List.iter walkMeasure ms
| SynMeasure.Paren (m, _)
| SynMeasure.Power (m, _, _) -> walkMeasure m
| SynMeasure.Var (ty, _) -> walkTypar ty
| SynMeasure.One
| SynMeasure.One _
| SynMeasure.Anon _ -> ()

and walkSimplePat spat =
Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ type SynConst =

| UInt16s of uint16[]

| Measure of constant: SynConst * constantRange: range * SynMeasure
| Measure of constant: SynConst * constantRange: range * synMeasure: SynMeasure * trivia: SynMeasureConstantTrivia

| SourceIdentifier of constant: string * value: string * range: range

Expand All @@ -178,11 +178,11 @@ type SynMeasure =

| Seq of measures: SynMeasure list * range: range

| Divide of measure1: SynMeasure * measure2: SynMeasure * range: range
| Divide of measure1: SynMeasure option * measure2: SynMeasure * range: range

| Power of measure: SynMeasure * power: SynRationalConst * range: range

| One
| One of range: range

| Anon of range: range

Expand All @@ -193,7 +193,7 @@ type SynMeasure =
[<NoEquality; NoComparison; RequireQualifiedAccess>]
type SynRationalConst =

| Integer of value: int32
| Integer of value: int32 * range: range

| Rational of numerator: int32 * denominator: int32 * range: range

Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ type SynConst =
| UInt16s of uint16[]

/// Old comment: "we never iterate, so the const here is not another SynConst.Measure"
| Measure of constant: SynConst * constantRange: range * SynMeasure
| Measure of constant: SynConst * constantRange: range * synMeasure: SynMeasure * trivia: SynMeasureConstantTrivia

/// Source Line, File, and Path Identifiers
/// Containing both the original value as the evaluated value.
Expand All @@ -193,13 +193,13 @@ type SynMeasure =
| Seq of measures: SynMeasure list * range: range

/// A division of two units of measure, e.g. 'kg / m'
| Divide of measure1: SynMeasure * measure2: SynMeasure * range: range
| Divide of measure1: SynMeasure option * measure2: SynMeasure * range: range

/// A power of a unit of measure, e.g. 'kg ^ 2'
| Power of measure: SynMeasure * power: SynRationalConst * range: range
dawedawe marked this conversation as resolved.
Show resolved Hide resolved

/// The '1' unit of measure
| One
| One of range: range

/// An anonymous (inferred) unit of measure
| Anon of range: range
Expand All @@ -214,7 +214,7 @@ type SynMeasure =
[<NoEquality; NoComparison; RequireQualifiedAccess>]
type SynRationalConst =

| Integer of value: int32
| Integer of value: int32 * range: range

| Rational of numerator: int32 * denominator: int32 * range: range

Expand Down
7 changes: 7 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -388,3 +388,10 @@ type SynMemberSigMemberTrivia =
}

static member Zero: SynMemberSigMemberTrivia = { GetSetKeywords = None }

[<NoEquality; NoComparison>]
type SynMeasureConstantTrivia =
{
LessRange: range
GreaterRange: range
}
6 changes: 6 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -507,3 +507,9 @@ type SynMemberSigMemberTrivia =
}

static member Zero: SynMemberSigMemberTrivia

/// Represents additional information for SynConst.Measure
[<NoEquality; NoComparison>]
type SynMeasureConstantTrivia =
{ LessRange: range
GreaterRange: range }
28 changes: 19 additions & 9 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -3292,15 +3292,15 @@ rationalConstant:

| INT32
{ if snd $1 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState))
SynRationalConst.Integer(fst $1) }
SynRationalConst.Integer(fst $1, lhs parseState) }

| MINUS INT32
{ if snd $2 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState))
SynRationalConst.Negate(SynRationalConst.Integer(fst $2)) }
SynRationalConst.Negate(SynRationalConst.Integer(fst $2, lhs parseState)) }

atomicUnsignedRationalConstant:
| INT32 { if snd $1 then errorR(Error(FSComp.SR.lexOutsideThirtyTwoBitSigned(), lhs parseState))
SynRationalConst.Integer(fst $1) }
SynRationalConst.Integer(fst $1, lhs parseState) }

| LPAREN rationalConstant rparen
{ $2 }
Expand All @@ -3316,7 +3316,10 @@ constant:
{ $1, rhs parseState 1 }

| rawConstant HIGH_PRECEDENCE_TYAPP measureTypeArg
{ SynConst.Measure($1, rhs parseState 1, $3), lhs parseState }
{ let synMeasure, trivia = $3
let mConstant = rhs parseState 1
let m = unionRanges mConstant trivia.GreaterRange
SynConst.Measure($1, rhs parseState 1, synMeasure, trivia), m }

bindingPattern:
| headBindingPattern
Expand Down Expand Up @@ -6193,10 +6196,16 @@ dummyTypeArg:

measureTypeArg:
| LESS measureTypeExpr GREATER
{ $2 }
{ let mLess = rhs parseState 1
let mGreater = rhs parseState 3
let trivia = { LessRange = mLess; GreaterRange = mGreater }
$2, trivia }

| LESS UNDERSCORE GREATER
{ SynMeasure.Anon(lhs parseState) }
{ let mLess = rhs parseState 1
let mGreater = rhs parseState 3
let trivia = { LessRange = mLess; GreaterRange = mGreater }
SynMeasure.Anon(rhs parseState 2), trivia }

measureTypeAtom:
| path
Expand All @@ -6220,7 +6229,8 @@ measureTypePower:

| INT32
{ if fst $1 <> 1 then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedIntegerLiteralForUnitOfMeasure())
SynMeasure.One }
let m = rhs parseState 1
SynMeasure.One(m) }

measureTypeSeq:
| measureTypePower
Expand All @@ -6239,11 +6249,11 @@ measureTypeExpr:
| measureTypeExpr INFIX_STAR_DIV_MOD_OP measureTypeExpr
{ if $2 <> "*" && $2 <> "/" then reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedOperatorForUnitOfMeasure())
if $2 = "*" then SynMeasure.Product($1, $3, lhs parseState)
else SynMeasure.Divide($1, $3, lhs parseState) }
else SynMeasure.Divide(Some $1, $3, lhs parseState) }

| INFIX_STAR_DIV_MOD_OP measureTypeExpr
{ if $1 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedOperatorForUnitOfMeasure())
SynMeasure.Divide(SynMeasure.One, $2, lhs parseState) }
SynMeasure.Divide(None, $2, lhs parseState) }

typar:
| QUOTE ident
Expand Down
Loading
Loading