Skip to content

Commit e84544a

Browse files
authored
AttributeTargets better error message (#18641)
1 parent 3183453 commit e84544a

38 files changed

+349
-229
lines changed

docs/release-notes/.FSharp.Compiler.Service/10.0.100.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
* Fix parsing errors using anonymous records and units of measures ([PR #18543](https://github.com/dotnet/fsharp/pull/18543))
88
* Fix parsing errors using anonymous records and code quotations ([PR #18603](https://github.com/dotnet/fsharp/pull/18603))
9+
* Better error message for attribute targets. ([PR #18641](https://github.com/dotnet/fsharp/pull/18641))
910
* Fixed: Allow `return`, `return!`, `yield`, `yield!` type annotations without parentheses ([PR #18533](https://github.com/dotnet/fsharp/pull/18533))
1011
* Allow `let!` and `use!` type annotations without requiring parentheses ([PR #18508](https://github.com/dotnet/fsharp/pull/18508))
1112
* Fix find all references for F# exceptions ([PR #18565](https://github.com/dotnet/fsharp/pull/18565))

src/Compiler/Checking/Expressions/CheckExpressions.fs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ exception StandardOperatorRedefinitionWarning of string * range
143143

144144
exception InvalidInternalsVisibleToAssemblyName of badName: string * fileName: string option
145145

146+
exception InvalidAttributeTargetForLanguageElement of elementTargets: string array * allowedTargets: string array * range: range
147+
146148
//----------------------------------------------------------------------------------------------
147149
// Helpers for determining if/what specifiers a string has.
148150
// Used to decide if interpolated string can be lowered to a concat call.
@@ -11356,7 +11358,29 @@ and CheckAttributeUsage (g: TcGlobals) (mAttr: range) (tcref: TyconRef) (attrTgt
1135611358
if (directedTargets = AttributeTargets.Assembly || directedTargets = AttributeTargets.Module) then
1135711359
errorR(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElementUseDo(), mAttr))
1135811360
else
11359-
warning(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElement(), mAttr))
11361+
let attributeTargetsToString (targets: int) =
11362+
[|
11363+
if targets &&& int AttributeTargets.Assembly <> 0 then "assembly"
11364+
if targets &&& int AttributeTargets.Module <> 0 then "module"
11365+
if targets &&& int AttributeTargets.Class <> 0 then "class"
11366+
if targets &&& int AttributeTargets.Struct <> 0 then "struct"
11367+
if targets &&& int AttributeTargets.Enum <> 0 then "enum"
11368+
if targets &&& int AttributeTargets.Constructor <> 0 then "constructor"
11369+
if targets &&& int AttributeTargets.Method <> 0 then "method"
11370+
if targets &&& int AttributeTargets.Property <> 0 then "property"
11371+
if targets &&& int AttributeTargets.Field <> 0 then "field"
11372+
if targets &&& int AttributeTargets.Event <> 0 then "event"
11373+
if targets &&& int AttributeTargets.Interface <> 0 then "interface"
11374+
if targets &&& int AttributeTargets.Parameter <> 0 then "parameter"
11375+
if targets &&& int AttributeTargets.Delegate <> 0 then "delegate"
11376+
if targets &&& int AttributeTargets.ReturnValue <> 0 then "return value"
11377+
if targets &&& int AttributeTargets.GenericParameter <> 0 then "type parameter"
11378+
|]
11379+
11380+
let elementTargets = attributeTargetsToString (int attrTgt)
11381+
let allowedTargets = attributeTargetsToString validOn
11382+
11383+
warning(InvalidAttributeTargetForLanguageElement(elementTargets, allowedTargets, mAttr))
1136011384

1136111385
constrainedTargets
1136211386

src/Compiler/Checking/Expressions/CheckExpressions.fsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ exception StandardOperatorRedefinitionWarning of string * range
121121

122122
exception InvalidInternalsVisibleToAssemblyName of badName: string * fileName: string option
123123

124+
exception InvalidAttributeTargetForLanguageElement of
125+
elementTargets: string array *
126+
allowedTargets: string array *
127+
range: range
128+
124129
val TcFieldInit: range -> ILFieldInit -> Const
125130

126131
/// Indicates whether a syntactic type is allowed to include new type variables

src/Compiler/Driver/CompilerDiagnostics.fs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ type Exception with
155155
| LibraryUseOnly m
156156
| FieldsFromDifferentTypes(_, _, _, m)
157157
| IndeterminateType m
158+
| InvalidAttributeTargetForLanguageElement(_, _, m)
158159
| TyconBadArgs(_, _, _, m) -> Some m
159160

160161
| FieldNotContained(_, _, _, _, _, arf, _, _) -> Some arf.Range
@@ -353,6 +354,7 @@ type Exception with
353354
| ConstraintSolverNullnessWarningWithTypes _ -> 3261
354355
| ConstraintSolverNullnessWarningWithType _ -> 3261
355356
| ConstraintSolverNullnessWarning _ -> 3261
357+
| InvalidAttributeTargetForLanguageElement _ -> 842
356358
| _ -> 193
357359

358360
type PhasedDiagnostic with
@@ -611,6 +613,9 @@ module OldStyleMessages =
611613
let DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferE () =
612614
Message("DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer", "%s%s%s%s")
613615

616+
let InvalidAttributeTargetForLanguageElement1E () = Message("InvalidAttributeTargetForLanguageElement1", "%s%s")
617+
let InvalidAttributeTargetForLanguageElement2E () = Message("InvalidAttributeTargetForLanguageElement2", "")
618+
614619
#if DEBUG
615620
let mutable showParserStackOnParseError = false
616621
#endif
@@ -1932,6 +1937,14 @@ type Exception with
19321937
s2
19331938
)
19341939

1940+
| InvalidAttributeTargetForLanguageElement(elementTargets, allowedTargets, _m) ->
1941+
if Array.isEmpty elementTargets then
1942+
os.AppendString(InvalidAttributeTargetForLanguageElement2E().Format)
1943+
else
1944+
let elementTargets = String.concat ", " elementTargets
1945+
let allowedTargets = allowedTargets |> String.concat ", "
1946+
os.AppendString(InvalidAttributeTargetForLanguageElement1E().Format elementTargets allowedTargets)
1947+
19351948
// Strip TargetInvocationException wrappers
19361949
| :? TargetInvocationException as e when isNotNull e.InnerException -> (!!e.InnerException).Output(os, suggestNames)
19371950

src/Compiler/FSComp.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,6 @@ tcUnnamedArgumentsDoNotFormPrefix,"The unnamed arguments do not form a prefix of
698698
839,tcUnexpectedConditionInImportedAssembly,"Unexpected condition in imported assembly: failed to decode AttributeUsage attribute"
699699
840,tcUnrecognizedAttributeTarget,"Unrecognized attribute target. Valid attribute targets are 'assembly', 'module', 'type', 'method', 'property', 'return', 'param', 'field', 'event', 'constructor'."
700700
841,tcAttributeIsNotValidForLanguageElementUseDo,"This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module."
701-
842,tcAttributeIsNotValidForLanguageElement,"This attribute is not valid for use on this language element"
702701
843,tcOptionalArgumentsCannotBeUsedInCustomAttribute,"Optional arguments cannot be used in custom attributes"
703702
844,tcPropertyCannotBeSet0,"This property cannot be set"
704703
845,tcPropertyOrFieldNotFoundInAttribute,"This property or field was not found on this custom attribute type"

src/Compiler/FSStrings.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,4 +1146,10 @@
11461146
<data name="Parser.TOKEN.WHILE.BANG" xml:space="preserve">
11471147
<value>keyword 'while!'</value>
11481148
</data>
1149+
<data name="InvalidAttributeTargetForLanguageElement1" xml:space="preserve">
1150+
<value>This attribute cannot be applied to {0}. Valid targets are: {1}</value>
1151+
</data>
1152+
<data name="InvalidAttributeTargetForLanguageElement2" xml:space="preserve">
1153+
<value>This attribute is not valid for use on this language element</value>
1154+
</data>
11491155
</root>

src/Compiler/xlf/FSComp.txt.cs.xlf

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compiler/xlf/FSComp.txt.de.xlf

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compiler/xlf/FSComp.txt.es.xlf

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compiler/xlf/FSComp.txt.fr.xlf

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)