From b7fe207c34aac7eb931feb9eaede8f32007ea66d Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Fri, 2 Sep 2016 18:58:55 +0200 Subject: [PATCH 01/11] Faster name resolution + more predictions --- src/fsharp/NameResolution.fs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index bb6ad631ea0..39008c2b80d 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -2000,6 +2000,10 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv (typeN |> CollectResults (fun (resInfo,typ) -> ResolveObjectConstructorPrim ncenv nenv.eDisplayEnv resInfo id.idRange ad typ) |> MapResults (fun (resInfo,item) -> (resInfo,item,[])) + match tyconSearch with + | Result (res :: _) -> success res + | _ -> + // Something in a sub-namespace or sub-module let moduleSearch = if not (List.isEmpty rest) then @@ -2205,6 +2209,11 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num ResolveLongIdentInTyconRefs (ncenv:NameResolver) nenv LookupKind.Pattern (depth+1) m ad rest numTyArgsOpt id.idRange tcrefs | _ -> NoResultsOrUsefulErrors + + match tyconSearch with + | Result (res :: _) -> success res + | _ -> + // Constructor of a type? let ctorSearch = if List.isEmpty rest then @@ -2215,6 +2224,10 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num else NoResultsOrUsefulErrors + match ctorSearch with + | Result (res :: _) -> success res + | _ -> + // Something in a sub-namespace or sub-module or nested-type let moduleSearch = if not (List.isEmpty rest) then @@ -2225,8 +2238,16 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num | _ -> NoResultsOrUsefulErrors else NoResultsOrUsefulErrors - let res = AtMostOneResult id.idRange ( tyconSearch +++ ctorSearch +++ moduleSearch +++ raze (UndefinedName(depth,FSComp.SR.undefinedNameConstructorModuleOrNamespace,id,NoPredictions))) - res + + match tyconSearch +++ ctorSearch +++ moduleSearch with + | Result [] -> + let predictedPossibleTypes = + modref.ModuleOrNamespaceType.AllEntities + |> Seq.map (fun e -> e.DisplayName) + |> Set.ofSeq + + raze (UndefinedName(depth,FSComp.SR.undefinedNameConstructorModuleOrNamespace,id,predictedPossibleTypes)) + | results -> AtMostOneResult id.idRange results /// Used to report a warning condition for the use of upper-case identifiers in patterns exception UpperCaseIdentifierInPattern of range From dcd2cf1dd6c6b766c145b6c077a8bed302bf383c Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Fri, 2 Sep 2016 19:07:05 +0200 Subject: [PATCH 02/11] Cleanup --- src/fsharp/NameResolution.fs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 39008c2b80d..b1e97f6f4ce 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -2455,7 +2455,9 @@ let rec ResolveTypeLongIdentPrim (ncenv:NameResolver) fullyQualified m nenv ad ( (ResolveTypeLongIdentInModuleOrNamespace ncenv typeNameResInfo.DropStaticArgsInfo AccessibleFromSomeFSharpCode genOk) |?> List.concat - match tyconSearch +++ modulSearch with + let searchSoFar = tyconSearch +++ modulSearch + + match searchSoFar with | Result results -> // NOTE: we delay checking the CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities condition until right at the end after we've // collected all possible resolutions of the type @@ -2465,12 +2467,12 @@ let rec ResolveTypeLongIdentPrim (ncenv:NameResolver) fullyQualified m nenv ad ( // We've already reported the ambiguity, possibly as an error. Now just take the first possible result. success(resInfo,tcref) | [] -> - // failing case - report nice ambiguity errors even in this case - AtMostOneResult m ((tyconSearch +++ modulSearch +++ modulSearchFailed()) |?> (fun tcrefs -> CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, genOk, rangeOfLid lid))) + // failing case - report nice ambiguity errors even in this case + AtMostOneResult m ((searchSoFar +++ modulSearchFailed()) |?> (fun tcrefs -> CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, genOk, rangeOfLid lid))) | _ -> // failing case - report nice ambiguity errors even in this case - AtMostOneResult m ((tyconSearch +++ modulSearch +++ modulSearchFailed()) |?> (fun tcrefs -> CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, genOk, rangeOfLid lid))) + AtMostOneResult m ((searchSoFar +++ modulSearchFailed()) |?> (fun tcrefs -> CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, typeNameResInfo, genOk, rangeOfLid lid))) /// Resolve a long identifier representing a type and report it From b95e1ad3897487e58fc99b6acbe6656912fb6d79 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Fri, 2 Sep 2016 19:07:25 +0200 Subject: [PATCH 03/11] Faster name resolution --- src/fsharp/NameResolution.fs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index b1e97f6f4ce..8f3ea59b53b 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -2397,6 +2397,7 @@ let rec private ResolveTypeLongIdentInModuleOrNamespace (ncenv:NameResolver) (ty ResolveTypeLongIdentInModuleOrNamespace ncenv typeNameResInfo ad genOk resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType rest | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameNamespaceOrModule,id,NoPredictions)) + let tyconSearch = let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, ad, id.idText, TypeNameResolutionStaticArgsInfo.Indefinite, modref) match tcrefs with @@ -2505,6 +2506,12 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re let showDeprecated = HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs success(resInfo, FieldResolution(modref.RecdFieldRefInNestedTycon tycon id,showDeprecated), rest) | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions)) + |> OneResult + + match modulScopedFieldNames with + | Result (res :: _) -> success res + | _ -> + // search for type-qualified names, e.g. { Microsoft.FSharp.Core.Ref.contents = 1 } let tyconSearch = match lid with @@ -2517,6 +2524,11 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re tyconSearch | _ -> NoResultsOrUsefulErrors + + match tyconSearch with + | Result (res :: _) -> success res + | _ -> + // search for names in nested modules, e.g. { Microsoft.FSharp.Core.contents = 1 } let modulSearch = if not (List.isEmpty rest) then @@ -2526,7 +2538,9 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re ResolveFieldInModuleOrNamespace ncenv nenv ad resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType rest | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions)) else raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions)) - AtMostOneResult m (OneResult modulScopedFieldNames +++ tyconSearch +++ OneResult modulSearch) + |> OneResult + + AtMostOneResult m (modulScopedFieldNames +++ tyconSearch +++ modulSearch) | [] -> error(InternalError("ResolveFieldInModuleOrNamespace",m)) From 8c26d34e2f4ea32f484fa292987df90592bd8dbe Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Fri, 2 Sep 2016 19:10:21 +0200 Subject: [PATCH 04/11] Cleanup --- src/fsharp/NameResolution.fs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 8f3ea59b53b..c63b3228b2e 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -2504,9 +2504,8 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re match TryFindTypeWithRecdField modref id with | Some tycon when IsEntityAccessible ncenv.amap m ad (modref.NestedTyconRef tycon) -> let showDeprecated = HasFSharpAttribute ncenv.g ncenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs - success(resInfo, FieldResolution(modref.RecdFieldRefInNestedTycon tycon id,showDeprecated), rest) + success [resInfo, FieldResolution(modref.RecdFieldRefInNestedTycon tycon id,showDeprecated), rest] | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions)) - |> OneResult match modulScopedFieldNames with | Result (res :: _) -> success res @@ -2535,10 +2534,10 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re match modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> let resInfo = resInfo.AddEntity(id.idRange,submodref) - ResolveFieldInModuleOrNamespace ncenv nenv ad resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType rest + ResolveFieldInModuleOrNamespace ncenv nenv ad resInfo (depth+1) m submodref submodref.ModuleOrNamespaceType rest + |> OneResult | _ -> raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions)) else raze (UndefinedName(depth,FSComp.SR.undefinedNameRecordLabelOrNamespace,id,NoPredictions)) - |> OneResult AtMostOneResult m (modulScopedFieldNames +++ tyconSearch +++ modulSearch) | [] -> From bd2723662f54dc92338e2b5339bf670a115c7f3b Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Fri, 2 Sep 2016 19:15:46 +0200 Subject: [PATCH 05/11] Faster name resolution --- src/fsharp/NameResolution.fs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index c63b3228b2e..7fcb767bc11 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -2642,11 +2642,38 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) allFields = let tyconSearch = tyconSearch |?> List.choose (function (resInfo,Item.RecdField(RecdFieldInfo(_,rfref)),rest) -> Some(resInfo,FieldResolution(rfref,false),rest) | _ -> None) tyconSearch | _ -> NoResultsOrUsefulErrors + let modulSearch ad = ResolveLongIndentAsModuleOrNamespaceThen ncenv.amap m OpenQualified nenv ad lid (ResolveFieldInModuleOrNamespace ncenv nenv ad) - let resInfo,item,rest = ForceRaise (AtMostOneResult m (modulSearch ad +++ tyconSearch ad +++ modulSearch AccessibleFromSomeFSharpCode +++ tyconSearch AccessibleFromSomeFSharpCode)) - if not (List.isEmpty rest) then errorR(Error(FSComp.SR.nrInvalidFieldLabel(),(List.head rest).idRange)) + + let search = + let moduleSearch1 = modulSearch ad + + match moduleSearch1 with + | Result (res :: _) -> success res + | _ -> + + let tyconSearch1 = tyconSearch ad + + match tyconSearch1 with + | Result (res :: _) -> success res + | _ -> + + let moduleSearch2 = modulSearch AccessibleFromSomeFSharpCode + + match moduleSearch2 with + | Result (res :: _) -> success res + | _ -> + + let tyconSearch2 = tyconSearch AccessibleFromSomeFSharpCode + + AtMostOneResult m (moduleSearch1 +++ tyconSearch1 +++ moduleSearch2 +++ tyconSearch2) + + let resInfo,item,rest = ForceRaise search + if not (List.isEmpty rest) then + errorR(Error(FSComp.SR.nrInvalidFieldLabel(),(List.head rest).idRange)) + [(resInfo,item)] let ResolveField sink ncenv nenv ad typ (mp,id) allFields = From 9c979f6bee631056779771f1f51067a520bdada3 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Fri, 2 Sep 2016 19:31:56 +0200 Subject: [PATCH 06/11] Faster name resolution --- src/fsharp/NameResolution.fs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 7fcb767bc11..a54ad52a9bc 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -1845,9 +1845,9 @@ let DecodeFSharpEvent (pinfos:PropInfo list) ad g (ncenv:NameResolver) m = None -// REVIEW: this shows up on performance logs. Consider for example endless resolutions of "List.map" to +// REVIEW: this shows up on performance logs. Consider for example endless resolutions of "List.map" to // the empty set of results, or "x.Length" for a list or array type. This indicates it could be worth adding a cache here. -let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo:ResolutionInfo) depth m ad (lid:Ident list) findFlag (typeNameResInfo: TypeNameResolutionInfo) typ = +let rec ResolveLongIdentInTypePrim atMostOne (ncenv:NameResolver) nenv lookupKind (resInfo:ResolutionInfo) depth m ad (lid:Ident list) findFlag (typeNameResInfo: TypeNameResolutionInfo) typ = let g = ncenv.g match lid with | [] -> error(InternalError("ResolveLongIdentInTypePrim",m)) @@ -1902,6 +1902,12 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo elif isTyparTy g typ then raze (IndeterminateType(unionRanges m id.idRange)) else raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,NoPredictions)) + + |> OneResult + + match contentsSearchAccessible with + | Result res when atMostOne && not (List.isEmpty res) -> contentsSearchAccessible + | _ -> let nestedSearchAccessible = let nestedTypes = GetNestedTypesOfType (ad, ncenv, Some nm, (if List.isEmpty rest then typeNameResInfo.StaticArgsInfo else TypeNameResolutionStaticArgsInfo.Indefinite), true, m) typ @@ -1918,18 +1924,19 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo OneSuccess (resInfo,Item.Types (nm,nestedTypes),rest) else ResolveLongIdentInNestedTypes ncenv nenv lookupKind resInfo (depth+1) id m ad rest findFlag typeNameResInfo nestedTypes - (OneResult contentsSearchAccessible +++ nestedSearchAccessible) + + contentsSearchAccessible +++ nestedSearchAccessible and ResolveLongIdentInNestedTypes (ncenv:NameResolver) nenv lookupKind resInfo depth id m ad lid findFlag typeNameResInfo typs = typs |> CollectResults (fun typ -> let resInfo = if isAppTy ncenv.g typ then resInfo.AddEntity(id.idRange,tcrefOfAppTy ncenv.g typ) else resInfo - ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad lid findFlag typeNameResInfo typ + ResolveLongIdentInTypePrim true ncenv nenv lookupKind resInfo depth m ad lid findFlag typeNameResInfo typ |> AtMostOneResult m) /// Resolve a long identifier using type-qualified name resolution. let ResolveLongIdentInType sink ncenv nenv lookupKind m ad lid findFlag typeNameResInfo typ = let resInfo,item,rest = - ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind ResolutionInfo.Empty 0 m ad lid findFlag typeNameResInfo typ + ResolveLongIdentInTypePrim true (ncenv:NameResolver) nenv lookupKind ResolutionInfo.Empty 0 m ad lid findFlag typeNameResInfo typ |> AtMostOneResult m |> ForceRaise ResolutionInfo.SendToSink (sink,ncenv,nenv,ItemOccurence.UseInType,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) @@ -1941,7 +1948,7 @@ let private ResolveLongIdentInTyconRef (ncenv:NameResolver) nenv lookupKind resI CheckForDirectReferenceToGeneratedType (tcref, PermitDirectReferenceToGeneratedType.No, m) #endif let typ = FreshenTycon ncenv m tcref - typ |> ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad lid IgnoreOverrides typeNameResInfo + typ |> ResolveLongIdentInTypePrim false ncenv nenv lookupKind resInfo depth m ad lid IgnoreOverrides typeNameResInfo let private ResolveLongIdentInTyconRefs (ncenv:NameResolver) nenv lookupKind depth m ad lid typeNameResInfo idRange tcrefs = tcrefs |> CollectResults (fun (resInfo:ResolutionInfo,tcref) -> @@ -2701,7 +2708,7 @@ let FreshenRecdFieldRef (ncenv:NameResolver) m (rfref:RecdFieldRef) = // QUERY (instantiationGenerator cleanup): it would be really nice not to flow instantiationGenerator to here. let private ResolveExprDotLongIdent (ncenv:NameResolver) m ad nenv typ lid findFlag = let typeNameResInfo = TypeNameResolutionInfo.Default - let adhoctDotSearchAccessible = AtMostOneResult m (ResolveLongIdentInTypePrim ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m ad lid findFlag typeNameResInfo typ) + let adhoctDotSearchAccessible = AtMostOneResult m (ResolveLongIdentInTypePrim true ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m ad lid findFlag typeNameResInfo typ) match adhoctDotSearchAccessible with | Exception _ -> // If the dot is not resolved by adhoc overloading then look for a record field @@ -2723,8 +2730,8 @@ let private ResolveExprDotLongIdent (ncenv:NameResolver) m ad nenv typ lid findF match AtMostOneResult m search with | Result _ as res -> ForceRaise res | _ -> - let adhoctDotSearchAll = ResolveLongIdentInTypePrim ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m AccessibleFromSomeFSharpCode lid findFlag typeNameResInfo typ - ForceRaise (AtMostOneResult m (search +++ adhoctDotSearchAll)) + let adhocDotSearchAll = ResolveLongIdentInTypePrim true ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m AccessibleFromSomeFSharpCode lid findFlag typeNameResInfo typ + ForceRaise (AtMostOneResult m (search +++ adhocDotSearchAll)) | Result _ -> ForceRaise adhoctDotSearchAccessible From 8cee661b46af325ad76bd683f8b8742a8ddebd46 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Sat, 3 Sep 2016 10:29:35 +0200 Subject: [PATCH 07/11] Cleanup --- src/fsharp/NameResolution.fs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index a54ad52a9bc..3c16c040d55 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -1857,17 +1857,18 @@ let rec ResolveLongIdentInTypePrim atMostOne (ncenv:NameResolver) nenv lookupKin let optFilter = Some nm // used to filter the searches of the tables let contentsSearchAccessible = let unionCaseSearch = - if (match lookupKind with LookupKind.Expr | LookupKind.Pattern -> true | _ -> false) then - TryFindUnionCaseOfType g typ nm - else - None + match lookupKind with + | LookupKind.Expr | LookupKind.Pattern -> TryFindUnionCaseOfType g typ nm + | _ -> None + // Lookup: datatype constructors take precedence match unionCaseSearch with | Some ucase -> success(resInfo,Item.UnionCase(ucase,false),rest) | None -> + let isLookUpExpr = match lookupKind with LookupKind.Expr -> true | _ -> false match TryFindIntrinsicNamedItemOfType ncenv.InfoReader (nm,ad) findFlag m typ with - | Some (PropertyItem psets) when (match lookupKind with LookupKind.Expr -> true | _ -> false) -> + | Some (PropertyItem psets) when isLookUpExpr -> let pinfos = psets |> ExcludeHiddenOfPropInfos g ncenv.amap m // fold the available extension members into the overload resolution @@ -1876,9 +1877,9 @@ let rec ResolveLongIdentInTypePrim atMostOne (ncenv:NameResolver) nenv lookupKin // make sure to keep the intrinsic pinfos before the extension pinfos in the list, // since later on this logic is used when giving preference to intrinsic definitions match DecodeFSharpEvent (pinfos@extensionPropInfos) ad g ncenv m with - | Some x -> success (resInfo, x, rest) - | None -> raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,NoPredictions)) - | Some(MethodItem msets) when (match lookupKind with LookupKind.Expr -> true | _ -> false) -> + | Some x -> success (resInfo, x, rest) + | None -> raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,NoPredictions)) + | Some(MethodItem msets) when isLookUpExpr -> let minfos = msets |> ExcludeHiddenOfMethInfos g ncenv.amap m // fold the available extension members into the overload resolution @@ -1888,16 +1889,16 @@ let rec ResolveLongIdentInTypePrim atMostOne (ncenv:NameResolver) nenv lookupKin | Some (ILFieldItem (finfo:: _)) when (match lookupKind with LookupKind.Expr | LookupKind.Pattern -> true | _ -> false) -> success (resInfo,Item.ILField finfo,rest) - | Some (EventItem (einfo :: _)) when (match lookupKind with LookupKind.Expr -> true | _ -> false) -> + | Some (EventItem (einfo :: _)) when isLookUpExpr -> success (resInfo,Item.Event einfo,rest) | Some (RecdFieldItem (rfinfo)) when (match lookupKind with LookupKind.Expr | LookupKind.RecdField | LookupKind.Pattern -> true | _ -> false) -> success(resInfo,Item.RecdField(rfinfo),rest) | _ -> let pinfos = ExtensionPropInfosOfTypeInScope ncenv.InfoReader nenv (optFilter, ad) m typ - if not (List.isEmpty pinfos) && (match lookupKind with LookupKind.Expr -> true | _ -> false) then + if not (List.isEmpty pinfos) && isLookUpExpr then success (resInfo,Item.Property (nm,pinfos),rest) else let minfos = ExtensionMethInfosOfTypeInScope ncenv.InfoReader nenv optFilter m typ - if not (List.isEmpty minfos) && (match lookupKind with LookupKind.Expr -> true | _ -> false) then + if not (List.isEmpty minfos) && isLookUpExpr then success (resInfo,Item.MakeMethGroup (nm,minfos),rest) elif isTyparTy g typ then raze (IndeterminateType(unionRanges m id.idRange)) From f4d5d7be5071b22dbef91bd4d6b0bc43f6b02497 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Sat, 3 Sep 2016 12:08:54 +0200 Subject: [PATCH 08/11] Cleanup name res --- src/fsharp/NameResolution.fs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 3c16c040d55..aa69a609239 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -1847,7 +1847,7 @@ let DecodeFSharpEvent (pinfos:PropInfo list) ad g (ncenv:NameResolver) m = // REVIEW: this shows up on performance logs. Consider for example endless resolutions of "List.map" to // the empty set of results, or "x.Length" for a list or array type. This indicates it could be worth adding a cache here. -let rec ResolveLongIdentInTypePrim atMostOne (ncenv:NameResolver) nenv lookupKind (resInfo:ResolutionInfo) depth m ad (lid:Ident list) findFlag (typeNameResInfo: TypeNameResolutionInfo) typ = +let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo:ResolutionInfo) depth m ad (lid:Ident list) findFlag (typeNameResInfo: TypeNameResolutionInfo) typ = let g = ncenv.g match lid with | [] -> error(InternalError("ResolveLongIdentInTypePrim",m)) @@ -1907,7 +1907,7 @@ let rec ResolveLongIdentInTypePrim atMostOne (ncenv:NameResolver) nenv lookupKin |> OneResult match contentsSearchAccessible with - | Result res when atMostOne && not (List.isEmpty res) -> contentsSearchAccessible + | Result res when not (List.isEmpty res) -> contentsSearchAccessible | _ -> let nestedSearchAccessible = @@ -1931,13 +1931,13 @@ let rec ResolveLongIdentInTypePrim atMostOne (ncenv:NameResolver) nenv lookupKin and ResolveLongIdentInNestedTypes (ncenv:NameResolver) nenv lookupKind resInfo depth id m ad lid findFlag typeNameResInfo typs = typs |> CollectResults (fun typ -> let resInfo = if isAppTy ncenv.g typ then resInfo.AddEntity(id.idRange,tcrefOfAppTy ncenv.g typ) else resInfo - ResolveLongIdentInTypePrim true ncenv nenv lookupKind resInfo depth m ad lid findFlag typeNameResInfo typ + ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad lid findFlag typeNameResInfo typ |> AtMostOneResult m) /// Resolve a long identifier using type-qualified name resolution. let ResolveLongIdentInType sink ncenv nenv lookupKind m ad lid findFlag typeNameResInfo typ = let resInfo,item,rest = - ResolveLongIdentInTypePrim true (ncenv:NameResolver) nenv lookupKind ResolutionInfo.Empty 0 m ad lid findFlag typeNameResInfo typ + ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind ResolutionInfo.Empty 0 m ad lid findFlag typeNameResInfo typ |> AtMostOneResult m |> ForceRaise ResolutionInfo.SendToSink (sink,ncenv,nenv,ItemOccurence.UseInType,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) @@ -1949,7 +1949,7 @@ let private ResolveLongIdentInTyconRef (ncenv:NameResolver) nenv lookupKind resI CheckForDirectReferenceToGeneratedType (tcref, PermitDirectReferenceToGeneratedType.No, m) #endif let typ = FreshenTycon ncenv m tcref - typ |> ResolveLongIdentInTypePrim false ncenv nenv lookupKind resInfo depth m ad lid IgnoreOverrides typeNameResInfo + typ |> ResolveLongIdentInTypePrim ncenv nenv lookupKind resInfo depth m ad lid IgnoreOverrides typeNameResInfo let private ResolveLongIdentInTyconRefs (ncenv:NameResolver) nenv lookupKind depth m ad lid typeNameResInfo idRange tcrefs = tcrefs |> CollectResults (fun (resInfo:ResolutionInfo,tcref) -> @@ -2709,7 +2709,7 @@ let FreshenRecdFieldRef (ncenv:NameResolver) m (rfref:RecdFieldRef) = // QUERY (instantiationGenerator cleanup): it would be really nice not to flow instantiationGenerator to here. let private ResolveExprDotLongIdent (ncenv:NameResolver) m ad nenv typ lid findFlag = let typeNameResInfo = TypeNameResolutionInfo.Default - let adhoctDotSearchAccessible = AtMostOneResult m (ResolveLongIdentInTypePrim true ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m ad lid findFlag typeNameResInfo typ) + let adhoctDotSearchAccessible = AtMostOneResult m (ResolveLongIdentInTypePrim ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m ad lid findFlag typeNameResInfo typ) match adhoctDotSearchAccessible with | Exception _ -> // If the dot is not resolved by adhoc overloading then look for a record field @@ -2731,7 +2731,7 @@ let private ResolveExprDotLongIdent (ncenv:NameResolver) m ad nenv typ lid findF match AtMostOneResult m search with | Result _ as res -> ForceRaise res | _ -> - let adhocDotSearchAll = ResolveLongIdentInTypePrim true ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m AccessibleFromSomeFSharpCode lid findFlag typeNameResInfo typ + let adhocDotSearchAll = ResolveLongIdentInTypePrim ncenv nenv LookupKind.Expr ResolutionInfo.Empty 1 m AccessibleFromSomeFSharpCode lid findFlag typeNameResInfo typ ForceRaise (AtMostOneResult m (search +++ adhocDotSearchAll)) | Result _ -> From 8160964ecbda6f6eb2262437ee0d8aca88e7af34 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Sat, 3 Sep 2016 12:16:57 +0200 Subject: [PATCH 09/11] yet another case --- src/fsharp/NameResolution.fs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index aa69a609239..45137c7bcfb 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -2103,18 +2103,24 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) fullyQualified m ad n match envSearch with | Some res -> res | None -> - // Check if it's a type name, e.g. a constructor call or a type instantiation - let ctorSearch = - let tcrefs = LookupTypeNameInEnvMaybeHaveArity fullyQualified id.idText typeNameResInfo nenv - ChooseTyconRefInExpr (ncenv, m, ad, nenv, id, typeNameResInfo, resInfo, tcrefs) - - let implicitOpSearch = - if IsMangledOpName id.idText then - success [(resInfo,Item.ImplicitOp(id, ref None),[])] - else NoResultsOrUsefulErrors - - let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueOfConstructor,id,NoPredictions)) - let search = ctorSearch +++ implicitOpSearch +++ failingCase + let search = + // Check if it's a type name, e.g. a constructor call or a type instantiation + let ctorSearch = + let tcrefs = LookupTypeNameInEnvMaybeHaveArity fullyQualified id.idText typeNameResInfo nenv + ChooseTyconRefInExpr (ncenv, m, ad, nenv, id, typeNameResInfo, resInfo, tcrefs) + + match ctorSearch with + | Result res when not (List.isEmpty res) -> ctorSearch + | _ -> + + let implicitOpSearch = + if IsMangledOpName id.idText then + success [(resInfo,Item.ImplicitOp(id, ref None),[])] + else NoResultsOrUsefulErrors + + let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueOfConstructor,id,NoPredictions)) + ctorSearch +++ implicitOpSearch +++ failingCase + let resInfo,item,rest = ForceRaise (AtMostOneResult m search) ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) item,rest From c6eb2971ae811bea1fe40107df9e1b6779e5cc2c Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Sat, 3 Sep 2016 12:24:19 +0200 Subject: [PATCH 10/11] yet another case --- src/fsharp/NameResolution.fs | 57 +++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 45137c7bcfb..21c9a3d014a 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -2156,28 +2156,57 @@ let rec ResolveExprLongIdentPrim sink (ncenv:NameResolver) fullyQualified m ad n let tyconSearch ad = let tcrefs = LookupTypeNameInEnvNoArity fullyQualified id.idText nenv let tcrefs = tcrefs |> List.map (fun tcref -> (resInfo,tcref)) - let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, TypeNameResolutionInfo.ResolveToTypeRefs (TypeNameResolutionStaticArgsInfo.Indefinite), PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) + let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, TypeNameResolutionInfo.ResolveToTypeRefs (TypeNameResolutionStaticArgsInfo.Indefinite), PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) ResolveLongIdentInTyconRefs ncenv nenv LookupKind.Expr 1 m ad rest typeNameResInfo id.idRange tcrefs - let envSearch = - match fullyQualified with - | FullyQualified -> - NoResultsOrUsefulErrors - | OpenQualified -> - match nenv.eUnqualifiedItems.TryFind id.idText with - | Some (Item.UnqualifiedType _) - | None -> NoResultsOrUsefulErrors - | Some res -> OneSuccess (resInfo,FreshenUnqualifiedItem ncenv m res,rest) + let search = + let moduleSearch = moduleSearch ad + + match moduleSearch with + | Result res when not (List.isEmpty res) -> moduleSearch + | _ -> + + let tyconSearch = tyconSearch ad - let search = moduleSearch ad +++ tyconSearch ad +++ envSearch + match tyconSearch with + | Result res when not (List.isEmpty res) -> tyconSearch + | _ -> + + let envSearch = + match fullyQualified with + | FullyQualified -> + NoResultsOrUsefulErrors + | OpenQualified -> + match nenv.eUnqualifiedItems.TryFind id.idText with + | Some (Item.UnqualifiedType _) + | None -> NoResultsOrUsefulErrors + | Some res -> OneSuccess (resInfo,FreshenUnqualifiedItem ncenv m res,rest) + + moduleSearch +++ tyconSearch +++ envSearch let resInfo,item,rest = match AtMostOneResult m search with | Result _ as res -> ForceRaise res - | _ -> - let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueNamespaceTypeOrModule,id,NoPredictions)) - ForceRaise (AtMostOneResult m (search +++ moduleSearch AccessibleFromSomeFSharpCode +++ tyconSearch AccessibleFromSomeFSharpCode +++ failingCase)) + | _ -> + let innerSearch = + let moduleSearch = moduleSearch AccessibleFromSomeFSharpCode + + match moduleSearch with + | Result res when not (List.isEmpty res) -> moduleSearch + | _ -> + + let tyconSearch = tyconSearch AccessibleFromSomeFSharpCode + + match tyconSearch with + | Result res when not (List.isEmpty res) -> tyconSearch + | _ -> + + let failingCase = raze (UndefinedName(0,FSComp.SR.undefinedNameValueNamespaceTypeOrModule,id,NoPredictions)) + + search +++ moduleSearch +++ tyconSearch +++ failingCase + + ForceRaise (AtMostOneResult m innerSearch) ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> CheckAllTyparsInferrable ncenv.amap m item)) item,rest From 868c5168b8bb1576d3e153fd798b41079559a0a0 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Sun, 4 Sep 2016 10:36:52 +0200 Subject: [PATCH 11/11] Remove predictions --- src/fsharp/NameResolution.fs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 21c9a3d014a..2d708042681 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -1866,7 +1866,7 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo | Some ucase -> success(resInfo,Item.UnionCase(ucase,false),rest) | None -> - let isLookUpExpr = match lookupKind with LookupKind.Expr -> true | _ -> false + let isLookUpExpr = lookupKind = LookupKind.Expr match TryFindIntrinsicNamedItemOfType ncenv.InfoReader (nm,ad) findFlag m typ with | Some (PropertyItem psets) when isLookUpExpr -> let pinfos = psets |> ExcludeHiddenOfPropInfos g ncenv.amap m @@ -2283,13 +2283,7 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num else NoResultsOrUsefulErrors match tyconSearch +++ ctorSearch +++ moduleSearch with - | Result [] -> - let predictedPossibleTypes = - modref.ModuleOrNamespaceType.AllEntities - |> Seq.map (fun e -> e.DisplayName) - |> Set.ofSeq - - raze (UndefinedName(depth,FSComp.SR.undefinedNameConstructorModuleOrNamespace,id,predictedPossibleTypes)) + | Result [] -> raze (UndefinedName(depth,FSComp.SR.undefinedNameConstructorModuleOrNamespace,id,NoPredictions)) | results -> AtMostOneResult id.idRange results /// Used to report a warning condition for the use of upper-case identifiers in patterns