diff --git a/eng/Build.ps1 b/eng/Build.ps1 index 54e6ff5e2b7..9f6d5dd045f 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -182,6 +182,7 @@ function BuildSolution() { /p:QuietRestore=$quietRestore ` /p:QuietRestoreBinaryLog=$binaryLog ` /p:TestTargetFrameworks=$testTargetFrameworks ` + /v:$verbosity ` $suppressExtensionDeployment ` @properties } diff --git a/eng/build.sh b/eng/build.sh index c467296d3d3..4d3e87fcba6 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -242,6 +242,7 @@ function BuildSolution { # do real build MSBuild $toolset_build_proj \ $bl \ + /v:$verbosity \ /p:Configuration=$configuration \ /p:Projects="$projects" \ /p:RepoRoot="$repo_root" \ @@ -273,3 +274,4 @@ if [[ "$test_core_clr" == true ]]; then fi ExitWithExitCode 0 + diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh old mode 100644 new mode 100755 diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index a324cc9ed4a..4b5f756f06d 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1461,6 +1461,8 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 3243,parsInvalidAnonRecdExpr,"Invalid anonymous record expression" 3244,parsInvalidAnonRecdType,"Invalid anonymous record type" 3245,tcCopyAndUpdateNeedsRecordType,"The input to a copy-and-update expression that creates an anonymous record must be either an anonymous record or a record" +3250,expressionHasNoName,"Expression does not have a name." +3251,chkNoFirstClassNameOf,"Using the 'nameof' operator as a first-class function value is not permitted." 3300,chkInvalidFunctionParameterType,"The parameter '%s' has an invalid type '%s'. This is not permitted by the rules of Common IL." 3301,chkInvalidFunctionReturnType,"The function or method has an invalid return type '%s'. This is not permitted by the rules of Common IL." useSdkRefs,"Use reference assemblies for .NET framework references when available (Enabled by default)." diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 1fe3d7e841a..a656e8e8088 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -4142,6 +4142,9 @@ namespace Microsoft.FSharp.Core [] let inline typeof<'T> = BasicInlinedOperations.typeof<'T> + [] + let inline nameof (_: 'T) : string = raise (Exception "may not call directly, should always be optimized away") + [] let methodhandleof (_call: ('T -> 'TResult)) : System.RuntimeMethodHandle = raise (Exception "may not call directly, should always be optimized away") diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 264cf7ff872..c328782c8ec 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -2401,6 +2401,10 @@ namespace Microsoft.FSharp.Core [] val inline typeof<'T> : System.Type + /// Returns the name of the given symbol. + [] + val inline nameof : 'T -> string + /// An internal, library-only compiler intrinsic for compile-time /// generation of a RuntimeMethodHandle. [] diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 1809fdaf3b0..fd883868cc4 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -1259,7 +1259,7 @@ type FormatStringCheckContext = type ITypecheckResultsSink = abstract NotifyEnvWithScope: range * NameResolutionEnv * AccessorDomain -> unit abstract NotifyExprHasType: pos * TType * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit - abstract NotifyNameResolution: pos * Item * Item * TyparInst * ItemOccurence * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range * bool -> unit + abstract NotifyNameResolution: pos * item: Item * itemMethodGroup: Item * TyparInst * ItemOccurence * Tastops.DisplayEnv * NameResolutionEnv * AccessorDomain * range * replace: bool -> unit abstract NotifyFormatSpecifierLocation: range * int -> unit abstract NotifyOpenDeclaration: OpenDeclaration -> unit abstract CurrentSourceText: ISourceText option diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index b6a286c5d79..dd1ec5c2af5 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -678,6 +678,7 @@ and CheckValRef (cenv: cenv) (env: env) v m (context: PermitByRefExpr) = if isSpliceOperator cenv.g v then errorR(Error(FSComp.SR.chkNoFirstClassSplicing(), m)) if valRefEq cenv.g v cenv.g.addrof_vref then errorR(Error(FSComp.SR.chkNoFirstClassAddressOf(), m)) if valRefEq cenv.g v cenv.g.reraise_vref then errorR(Error(FSComp.SR.chkNoFirstClassRethrow(), m)) + if valRefEq cenv.g v cenv.g.nameof_vref then errorR(Error(FSComp.SR.chkNoFirstClassNameOf(), m)) // ByRefLike-typed values can only occur in permitting contexts if context.Disallow && isByrefLikeTy cenv.g m v.Type then diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 00fb9a08278..55436c91843 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -3206,6 +3206,11 @@ let isSizeOfValRef g vref = // There is an internal version of typeof defined in prim-types.fs that needs to be detected || (g.compilingFslib && vref.LogicalName = "sizeof") +let isNameOfValRef g vref = + valRefEq g vref g.nameof_vref + // There is an internal version of nameof defined in prim-types.fs that needs to be detected + || (g.compilingFslib && vref.LogicalName = "nameof") + let isTypeDefOfValRef g vref = valRefEq g vref g.typedefof_vref // There is an internal version of typedefof defined in prim-types.fs that needs to be detected @@ -3231,6 +3236,16 @@ let (|TypeDefOfExpr|_|) g expr = | Expr.App (Expr.Val (vref, _, _), _, [ty], [], _) when isTypeDefOfValRef g vref -> Some ty | _ -> None +let (|NameOfExpr|_|) g expr = + match expr with + | Expr.App(Expr.Val(vref,_,_),_,[ty],[],_) when isNameOfValRef g vref -> Some ty + | _ -> None + +let (|SeqExpr|_|) g expr = + match expr with + | Expr.App(Expr.Val(vref,_,_),_,_,_,_) when valRefEq g vref g.seq_vref -> Some() + | _ -> None + //-------------------------------------------------------------------------- // DEBUG layout //--------------------------------------------------------------------------- @@ -8553,7 +8568,8 @@ let IsSimpleSyntacticConstantExpr g inputExpr = | Expr.Op (TOp.UnionCase _, _, [], _) // Nullary union cases | UncheckedDefaultOfExpr g _ | SizeOfExpr g _ - | TypeOfExpr g _ -> true + | TypeOfExpr g _ + | NameOfExpr g _ -> true // All others are not simple constant expressions | _ -> false diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 8c71736a844..46088de6bd2 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -2231,6 +2231,8 @@ val (|EnumExpr|_|) : TcGlobals -> Expr -> Expr option val (|TypeOfExpr|_|) : TcGlobals -> Expr -> TType option val (|TypeDefOfExpr|_|) : TcGlobals -> Expr -> TType option +val (|NameOfExpr|_|) : TcGlobals -> Expr -> TType option +val (|SeqExpr|_|) : TcGlobals -> Expr -> unit option val EvalLiteralExprOrAttribArg: TcGlobals -> Expr -> Expr diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index 1aa14c5794d..7952804ccd4 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -664,6 +664,8 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_typeof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "typeof" , None , Some "TypeOf" , [vara], ([], v_system_Type_ty)) let v_methodhandleof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "methodhandleof" , None , Some "MethodHandleOf", [vara;varb], ([[varaTy --> varbTy]], v_system_RuntimeMethodHandle_ty)) let v_sizeof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "sizeof" , None , Some "SizeOf" , [vara], ([], v_int_ty)) + let v_nameof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "nameof" , None , Some "NameOf" , [vara], ([[varaTy]], v_string_ty)) + let v_unchecked_defaultof_info = makeIntrinsicValRef(fslib_MFOperatorsUnchecked_nleref, "defaultof" , None , Some "DefaultOf", [vara], ([], varaTy)) let v_typedefof_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "typedefof" , None , Some "TypeDefOf", [vara], ([], v_system_Type_ty)) let v_range_op_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_Range" , None , None , [vara], ([[varaTy];[varaTy]], mkSeqTy varaTy)) @@ -1331,6 +1333,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val methodhandleof_vref = ValRefForIntrinsic v_methodhandleof_info member val typeof_vref = ValRefForIntrinsic v_typeof_info member val sizeof_vref = ValRefForIntrinsic v_sizeof_info + member val nameof_vref = ValRefForIntrinsic v_nameof_info member val typedefof_vref = ValRefForIntrinsic v_typedefof_info member val enum_vref = ValRefForIntrinsic v_enum_operator_info member val enumOfValue_vref = ValRefForIntrinsic v_enumOfValue_info @@ -1358,15 +1361,15 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val unbox_fast_vref = ValRefForIntrinsic v_unbox_fast_info member val istype_vref = ValRefForIntrinsic v_istype_info member val istype_fast_vref = ValRefForIntrinsic v_istype_fast_info - member val query_source_vref = ValRefForIntrinsic v_query_source_info - member val query_value_vref = ValRefForIntrinsic v_query_value_info - member val query_run_value_vref = ValRefForIntrinsic v_query_run_value_info - member val query_run_enumerable_vref = ValRefForIntrinsic v_query_run_enumerable_info - member val query_for_vref = ValRefForIntrinsic v_query_for_value_info - member val query_yield_vref = ValRefForIntrinsic v_query_yield_value_info - member val query_yield_from_vref = ValRefForIntrinsic v_query_yield_from_value_info - member val query_select_vref = ValRefForIntrinsic v_query_select_value_info - member val query_where_vref = ValRefForIntrinsic v_query_where_value_info + member val query_source_vref = ValRefForIntrinsic v_query_source_info + member val query_value_vref = ValRefForIntrinsic v_query_value_info + member val query_run_value_vref = ValRefForIntrinsic v_query_run_value_info + member val query_run_enumerable_vref = ValRefForIntrinsic v_query_run_enumerable_info + member val query_for_vref = ValRefForIntrinsic v_query_for_value_info + member val query_yield_vref = ValRefForIntrinsic v_query_yield_value_info + member val query_yield_from_vref = ValRefForIntrinsic v_query_yield_from_value_info + member val query_select_vref = ValRefForIntrinsic v_query_select_value_info + member val query_where_vref = ValRefForIntrinsic v_query_where_value_info member val query_zero_vref = ValRefForIntrinsic v_query_zero_value_info member __.seq_collect_info = v_seq_collect_info diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 824cb2ac205..044e0f8ed88 100644 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -8711,37 +8711,87 @@ and delayRest rest mPrior delayed = let mPriorAndLongId = unionRanges mPrior (rangeOfLid longId) DelayedDotLookup (rest, mPriorAndLongId) :: delayed +/// Typecheck "nameof" expressions +and TcNameOfExpr cenv env tpenv (synArg: SynExpr) = + + let rec stripParens expr = + match expr with + | SynExpr.Paren(expr, _, _, _) -> stripParens expr + | _ -> expr + + let cleanSynArg = stripParens synArg + let m = cleanSynArg.Range + let rec check overallTyOpt expr (delayed: DelayedItem list) = + match expr with + | LongOrSingleIdent (false, (LongIdentWithDots(longId, _) as lidd), _, _) when longId.Length > 0 -> + let ad = env.eAccessRights + let id, rest = List.headAndTail longId + match ResolveLongIndentAsModuleOrNamespace cenv.tcSink ResultCollectionSettings.AllResults cenv.amap m true OpenQualified env.eNameResEnv ad id rest true with + | Result modref when delayed.IsEmpty && modref |> List.exists (p23 >> IsEntityAccessible cenv.amap m ad) -> + () // resolved to a module or namespace, done with checks + | _ -> + let (TypeNameResolutionInfo(_, staticArgsInfo)) = GetLongIdentTypeNameInfo delayed + match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInAttribute OpenQualified env.eNameResEnv ad longId staticArgsInfo PermitDirectReferenceToGeneratedType.No with + | Result tcref when IsEntityAccessible cenv.amap m ad tcref -> + () // resolved to a type name, done with checks + | _ -> + let overallTy = match overallTyOpt with None -> NewInferenceType() | Some t -> t + let _, _ = TcLongIdentThen cenv overallTy env tpenv lidd delayed + () // checked as an expression, done with checks + List.last longId + + | SynExpr.TypeApp (hd, _, types, _, _, _, m) -> + check overallTyOpt hd (DelayedTypeApp(types, m, m) :: delayed) + + | SynExpr.Paren(expr, _, _, _) when overallTyOpt.IsNone && delayed.IsEmpty -> + check overallTyOpt expr [] + + | SynExpr.Typed (synBodyExpr, synType, _m) when delayed.IsEmpty && overallTyOpt.IsNone -> + let tgtTy, _tpenv = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType env tpenv synType + check (Some tgtTy) synBodyExpr [] + + | _ -> + error (Error(FSComp.SR.expressionHasNoName(), m)) + let lastIdent = check None cleanSynArg [] + let constRange = mkRange m.FileName m.Start (mkPos m.StartLine (m.StartColumn + lastIdent.idText.Length + 2)) // `2` are for quotes + Expr.Const(Const.String(lastIdent.idText), constRange, cenv.g.string_ty) + //------------------------------------------------------------------------- // TcFunctionApplicationThen: Typecheck "expr x" + projections //------------------------------------------------------------------------- and TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty (synArg: SynExpr) atomicFlag delayed = - let denv = env.DisplayEnv let mArg = synArg.Range let mFunExpr = expr.Range + // If the type of 'synArg' unifies as a function type, then this is a function application, otherwise // it is an error or a computation expression match UnifyFunctionTypeUndoIfFailed cenv denv mFunExpr exprty with | ValueSome (domainTy, resultTy) -> - - // Notice the special case 'seq { ... }'. In this case 'seq' is actually a function in the F# library. - // Set a flag in the syntax tree to say we noticed a leading 'seq' - match synArg with - | SynExpr.CompExpr (false, isNotNakedRefCell, _comp, _m) -> - isNotNakedRefCell := - !isNotNakedRefCell - || - (match expr with - | ApplicableExpr(_, Expr.Op (TOp.Coerce, _, [Expr.App (Expr.Val (vf, _, _), _, _, _, _)], _), _) when valRefEq cenv.g vf cenv.g.seq_vref -> true - | _ -> false) - | _ -> () - - let arg, tpenv = TcExpr cenv domainTy env tpenv synArg - let exprAndArg, resultTy = buildApp cenv expr resultTy arg mExprAndArg - TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed - | _ -> + match expr with + | ApplicableExpr(_, NameOfExpr cenv.g _, _) -> + let replacementExpr = TcNameOfExpr cenv env tpenv synArg + TcDelayed cenv overallTy env tpenv mExprAndArg (ApplicableExpr(cenv, replacementExpr, true)) cenv.g.string_ty ExprAtomicFlag.Atomic delayed + | _ -> + // Notice the special case 'seq { ... }'. In this case 'seq' is actually a function in the F# library. + // Set a flag in the syntax tree to say we noticed a leading 'seq' + match synArg with + | SynExpr.CompExpr (false, isNotNakedRefCell, _comp, _m) -> + isNotNakedRefCell := + !isNotNakedRefCell + || + (match expr with + | ApplicableExpr(_, Expr.Op(TOp.Coerce, _, [SeqExpr cenv.g], _), _) -> true + | _ -> false) + | _ -> () + + let arg, tpenv = TcExpr cenv domainTy env tpenv synArg + let exprAndArg, resultTy = buildApp cenv expr resultTy arg mExprAndArg + TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed + + | ValueNone -> // OK, 'expr' doesn't have function type, but perhaps 'expr' is a computation expression builder, and 'arg' is '{ ... }' match synArg with | SynExpr.CompExpr (false, _isNotNakedRefCell, comp, _m) -> @@ -8754,25 +8804,26 @@ and TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty ( // TcLongIdentThen: Typecheck "A.B.C.E.F ... " constructs //------------------------------------------------------------------------- -and TcLongIdentThen cenv overallTy env tpenv (LongIdentWithDots(longId, _)) delayed = +and GetLongIdentTypeNameInfo delayed = + // Given 'MyOverloadedType.MySubType...' use the number of given type arguments to help + // resolve type name lookup of 'MyOverloadedType' + // Also determine if type names should resolve to Item.Types or Item.CtorGroup + match delayed with + | DelayedTypeApp (tyargs, _, _) :: (DelayedDot | DelayedDotLookup _) :: _ -> + // cases like 'MyType.Sth' + TypeNameResolutionInfo(ResolveTypeNamesToTypeRefs, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) - let ad = env.eAccessRights - let typeNameResInfo = - // Given 'MyOverloadedType.MySubType...' use arity of #given type arguments to help - // resolve type name lookup of 'MyOverloadedType' - // Also determine if type names should resolve to Item.Types or Item.CtorGroup - match delayed with - | DelayedTypeApp (tyargs, _, _) :: (DelayedDot | DelayedDotLookup _) :: _ -> - // cases like 'MyType.Sth' - TypeNameResolutionInfo(ResolveTypeNamesToTypeRefs, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) + | DelayedTypeApp (tyargs, _, _) :: _ -> + // Note, this also covers the case 'MyType.' (without LValue_get), which is needed for VS (when typing) + TypeNameResolutionInfo(ResolveTypeNamesToCtors, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) - | DelayedTypeApp (tyargs, _, _) :: _ -> - // Note, this also covers the case 'MyType.' (without LValue_get), which is needed for VS (when typing) - TypeNameResolutionInfo(ResolveTypeNamesToCtors, TypeNameResolutionStaticArgsInfo.FromTyArgs tyargs.Length) + | _ -> + TypeNameResolutionInfo.Default - | _ -> - TypeNameResolutionInfo.Default +and TcLongIdentThen cenv overallTy env tpenv (LongIdentWithDots(longId, _)) delayed = + let ad = env.eAccessRights + let typeNameResInfo = GetLongIdentTypeNameInfo delayed let nameResolutionResult = ResolveLongIdentAsExprAndComputeRange cenv.tcSink cenv.nameResolver (rangeOfLid longId) ad env.eNameResEnv typeNameResInfo longId TcItemThen cenv overallTy env tpenv nameResolutionResult delayed diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index c0998c729b0..7c1b38a4b5f 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -7182,6 +7182,16 @@ Následující členy nemají žádnou implementaci (některé výsledky jsou vynechané): {0} Všechny členy rozhraní je potřeba implementovat a uvést pod příslušnou deklarací interface, třeba takto: interface ... with member ... + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Mapuje fyzické cesty na názvy zdrojových cest z výstupu kompilátoru. diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index f5c38ec416d..33a03002ea8 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -7182,6 +7182,16 @@ Für folgende Member wurde keine Implementierung angegeben (einige Ergebnisse ausgelassen): {0} Beachten Sie, dass alle Schnittstellenmember implementiert und in einer entsprechenden interface-Deklaration aufgeführt werden müssen, z.B. "interface ... with member ...". + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Ordnet der Ausgabe von Quellpfadnamen des Compilers physische Pfade zu diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 73a099a9ad4..07a6a376d6c 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -7182,6 +7182,16 @@ No se ofreció ninguna implementación para esos miembros (se omitieron algunos resultados): {0} Tenga en cuenta que todos los miembros de la interfaz deben implementarse y enumerarse bajo una declaración de "interface" apropiada; por ejemplo, "interface ... with member ...". + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Asigna rutas físicas de acceso a nombres de ruta de origen resultantes del compilador diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index a66cc29b2b8..db443013ccc 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -7182,6 +7182,16 @@ Aucune implémentation pour ces membres (certains résultats sont omis) : {0} Notez que tous les membres d'interface doivent être implémentés et listés sous une déclaration 'interface' appropriée, par ex., 'interface ... with member ... '. + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Mappe les chemins physiques aux noms de chemin source générés par le compilateur diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index bf3c33673f7..27d3af91a0e 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -7182,6 +7182,16 @@ Non è stata specificata alcuna implementazione per tali membri (alcuni risultati sono stati omessi): {0}. Si noti che tutti i membri dell'interfaccia devono essere implementati ed elencati in una dichiarazione 'interface' appropriata, ad esempio 'interface ... with member ...'. + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Esegue il mapping dei percorsi fisici ai nomi di percorso di origine restituiti dal compilatore diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index dc8a58a5286..47430c5e72b 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -7184,6 +7184,16 @@ これらのメンバーに実装が指定されていません (一部の結果が省略されました): {0} すべてのインターフェイス メンバーは実装され、適切な 'interface' 宣言でリストされている必要があります。例: 'interface ... with member ...'。 + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler 物理パスをコンパイラ出力のソース パス名にマップします diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index c1597b85efe..2f3708ed03f 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -7182,6 +7182,16 @@ 멤버 {0}에 지정된 구현이 없습니다(일부 결과는 생략됨). 모든 인터페이스 멤버가 구현되어 적절한 'interface' 선언에 나열되어야 합니다(예: 'interface ... with member ...'). + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler 컴파일러에서 실제 경로를 소스 경로 이름 출력에 매핑합니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index af1213810f4..4b92b5b6a51 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -7182,6 +7182,16 @@ Nie podano implementacji dla tych składowych (niektóre wyniki zostały pominięte): {0}Pamiętaj, że wszystkie składowe interfejsów muszą być zaimplementowane i wymienione w ramach odpowiedniej deklaracji „interface” np. „interface ... with member ...”. + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Mapuje ścieżki fizyczne na wyjściowe nazwy ścieżek źródłowych z kompilatora diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index e806ec89442..d679c9502a5 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -7182,6 +7182,16 @@ Implementação não concedida para os membros (alguns resultados omitidos): {0} Todos os membros de interface devem ser implementados e listados em uma declaração de 'interface' apropriada, por exemplo, 'interface ... com o membro...'. + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Mapeia caminhos físicos para nomes de caminho de origem gerados pelo compilador diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index de5cb30a93f..3fc4173787b 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -7182,6 +7182,16 @@ Реализация для этих членов отсутствует (некоторые результаты опущены): {0}Обратите внимание, что каждый член интерфейса должен быть реализован и указан в соответствующем объявлении "interface", например, "интерфейс ... с членом ...". + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Сопоставляет физические пути с исходными путями в выходных данных компилятора diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 1b73a0bacc8..a04bc7ada54 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -7182,6 +7182,16 @@ Bu üyelere uygulama verilmedi (bazı sonuçlar atlandı): {0}Tüm arabirim üyelerinin uygulanması ve uygun bir "arabirim" bildirimi (ör. "arabirim ... ile üye ..." kapsamında listelenmesi gerektiğini unutmayın. + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler Fiziksel yolları derleyiciye göre kaynak yol adları çıkışıyla eşler diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index b29032a560c..38918ceec9f 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -7182,6 +7182,16 @@ 没有为这些成员提供实现 (省略了一些结果): {0}请注意,必须实现所有接口成员,并在适当的 "interface" 声明下列出,例如 "interface ... with member ..."。 + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler 将物理路径映射到编译器输出的源路径名 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index fd998bfd5d3..1a02de7e416 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -7182,6 +7182,16 @@ 未提供任何實作給這些成員 (部分結果已省略): {0}請注意,所有介面成員都必須經過實作,並列於適當的 'interface' 宣告下,例如 'interface ... with member ...'。 + + Expression does not have a name. + Expression does not have a name. + + + + Using the 'nameof' operator as a first-class function value is not permitted. + Using the 'nameof' operator as a first-class function value is not permitted. + + Maps physical paths to source path names output by the compiler 將實體路徑對應至來源路徑名稱,由編譯器輸出 diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj index cf028bc3d22..2fd3442f3f7 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj @@ -66,6 +66,7 @@ + @@ -96,9 +97,9 @@ - - - + + + diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/NameOfTests.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/NameOfTests.fs new file mode 100644 index 00000000000..32decc49109 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/NameOfTests.fs @@ -0,0 +1,295 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace FSharp.Core.Unittests +open System +open NUnit.Framework + +exception ABC + +type BasicNameOfTests() = + let localConstant = 23 + member this.MemberMethod() = 0 + member this.MemberProperty = this.MemberMethod() + static member StaticMethod() = 0 + static member StaticProperty = BasicNameOfTests.StaticMethod() + + [] + member this.``local variable name lookup`` () = + let a = 0 + let result = nameof a + Assert.AreEqual("a",result) + Assert.AreEqual("result",nameof result) + + [] + member this.``local int function name`` () = + let myFunction x = 0 * x + let b = nameof myFunction + Assert.AreEqual("myFunction",b) + + [] + member this.``local curried function name`` () = + let curriedFunction x y = x * y + let b = nameof curriedFunction + Assert.AreEqual("curriedFunction",b) + + [] + member this.``local tupled function name`` () = + let tupledFunction(x,y) = x * y + let b = nameof tupledFunction + Assert.AreEqual("tupledFunction",b) + + [] + member this.``local unit function name`` () = + let myFunction() = 1 + let b = nameof(myFunction) + Assert.AreEqual("myFunction",b) + + [] + member this.``local function parameter name`` () = + let myFunction parameter1 = nameof parameter1 + + Assert.AreEqual("parameter1",myFunction "x") + + [] + member this.``can get name from inside a local function (needs to be let rec)`` () = + let rec myLocalFunction x = + let z = 2 * x + nameof myLocalFunction + " " + z.ToString() + + Assert.AreEqual("myLocalFunction 46",myLocalFunction 23) + Assert.AreEqual("myLocalFunction 50",myLocalFunction 25) + + [] + member this.CanGetNameFromInsideAMember () = + let b = nameof(this.CanGetNameFromInsideAMember) + Assert.AreEqual("CanGetNameFromInsideAMember",b) + + [] + member this.``member function name`` () = + let b = nameof(this.MemberMethod) + Assert.AreEqual("MemberMethod",b) + + [] + member this.``namespace name`` () = + let b = nameof(FSharp.Core) + Assert.AreEqual("Core",b) + + [] + member this.``module name`` () = + let b = nameof(FSharp.Core.Operators) + Assert.AreEqual("Operators",b) + + [] + member this.``exception name`` () = + let b = nameof(ABC) + Assert.AreEqual("ABC",b) + + [] + member this.``nested type name 1`` () = + let b = nameof(System.Collections.Generic.List.Enumerator<_>) + Assert.AreEqual("Enumerator",b) + + [] + member this.``type name 2`` () = + let b = nameof(System.Action<_>) + Assert.AreEqual("Action",b) + + [] + member this.``member function which is defined below`` () = + let b = nameof(this.MemberMethodDefinedBelow) + Assert.AreEqual("MemberMethodDefinedBelow",b) + + member this.MemberMethodDefinedBelow(x,y) = x * y + + [] + member this.``static member function name`` () = + let b = nameof(BasicNameOfTests.StaticMethod) + Assert.AreEqual("StaticMethod",b) + + [] + member this.``class member lookup`` () = + let b = nameof(localConstant) + Assert.AreEqual("localConstant",b) + + [] + member this.``member property name`` () = + let b = nameof(this.MemberProperty) + Assert.AreEqual("MemberProperty",b) + + [] + member this.``static property name`` () = + let b = nameof(BasicNameOfTests.StaticProperty) + Assert.AreEqual("StaticProperty",b) + + member this.get_XYZ() = 1 + + [] + member this.``member method starting with get_`` () = + let b = nameof(this.get_XYZ) + Assert.AreEqual("get_XYZ",b) + + static member get_SXYZ() = 1 + + [] + member this.``static method starting with get_`` () = + let b = nameof(BasicNameOfTests.get_SXYZ) + Assert.AreEqual("get_SXYZ",b) + + [] + member this.``nameof local property with encapsulated name`` () = + let ``local property with encapsulated name and %.f`` = 0 + let b = nameof(``local property with encapsulated name and %.f``) + Assert.AreEqual("local property with encapsulated name and %.f",b) + +[] +type MethodGroupNameOfTests() = + member this.MethodGroup() = () + member this.MethodGroup(i:int) = () + + member this.MethodGroup1(i:int, f:float, s:string) = 0 + member this.MethodGroup1(f:float, l:int64) = "foo" + member this.MethodGroup1(u:unit -> unit -> int, h: unit) : unit = () + + [] + member this.``single argument method group name lookup`` () = + let b = nameof(this.MethodGroup) + Assert.AreEqual("MethodGroup",b) + + [] + member this.``multiple argument method group name lookup`` () = + let b = nameof(this.MethodGroup1 : (float * int64 -> _)) + Assert.AreEqual("MethodGroup1",b) + +[] +type FrameworkMethodTests() = + [] + member this.``library function name`` () = + let b = nameof(List.map) + Assert.AreEqual("map",b) + + [] + member this.``static class function name`` () = + let b = nameof(System.Tuple.Create) + Assert.AreEqual("Create",b) + +type CustomUnionType = + | OptionA + | OptionB of int * string + +type CustomRecordType = + { X: int; Y: int } + +[] type Milliquacks + +[] +type UnionAndRecordNameOfTests() = + + [] + member this.``measure 1`` () = + let b = nameof(Milliquacks) + Assert.AreEqual("Milliquacks",b) + + [] + member this.``record case 1`` () = + let sample = Unchecked.defaultof + let b = nameof(sample.X) + Assert.AreEqual("X",b) + let b = nameof(sample.Y) + Assert.AreEqual("Y",b) + + [] + member this.``union case 1`` () = + let b = nameof(OptionA) + Assert.AreEqual("OptionA",b) + + [] + member this.``union case 2`` () = + let b = nameof(OptionB) + Assert.AreEqual("OptionB",b) + +[] +type AttributeNameOfTests() = + + [] + member this.``ok in attribute`` () = + let t = typeof.GetMethod("ok in attribute") + let attrs = t.GetCustomAttributes(typeof, false) + let attr = attrs.[0] :?> ObsoleteAttribute + Assert.AreEqual(attr.Message, "test string") + +[] +type OperatorNameOfTests() = + + [] + member this.``lookup name of typeof operator`` () = + let b = nameof(typeof) + Assert.AreEqual("typeof",b) + + [] + member this.``lookup name of + operator`` () = + let b = nameof(+) + Assert.AreEqual("op_Addition",b) + + [] + member this.``lookup name of |> operator`` () = + let a = nameof(|>) + Assert.AreEqual("op_PipeRight",a) + let b = nameof(op_PipeRight) + Assert.AreEqual("op_PipeRight",b) + + [] + member this.``lookup name of nameof operator`` () = + let b = nameof(nameof) + Assert.AreEqual("nameof",b) + +[] +type PatternMatchingOfOperatorNameTests() = + member this.Method1(i:int) = () + + [] + member this.``use it as a match case guard`` () = + match "Method1" with + | x when x = nameof(this.Method1) -> () + | _ -> Assert.Fail("not expected") + +[] +type NameOfOperatorInQuotations() = + [] + member this.``use it in a quotation`` () = + let q = + <@ + let f(x:int) = nameof x + f 20 + @> + () + +[] +type NameOfOperatorForGenerics() = + [] + member this.``use it in a generic function`` () = + let fullyGeneric x = x + let b = nameof(fullyGeneric) + Assert.AreEqual("fullyGeneric",b) + + [] + member this.``lookup name of a generic class`` () = + let b = nameof System.Collections.Generic.List + Assert.AreEqual("List",b) + +[] +type UserDefinedNameOfTests() = + [] + member this.``userdefined nameof should shadow the operator`` () = + let nameof x = "test" + x.ToString() + + let y = nameof 1 + Assert.AreEqual("test1",y) + +type Person = + { Name : string + Age : int } + member __.Update(fld : string, value : obj) = + match fld with + | x when x = nameof __.Name -> { __ with Name = string value } + | x when x = nameof __.Age -> { __ with Age = value :?> int } + | _ -> __ diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs index 4d1c570e6f6..ed6ee35df21 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs @@ -755,9 +755,9 @@ Microsoft.FSharp.Control.ObservableModule: System.Type GetType() Microsoft.FSharp.Control.ObservableModule: Void Add[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], System.IObservable`1[T]) Microsoft.FSharp.Control.WebExtensions: Boolean Equals(System.Object) Microsoft.FSharp.Control.WebExtensions: Int32 GetHashCode() -Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Net.WebResponse] AsyncGetResponse(System.Net.WebRequest) Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncDownloadFile(System.Net.WebClient, System.Uri, System.String) Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Byte[]] AsyncDownloadData(System.Net.WebClient, System.Uri) +Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.Net.WebResponse] AsyncGetResponse(System.Net.WebRequest) Microsoft.FSharp.Control.WebExtensions: Microsoft.FSharp.Control.FSharpAsync`1[System.String] AsyncDownloadString(System.Net.WebClient, System.Uri) Microsoft.FSharp.Control.WebExtensions: System.String ToString() Microsoft.FSharp.Control.WebExtensions: System.Type GetType() @@ -2732,6 +2732,7 @@ Microsoft.FSharp.Core.Operators: System.Object Box[T](T)" + Microsoft.FSharp.Core.Operators: System.RuntimeMethodHandle MethodHandleOf[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult])" + #endif @" +Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) Microsoft.FSharp.Core.Operators: System.String ToString() Microsoft.FSharp.Core.Operators: System.String ToString[T](T) Microsoft.FSharp.Core.Operators: System.String op_Concatenate(System.String, System.String) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs index 945b341a372..408fc3955f2 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs @@ -2732,6 +2732,7 @@ Microsoft.FSharp.Core.Operators: System.Object Box[T](T)" + Microsoft.FSharp.Core.Operators: System.RuntimeMethodHandle MethodHandleOf[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult])" + #endif @" +Microsoft.FSharp.Core.Operators: System.String NameOf[T](T) Microsoft.FSharp.Core.Operators: System.String ToString() Microsoft.FSharp.Core.Operators: System.String ToString[T](T) Microsoft.FSharp.Core.Operators: System.String op_Concatenate(System.String, System.String) diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAdditionExpr.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAdditionExpr.fs new file mode 100644 index 00000000000..2fd34fa161a --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAdditionExpr.fs @@ -0,0 +1,7 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on const string +//Expression does not have a name. + +let x = nameof(1+2) + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAppliedFunction.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAppliedFunction.fs new file mode 100644 index 00000000000..666ba1453f3 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAppliedFunction.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on applied functions +//Expression does not have a name. + +let f() = 1 +let x = nameof(f()) + +exit 0 \ No newline at end of file diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAsAFunction.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAsAFunction.fs new file mode 100644 index 00000000000..4fba9670064 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfAsAFunction.fs @@ -0,0 +1,7 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof can't be used as a function. +//Using the 'nameof' operator as a first-class function value is not permitted + +let f = nameof + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfDictLookup.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfDictLookup.fs new file mode 100644 index 00000000000..988863a0e1f --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfDictLookup.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on dictionary lookup +//Expression does not have a name. + +let dict = new System.Collections.Generic.Dictionary() +let b = nameof(dict.[2]) + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfIntConst.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfIntConst.fs new file mode 100644 index 00000000000..9a2487e534f --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfIntConst.fs @@ -0,0 +1,7 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on const int +//Expression does not have a name. + +let x = nameof 1 + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfIntegerAppliedFunction.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfIntegerAppliedFunction.fs new file mode 100644 index 00000000000..303bd2b9a31 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfIntegerAppliedFunction.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on applied functions +//Expression does not have a name. + +let f x = 1 * x +let x = nameof(f 2) + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfParameterAppliedFunction.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfParameterAppliedFunction.fs new file mode 100644 index 00000000000..252e867c91a --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfParameterAppliedFunction.fs @@ -0,0 +1,9 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on applied functions +//Expression does not have a name. + +let f x y = x y +let z x = 1 * x +let b = nameof(f z 1) + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfPartiallyAppliedFunction.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfPartiallyAppliedFunction.fs new file mode 100644 index 00000000000..be11b22a6a6 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfPartiallyAppliedFunction.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on partially applied functions +//Expression does not have a name. + +let f x y = y * x +let x = nameof(f 2) + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfStringConst.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfStringConst.fs new file mode 100644 index 00000000000..f901f6f72ff --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfStringConst.fs @@ -0,0 +1,7 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof doesn't work on const string +//Expression does not have a name. + +let x = nameof "string" + +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfUnresolvableName.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfUnresolvableName.fs new file mode 100644 index 00000000000..2f998cbb172 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfUnresolvableName.fs @@ -0,0 +1,6 @@ +// #Regression #Conformance #DataExpressions +// Verify that passing unresolvable symbol name results with compilation error. +//The value, constructor, namespace or type 'Unknown' is not defined. + +let b = nameof System.Collections.Generic.Unknown +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfWithPipe.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfWithPipe.fs new file mode 100644 index 00000000000..26074a4cac6 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/E_NameOfWithPipe.fs @@ -0,0 +1,7 @@ +// #Regression #Conformance #DataExpressions +// Verify that nameof can't be used as a function. +//Using the 'nameof' operator as a first-class function value is not permitted. + +let curriedFunction x y = x * y +let b = curriedFunction |> nameof +exit 0 diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/env.lst new file mode 100644 index 00000000000..7e08cf92ea7 --- /dev/null +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/NameOf/env.lst @@ -0,0 +1,11 @@ + SOURCE=E_NameOfIntConst.fs # E_NameOfIntConst.fs + SOURCE=E_NameOfStringConst.fs # E_NameOfStringConst.fs + SOURCE=E_NameOfAppliedFunction.fs # E_NameOfAppliedFunction.fs + SOURCE=E_NameOfIntegerAppliedFunction.fs # E_NameOfIntegerAppliedFunction.fs + SOURCE=E_NameOfPartiallyAppliedFunction.fs # E_NameOfPartiallyAppliedFunction.fs + SOURCE=E_NameOfDictLookup.fs # E_NameOfDictLookup.fs + SOURCE=E_NameOfAdditionExpr.fs # E_NameOfAdditionExpr.fs + SOURCE=E_NameOfParameterAppliedFunction.fs # E_NameOfParameterAppliedFunction.fs + SOURCE=E_NameOfAsAFunction.fs # E_NameOfAsAFunction.fs + SOURCE=E_NameOfWithPipe.fs # E_NameOfWithPipe.fs + SOURCE=E_NameOfUnresolvableName.fs # E_NameOfUnresolvableName.fs diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst index 6e453b8d7b8..58ca9df397e 100644 --- a/tests/fsharpqa/Source/test.lst +++ b/tests/fsharpqa/Source/test.lst @@ -243,6 +243,7 @@ Conformance08 Conformance\UnitsOfMeasure\Parenthesis Conformance08 Conformance\UnitsOfMeasure\Parsing Conformance08 Conformance\UnitsOfMeasure\TypeChecker Conformance08 Conformance\UnitsOfMeasure\WithOOP +Conformance08 Conformance\Expressions\DataExpressions\NameOf Misc01 ClrFx\PseudoCustomAttributes\AssemblyAlgorithmId Misc01 ClrFx\PseudoCustomAttributes\AssemblyConfiguration