Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ let isGlobal (fcsReference: FSharpSymbolReference) =
not fcsReference.IsQualified &&

let referenceOwner = fcsReference.GetElement()
isNotNull referenceOwner && getTokenType referenceOwner.FSharpIdentifier == FSharpTokenType.GLOBAL
isNotNull referenceOwner && getTokenType referenceOwner.NameIdentifier == FSharpTokenType.GLOBAL

let isModuleOrNamespace (fcsReference: FSharpSymbolReference) =
let entity = fcsReference.GetFcsSymbol().As<FSharpEntity>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ type FcsErrorsStageProcessBase(fsFile, daemonProcess) =

let createHighlightingFromMappedExpression mapping highlightingCtor range (error: FSharpDiagnostic): IHighlighting =
let expr = nodeSelectionProvider.GetExpressionInRange(fsFile, range, false, null) |> mapping
if isNotNull expr then highlightingCtor(expr, error.Message) :> _ else null
if isNotNull expr then highlightingCtor (expr, error.Message) :> _ else null

let createCachedDiagnostic (error: FSharpDiagnostic) range =
let pos = error.Range.Start
Expand Down Expand Up @@ -227,8 +227,8 @@ type FcsErrorsStageProcessBase(fsFile, daemonProcess) =
createTypeMismatchHighlighting MatchClauseWrongTypeError range error

| Some(:? TypeMismatchDiagnosticExtendedData as data) ->
let expr = nodeSelectionProvider.GetExpressionInRange(fsFile, range, false, null) |> getResultExpr
if isNull expr then
let node = nodeSelectionProvider.GetExpressionInRange(fsFile, range, false, null) |> getResultNode
if isNull node then
null
elif isUnit data.ExpectedType then
createHighlightingFromNodeWithMessage UnitTypeExpectedError range error
Expand Down Expand Up @@ -359,7 +359,7 @@ type FcsErrorsStageProcessBase(fsFile, daemonProcess) =
| _ -> createGenericHighlighting error range

| UnitTypeExpected ->
createHighlightingFromMappedExpression getResultExpr UnitTypeExpectedWarning range error
createHighlightingFromMappedExpression getResultNode UnitTypeExpectedWarning range error

| UseBindingsIllegalInModules ->
createHighlightingFromNode UseBindingsIllegalInModulesWarning range
Expand Down Expand Up @@ -550,14 +550,14 @@ type FcsErrorsStageProcessBase(fsFile, daemonProcess) =
| MissingErrorNumber ->
match error.ExtendedData with
| Some (:? ExpressionIsAFunctionExtendedData) ->
createHighlightingFromMappedExpression getResultExpr FunctionValueUnexpectedWarning range error
createHighlightingFromMappedExpression getResultNode FunctionValueUnexpectedWarning range error

| Some (:? FieldNotContainedDiagnosticExtendedData) ->
createHighlightingFromParentNodeWithMessage FieldNotContainedTypesDifferError range error

| Some (:? TypeMismatchDiagnosticExtendedData as data) ->
if isUnit data.ExpectedType then
createHighlightingFromMappedExpression getResultExpr UnitTypeExpectedError range error else
createHighlightingFromMappedExpression getResultNode UnitTypeExpectedError range error else

createTypeMismatchHighlighting TypeConstraintMismatchError range error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util
open JetBrains.ReSharper.Plugins.FSharp.Psi.Impl
open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree
open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree
open JetBrains.ReSharper.Psi.ExtensionsAPI
open JetBrains.ReSharper.Resources.Shell

type AddIgnoreFix(expr: IFSharpExpression) =
type AddIgnoreFix(node: IFSharpTypeOwnerNode) =
inherit FSharpModernQuickFixBase()

let expr = node.As<IFSharpExpression>()

let shouldAddNewLine (expr: IFSharpExpression) =
if expr.IsSingleLine then false else
if lastBlockHasSameIndent expr then false else
Expand Down Expand Up @@ -47,13 +48,13 @@ type AddIgnoreFix(expr: IFSharpExpression) =
addParensIfNeeded replaced.LeftArgument |> ignore

new (warning: UnitTypeExpectedWarning) =
AddIgnoreFix(warning.Expr)
AddIgnoreFix(warning.Node)

new (warning: FunctionValueUnexpectedWarning) =
AddIgnoreFix(warning.Expr)
AddIgnoreFix(warning.Node)

new (error: UnitTypeExpectedError) =
AddIgnoreFix(error.Expr)
AddIgnoreFix(error.Node)

override x.Text = "Ignore value"
override x.IsAvailable _ = isValid expr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type AddParensToTypedLikeExprFix(typedLikeExpr: ITypedLikeExpr) =
AddParensToTypedLikeExprFix(error.Expr)

new (error: TypeConstraintMismatchError) =
let typedLikeExpr = TypedLikeExprNavigator.GetByExpression(error.Expr)
let typedLikeExpr = TypedLikeExprNavigator.GetByExpression(error.Node.As())
AddParensToTypedLikeExprFix typedLikeExpr

override x.Text =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ open JetBrains.ReSharper.Resources.Shell
open JetBrains.Util

[<AbstractClass>]
type ChangeTypeFixBase(expr: IFSharpExpression, fcsDiagnosticInfo: FcsCachedDiagnosticInfo) =
type ChangeTypeFixBase(node: IFSharpTypeOwnerNode, fcsDiagnosticInfo: FcsCachedDiagnosticInfo) =
inherit FSharpQuickFixBase()

let canUpdateType (decl: ITreeNode) =
decl :? IFSharpTypeUsageOwnerNode ||
decl :? IFSharpParameterDeclaration

member this.TargetFcsType =
use pinCheckResultsCookie = expr.FSharpFile.PinTypeCheckResults(true, "ChangeTypeFixBase")
use pinCheckResultsCookie = node.FSharpFile.PinTypeCheckResults(true, "ChangeTypeFixBase")
this.GetTargetFcsType(fcsDiagnosticInfo.TypeMismatchData)

abstract DeclaredElement: IDeclaredElement
Expand Down Expand Up @@ -86,16 +86,18 @@ type ChangeTypeFixBase(expr: IFSharpExpression, fcsDiagnosticInfo: FcsCachedDiag


// todo: test signatures, virtual/abstract members
type ChangeParameterTypeFromArgumentFix(expr, fcsDiagnosticInfo: FcsCachedDiagnosticInfo) =
inherit ChangeTypeFixBase(expr, fcsDiagnosticInfo)
type ChangeParameterTypeFromArgumentFix(node: IFSharpTypeOwnerNode, fcsDiagnosticInfo: FcsCachedDiagnosticInfo) =
inherit ChangeTypeFixBase(node, fcsDiagnosticInfo)

let fsParamIndex = FSharpArgumentsOwnerUtil.TryGetFSharpParameterIndex(expr)
let expr = node.As<IFSharpExpression>()

let fsParamIndex = FSharpArgumentsOwnerUtil.TryGetFSharpParameterIndex(node)

new (error: TypeEquationError) =
ChangeParameterTypeFromArgumentFix(error.Expr, error.DiagnosticInfo)
ChangeParameterTypeFromArgumentFix(error.Node, error.DiagnosticInfo)

new (error: TypeConstraintMismatchError) =
ChangeParameterTypeFromArgumentFix(error.Expr, error.DiagnosticInfo)
ChangeParameterTypeFromArgumentFix(error.Node, error.DiagnosticInfo)

override this.Text =
$"Change type of parameter to '{this.TargetFcsType.Format()}'"
Expand All @@ -119,39 +121,39 @@ type ChangeParameterTypeFromArgumentFix(expr, fcsDiagnosticInfo: FcsCachedDiagno
decl.SetParameterFcsType(fsParamIndex.Value, fcsType)


type ChangeTypeFromElementReferenceFix(expr, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(expr, fcsDiagnosticInfo)
type ChangeTypeFromElementReferenceFix(node, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(node, fcsDiagnosticInfo)

new (error: TypeEquationError) =
ChangeTypeFromElementReferenceFix(error.Expr, error.DiagnosticInfo)
ChangeTypeFromElementReferenceFix(error.Node, error.DiagnosticInfo)

new (error: TypeConstraintMismatchError) =
ChangeTypeFromElementReferenceFix(error.Expr, error.DiagnosticInfo)
ChangeTypeFromElementReferenceFix(error.Node, error.DiagnosticInfo)

override this.GetTargetFcsType(data) =
data.ExpectedType

override this.DeclaredElement =
let refExpr = expr.As<IReferenceExpr>()
if isNull refExpr then null else
let referenceOwner = node.As<IFSharpReferenceOwner>()
if isNull referenceOwner then null else

refExpr.Reference.Resolve().DeclaredElement
referenceOwner.Reference.Resolve().DeclaredElement


type ChangeReturnTypeFromInvocationFix(expr: IFSharpExpression, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(expr, fcsDiagnosticInfo)
type ChangeReturnTypeFromInvocationFix(node: IFSharpTypeOwnerNode, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(node, fcsDiagnosticInfo)

new (error: TypeEquationError) =
ChangeReturnTypeFromInvocationFix(error.Expr, error.DiagnosticInfo)
ChangeReturnTypeFromInvocationFix(error.Node, error.DiagnosticInfo)

new (error: TypeConstraintMismatchError) =
ChangeReturnTypeFromInvocationFix(error.Expr, error.DiagnosticInfo)
ChangeReturnTypeFromInvocationFix(error.Node, error.DiagnosticInfo)

override this.GetTargetFcsType(data) =
data.ExpectedType

override this.DeclaredElement =
let appExpr = expr.As<IPrefixAppExpr>()
let appExpr = node.As<IPrefixAppExpr>()
if isNull appExpr then null else

let reference = appExpr.InvokedFunctionReference
Expand Down Expand Up @@ -185,33 +187,47 @@ type ChangeReturnTypeFromInvocationFix(expr: IFSharpExpression, fcsDiagnosticInf
|> FSharpTypeUsageUtil.updateTypeUsage fcsType


type ChangeTypeFromRecordFieldBindingFix(expr, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(expr, fcsDiagnosticInfo)
type ChangeTypeFromRecordFieldBindingFix(node, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(node, fcsDiagnosticInfo)

let tryGetFieldReferenceOwner (node: IFSharpTypeOwnerNode) : IFSharpReferenceOwner =
match node with
| :? IFSharpExpression as expr ->
let fieldBinding = RecordFieldBindingNavigator.GetByExpression(expr.IgnoreParentParens())
if isNotNull fieldBinding then fieldBinding.ReferenceName else null

| :? IFSharpPattern as pat ->
let fieldPat = FieldPatNavigator.GetByPattern(pat.IgnoreParentParens())
if isNotNull fieldPat then fieldPat.ReferenceName else null

| _ -> null

new (error: TypeEquationError) =
ChangeTypeFromRecordFieldBindingFix(error.Expr, error.DiagnosticInfo)
ChangeTypeFromRecordFieldBindingFix(error.Node, error.DiagnosticInfo)

new (error: TypeConstraintMismatchError) =
ChangeTypeFromRecordFieldBindingFix(error.Expr, error.DiagnosticInfo)
ChangeTypeFromRecordFieldBindingFix(error.Node, error.DiagnosticInfo)

override this.GetTargetFcsType(data) =
data.ActualType

override this.DeclaredElement =
let binding = RecordFieldBindingNavigator.GetByExpression(expr.IgnoreParentParens())
if isNull binding then null else
let referenceOwner = tryGetFieldReferenceOwner node
if isNull referenceOwner then null else

referenceOwner.Reference.Resolve().DeclaredElement

binding.ReferenceName.Reference.Resolve().DeclaredElement

type ChangeTypeFromSetExprFix(node, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(node, fcsDiagnosticInfo)

type ChangeTypeFromSetExprFix(expr, fcsDiagnosticInfo) =
inherit ChangeTypeFixBase(expr, fcsDiagnosticInfo)
let expr = node.As<IFSharpExpression>()

new (error: TypeEquationError) =
ChangeTypeFromSetExprFix(error.Expr, error.DiagnosticInfo)
ChangeTypeFromSetExprFix(error.Node, error.DiagnosticInfo)

new (error: TypeConstraintMismatchError) =
ChangeTypeFromSetExprFix(error.Expr, error.DiagnosticInfo)
ChangeTypeFromSetExprFix(error.Node, error.DiagnosticInfo)

override this.GetTargetFcsType(data) =
data.ActualType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ open JetBrains.Util
type ConvertTupleToArrayOrListElementsFix(warning: TypeEquationError) =
inherit FSharpQuickFixBase()

let expr = warning.Expr
let expr = warning.Node.As<IFSharpExpression>()

override x.Text = "Use ';' separators"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ module IntroduceVarFix =
let [<Literal>] introduceVarText = "Introduce 'let' binding"
let [<Literal>] introduceVarOutsideLambdaText = "Introduce 'let' binding outside lambda"

type IntroduceVarFix(expr: IFSharpExpression, removeExpr, escapeLambdas, addMutable, text) =
type IntroduceVarFix(node: IFSharpTypeOwnerNode, removeExpr, escapeLambdas, addMutable, text) =
inherit FSharpQuickFixBase()

let mutable expr = expr
let mutable expr = node.As<IFSharpExpression>()

let suggestInnerExpression (expr: IFSharpExpression) =
let binaryAppExpr = expr.As<IBinaryAppExpr>()
Expand All @@ -23,13 +23,13 @@ type IntroduceVarFix(expr: IFSharpExpression, removeExpr, escapeLambdas, addMuta
null

new (warning: UnitTypeExpectedWarning) =
IntroduceVarFix(warning.Expr, true, false, false, IntroduceVarFix.introduceVarText)
IntroduceVarFix(warning.Node, true, false, false, IntroduceVarFix.introduceVarText)

new (warning: FunctionValueUnexpectedWarning) =
IntroduceVarFix(warning.Expr, true, false, false, IntroduceVarFix.introduceVarText)
IntroduceVarFix(warning.Node, true, false, false, IntroduceVarFix.introduceVarText)

new (error: UnitTypeExpectedError) =
IntroduceVarFix(error.Expr, true, false, false, IntroduceVarFix.introduceVarText)
IntroduceVarFix(error.Node, true, false, false, IntroduceVarFix.introduceVarText)

new (error: CantTakeAddressOfExpressionError) =
IntroduceVarFix(error.Expr.Expression, false, false, true, IntroduceVarFix.introduceVarText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi
open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings
open JetBrains.ReSharper.Plugins.FSharp.Psi.Services.Util
open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree
open JetBrains.ReSharper.Psi.ExtensionsAPI
open JetBrains.ReSharper.Psi.ExtensionsAPI.Tree
open JetBrains.ReSharper.Psi.Util
open JetBrains.ReSharper.Resources.Shell

type RemoveSubsequentFix(expr: IFSharpExpression) =
type RemoveSubsequentFix(node: IFSharpTypeOwnerNode) =
inherit FSharpQuickFixBase()

let expr = node.As<IFSharpExpression>()

new (warning: UnitTypeExpectedWarning) =
RemoveSubsequentFix(warning.Expr)
RemoveSubsequentFix(warning.Node)

new (warning: FunctionValueUnexpectedWarning) =
RemoveSubsequentFix(warning.Expr)
RemoveSubsequentFix(warning.Node)

override x.Text = "Remove subsequent expressions"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ open JetBrains.ReSharper.Psi.ExtensionsAPI
open JetBrains.ReSharper.Psi.Tree
open JetBrains.ReSharper.Resources.Shell

type ReplaceReturnTypeFix(expr: IFSharpExpression, diagnosticInfo: FcsCachedDiagnosticInfo) =
type ReplaceReturnTypeFix(node: IFSharpTypeOwnerNode, diagnosticInfo: FcsCachedDiagnosticInfo) =
inherit FSharpQuickFixBase()

let expr = node.As<IFSharpExpression>()

let unwrapDecl (decl: IDeclaration) =
match decl with
| :? IFSharpTypeOwnerDeclaration as typeOwnerDecl -> typeOwnerDecl
Expand All @@ -39,11 +41,11 @@ type ReplaceReturnTypeFix(expr: IFSharpExpression, diagnosticInfo: FcsCachedDiag

new (error: TypeConstraintMismatchError) =
// error FS0193: Type constraint mismatch. The type 'A.B' is not compatible with type 'Thing'
ReplaceReturnTypeFix(error.Expr, error.DiagnosticInfo)
ReplaceReturnTypeFix(error.Node, error.DiagnosticInfo)

new (error: TypeEquationError) =
// error FS0001: This expression was expected to have type 'int' but here has type 'string'
ReplaceReturnTypeFix(error.Expr, error.DiagnosticInfo)
ReplaceReturnTypeFix(error.Node, error.DiagnosticInfo)

new (error: MatchClauseWrongTypeError) =
// All branches of a pattern match expression must return values implicitly convertible to the type of the first branch, which here is 'int'.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ open JetBrains.ReSharper.Plugins.FSharp.Psi
open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Daemon.Highlightings
open JetBrains.ReSharper.Plugins.FSharp.Psi.Features.Util.FSharpExpressionUtil
open JetBrains.ReSharper.Plugins.FSharp.Psi.Tree
open JetBrains.ReSharper.Psi.ExtensionsAPI
open JetBrains.ReSharper.Psi
open JetBrains.ReSharper.Resources.Shell

type ReplaceWithAssignmentExpressionFix(expr: IBinaryAppExpr) =
inherit FSharpQuickFixBase()

new (error: UnitTypeExpectedError) =
ReplaceWithAssignmentExpressionFix(error.Expr.As<IBinaryAppExpr>())
ReplaceWithAssignmentExpressionFix(error.Node.As<IBinaryAppExpr>())

new (warning: UnitTypeExpectedWarning) =
ReplaceWithAssignmentExpressionFix(warning.Expr.As<IBinaryAppExpr>())
ReplaceWithAssignmentExpressionFix(warning.Node.As<IBinaryAppExpr>())

override x.IsAvailable _ =
if not (isValid expr && isPredefinedFunctionRef "=" expr.Operator) then false else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,25 @@ let getRefExprNameRange (refExpr: IReferenceExpr) =
| null -> refExpr.GetHighlightingRange()
| identifier -> identifier.GetHighlightingRange()

let rec getResultExpr (expr: IFSharpExpression) =
match expr with
| :? ILetOrUseExpr as letExpr ->
let inExpr = letExpr.InExpression
if isNotNull inExpr then getResultExpr inExpr else expr
let rec getResultNode (node: IFSharpTypeOwnerNode) : IFSharpTypeOwnerNode =
match node with
| :? IFSharpExpression as expr ->
match expr with
| :? ILetOrUseExpr as letExpr ->
let inExpr = letExpr.InExpression
if isNotNull inExpr then getResultNode inExpr else expr

| :? ISequentialExpr as seqExpr ->
let lastExpr = seqExpr.Expressions.LastOrDefault()
if isNotNull lastExpr then getResultExpr lastExpr else expr
| :? ISequentialExpr as seqExpr ->
let lastExpr = seqExpr.Expressions.LastOrDefault()
if isNotNull lastExpr then getResultNode lastExpr else expr

| :? IParenOrBeginEndExpr as parenExpr ->
let innerExpr = parenExpr.InnerExpression
if isNotNull innerExpr && not parenExpr.IsSingleLine then getResultExpr innerExpr else expr
| :? IParenOrBeginEndExpr as parenExpr ->
let innerExpr = parenExpr.InnerExpression
if isNotNull innerExpr && not parenExpr.IsSingleLine then getResultNode innerExpr else expr

| _ -> expr

| _ -> expr
| _ -> node

let getAttributeSuffixRange (attribute: IAttribute) =
let referenceName = attribute.ReferenceName
Expand Down
Loading
Loading