static AbstractType[] TryGetImplicitProperty(TemplateType template, ResolutionContext ctxt) { // Get actual overloads var matchingChild = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(template.NameHash, new[] { template }, ctxt, template.DeclarationOrExpressionBase, false); if (matchingChild != null) // Currently requried for proper UFCS resolution - sustain template's Tag { foreach (var ch in matchingChild) { var ds = ch as DSymbol; if (ds != null) { var newDeducedTypes = new DeducedTypeDictionary(ds); foreach (var tps in template.DeducedTypes) { newDeducedTypes[tps.Parameter] = tps; } ds.DeducedTypes = newDeducedTypes.ToReadonly(); } ch.Tag = template.Tag; } } return(matchingChild); }
/// <summary> /// http://dlang.org/operatoroverloading.html#Dispatch /// Check for the existence of an opDispatch overload. /// Important: Because static opDispatches are allowed as well, do check whether we can access non-static overloads from non-instance expressions or such /// </summary> public static IEnumerable <AbstractType> TryResolveFurtherIdViaOpDispatch(ResolutionContext ctxt, int nextIdentifierHash, UserDefinedType b) { // The usual SO prevention if (nextIdentifierHash == opDispatchId || b == null) { yield break; } var pop = ctxt.ScopedBlock != b.Definition; if (pop) { // Mainly required for not resolving opDispatch's return type, as this will be performed later on in higher levels var opt = ctxt.CurrentContext.ContextDependentOptions; ctxt.PushNewScope(b.Definition as IBlockNode); ctxt.CurrentContext.IntroduceTemplateParameterTypes(b); ctxt.CurrentContext.ContextDependentOptions = opt; } // Look for opDispatch-Members inside b's Definition var overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(opDispatchId, new[] { b }, ctxt); if (pop) { ctxt.Pop(); } if (overloads == null || overloads.Length < 0) { yield break; } var av = new ArrayValue(Evaluation.GetStringType(ctxt), Strings.TryGet(nextIdentifierHash)); foreach (DSymbol o in overloads) { var dn = o.Definition; if (dn.TemplateParameters != null && dn.TemplateParameters.Length > 0 && dn.TemplateParameters[0] is TemplateValueParameter) { //TODO: Test parameter types for being a string value o.DeducedTypes = new System.Collections.ObjectModel.ReadOnlyCollection <TemplateParameterSymbol> ( new[] { new TemplateParameterSymbol(dn.TemplateParameters[0], av) }); yield return(o); } } }
static AbstractType[] TryGetImplicitProperty(TemplateType template, ResolutionContext ctxt) { // Prepare a new context bool pop = !ctxt.ScopedBlockIsInNodeHierarchy(template.Definition); if (pop) { ctxt.PushNewScope(template.Definition); } // Introduce the deduced params to the current resolution context ctxt.CurrentContext.IntroduceTemplateParameterTypes(template); // Get actual overloads var matchingChild = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(template.NameHash, new[] { template }, ctxt); if (matchingChild != null) // Currently requried for proper UFCS resolution - sustain template's Tag { foreach (var ch in matchingChild) { var ds = ch as DSymbol; if (ds != null) { var newDeducedTypes = new DeducedTypeDictionary(ds); foreach (var tps in template.DeducedTypes) { newDeducedTypes[tps.Parameter] = tps; } ds.DeducedTypes = newDeducedTypes.ToReadonly(); } ch.Tag = template.Tag; } } // Undo context-related changes if (pop) { ctxt.Pop(); } else { ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(template); } return(matchingChild); }