/// <summary> /// Used for searching further identifier list parts. /// /// a.b -- nextIdentifier would be 'b' whereas <param name="resultBases">resultBases</param> contained the resolution result for 'a' /// </summary> public static AbstractType[] ResolveFurtherTypeIdentifier(int nextIdentifierHash, IEnumerable <AbstractType> resultBases, ResolutionContext ctxt, ISyntaxRegion typeIdObject = null) { MemberSymbol statProp; if ((resultBases = DResolver.StripMemberSymbols(resultBases)) == null) { return(null); } var r = new List <AbstractType>(); foreach (var b in resultBases) { if (b is UserDefinedType) { var udt = b as UserDefinedType; var bn = udt.Definition as IBlockNode; bool pop = b is MixinTemplateType; if (pop) { ctxt.PushNewScope(bn); } ctxt.CurrentContext.IntroduceTemplateParameterTypes(udt); r.AddRange(SingleNodeNameScan.SearchChildrenAndResolve(ctxt, udt, nextIdentifierHash, typeIdObject)); List <TemplateParameterSymbol> dedTypes = null; foreach (var t in r) { var ds = t as DSymbol; if (ds != null && ds.DeducedTypes == null) { if (dedTypes == null) { dedTypes = ctxt.DeducedTypesInHierarchy; } ds.DeducedTypes = new System.Collections.ObjectModel.ReadOnlyCollection <TemplateParameterSymbol>(dedTypes); } } statProp = StaticProperties.TryEvalPropertyType(ctxt, b, nextIdentifierHash); if (statProp != null) { r.Add(statProp); } // go the opDispatch way if possible - http://dlang.org/operatoroverloading.html#Dispatch if (r.Count == 0 && nextIdentifierHash != OpDispatchResolution.opDispatchId) { r.AddRange(OpDispatchResolution.TryResolveFurtherIdViaOpDispatch(ctxt, nextIdentifierHash, udt)); } if (r.Count == 0) { r.AddRange(UFCSResolver.TryResolveUFCS(b, nextIdentifierHash, !pop && typeIdObject != null ? typeIdObject.Location : ctxt.ScopedBlock.BlockStartLocation, ctxt, typeIdObject)); } if (pop) { ctxt.Pop(); } else { ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt); } } else if (b is PackageSymbol) { var pack = (b as PackageSymbol).Package; var accessedModule = pack.GetModule(nextIdentifierHash); if (accessedModule != null) { r.Add(new ModuleSymbol(accessedModule as DModule, typeIdObject as ISyntaxRegion, b as PackageSymbol)); } else if ((pack = pack.GetPackage(nextIdentifierHash)) != null) { r.Add(new PackageSymbol(pack, typeIdObject as ISyntaxRegion)); } } else if (b is ModuleSymbol) { r.AddRange(SingleNodeNameScan.SearchChildrenAndResolve(ctxt, b as ModuleSymbol, nextIdentifierHash, typeIdObject)); } else { statProp = StaticProperties.TryEvalPropertyType(ctxt, b, nextIdentifierHash); if (statProp != null) { r.Add(statProp); } if (r.Count == 0) // Only if there hasn't been a result yet? { r.AddRange(UFCSResolver.TryResolveUFCS(b, nextIdentifierHash, typeIdObject != null ? typeIdObject.Location : ctxt.ScopedBlock.BlockStartLocation, ctxt, typeIdObject)); } } } return(r.Count == 0 ? null : r.ToArray()); }
/// <summary> /// Used for searching further identifier list parts. /// /// a.b -- nextIdentifier would be 'b' whereas <param name="resultBases">resultBases</param> contained the resolution result for 'a' /// </summary> public static AbstractType[] ResolveFurtherTypeIdentifier(int nextIdentifierHash, IEnumerable <AbstractType> resultBases, ResolutionContext ctxt, object typeIdObject = null) { MemberSymbol statProp; if ((resultBases = DResolver.StripMemberSymbols(resultBases)) == null) { return(null); } var r = new List <AbstractType>(); foreach (var b in resultBases) { if (b is UserDefinedType) { var udt = b as UserDefinedType; var bn = udt.Definition as IBlockNode; bool pop = !(b is MixinTemplateType); if (!pop) { ctxt.PushNewScope(bn); } ctxt.CurrentContext.IntroduceTemplateParameterTypes(udt); r.AddRange(SingleNodeNameScan.SearchChildrenAndResolve(ctxt, bn, nextIdentifierHash, typeIdObject)); List <TemplateParameterSymbol> dedTypes = null; foreach (var t in r) { var ds = t as DSymbol; if (ds != null && ds.DeducedTypes == null) { if (dedTypes == null) { dedTypes = ctxt.DeducedTypesInHierarchy; } ds.DeducedTypes = new System.Collections.ObjectModel.ReadOnlyCollection <TemplateParameterSymbol>(dedTypes); } } statProp = StaticProperties.TryEvalPropertyType(ctxt, b, nextIdentifierHash); if (statProp != null) { r.Add(statProp); } ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt); if (!pop) { ctxt.Pop(); } } else if (b is PackageSymbol) { var pack = (b as PackageSymbol).Package; var accessedModule = pack.GetModule(nextIdentifierHash); if (accessedModule != null) { r.Add(new ModuleSymbol(accessedModule as DModule, typeIdObject as ISyntaxRegion, b as PackageSymbol)); } else if ((pack = pack.GetPackage(nextIdentifierHash)) != null) { r.Add(new PackageSymbol(pack, typeIdObject as ISyntaxRegion)); } } else if (b is ModuleSymbol) { r.AddRange(SingleNodeNameScan.SearchChildrenAndResolve(ctxt, (b as ModuleSymbol).Definition, nextIdentifierHash, typeIdObject)); } else { statProp = StaticProperties.TryEvalPropertyType(ctxt, b, nextIdentifierHash); if (statProp != null) { r.Add(statProp); } } // TODO: Search for UFCS symbols } return(r.Count == 0 ? null : r.ToArray()); }