bool Handle(TemplateTypeParameter p, ISemantic arg) { // if no argument given, try to handle default arguments if (arg == null) { return(TryAssignDefaultType(p)); } // If no spezialization given, assign argument immediately if (p.Specialization == null) { return(Set(p, arg, 0)); } bool handleResult = HandleDecl(null, p.Specialization, arg); if (!handleResult) { return(false); } // Apply the entire argument to parameter p if there hasn't been no explicit association yet TemplateParameterSymbol tps; if (!TargetDictionary.TryGetValue(p, out tps) || tps == null) { TargetDictionary[p] = new TemplateParameterSymbol(p, arg); } return(true); }
/// <summary> /// Returns false if the item has already been set before and if the already set item is not equal to 'r'. /// Inserts 'r' into the target dictionary and returns true otherwise. /// </summary> bool Set(ITemplateParameter p, ISemantic r, string name = null) { if (string.IsNullOrEmpty(name)) { name = p.Name; } TemplateParameterSymbol rl = null; if (!TargetDictionary.TryGetValue(name, out rl) || rl == null) { TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner); return(true); } else { if (rl != null) { if (ResultComparer.IsEqual(rl.Base, r)) { return(true); } else { // Error: Ambiguous assignment } } TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner); return(false); } }
public bool HandleDecl(TemplateTypeParameter p, ITypeDeclaration td, ISemantic rr) { if (td is IdentifierDeclaration) { return(HandleDecl(p, (IdentifierDeclaration)td, rr)); } if (TemplateInstanceHandler.IsNonFinalArgument(rr)) { foreach (var tp in this.TargetDictionary.Keys.ToList()) { if (TargetDictionary[tp] == null) { TargetDictionary[tp] = new TemplateParameterSymbol(tp, null); } } return(true); } //HACK Ensure that no information gets lost by using this function // -- getting a value but requiring an abstract type and just extract it from the value - is this correct behaviour? var at = AbstractType.Get(rr); if (td is ArrayDecl) { return(HandleDecl(p, (ArrayDecl)td, DResolver.StripMemberSymbols(at) as AssocArrayType)); } else if (td is DTokenDeclaration) { return(HandleDecl((DTokenDeclaration)td, at)); } else if (td is DelegateDeclaration) { return(HandleDecl(p, (DelegateDeclaration)td, DResolver.StripMemberSymbols(at) as DelegateType)); } else if (td is PointerDecl) { return(HandleDecl(p, (PointerDecl)td, DResolver.StripMemberSymbols(at) as PointerType)); } else if (td is MemberFunctionAttributeDecl) { return(HandleDecl(p, (MemberFunctionAttributeDecl)td, at)); } else if (td is TypeOfDeclaration) { return(HandleDecl((TypeOfDeclaration)td, at)); } else if (td is VectorDeclaration) { return(HandleDecl((VectorDeclaration)td, at)); } else if (td is TemplateInstanceExpression) { return(HandleDecl(p, (TemplateInstanceExpression)td, at)); } return(false); }
/// <summary> /// Returns false if the item has already been set before and if the already set item is not equal to 'r'. /// Inserts 'r' into the target dictionary and returns true otherwise. /// </summary> bool Set(TemplateParameter p, ISemantic r, int nameHash) { if (p == null) { if (nameHash != 0 && TargetDictionary.ExpectedParameters != null) { foreach (var tpar in TargetDictionary.ExpectedParameters) { if (tpar.NameHash == nameHash) { p = tpar; break; } } } } if (p == null) { ctxt.LogError(null, "no fitting template parameter found!"); return(false); } // void call(T)(T t) {} // call(myA) -- T is *not* myA but A, so only assign myA's type to T. if (p is TemplateTypeParameter) { var newR = Resolver.TypeResolution.DResolver.StripMemberSymbols(AbstractType.Get(r)); if (newR != null) { r = newR; } } TemplateParameterSymbol rl; if (!TargetDictionary.TryGetValue(p, out rl) || rl == null) { TargetDictionary[p] = new TemplateParameterSymbol(p, r); return(true); } else { if (ResultComparer.IsEqual(rl.Base, r)) { TargetDictionary[p] = new TemplateParameterSymbol(p, r); return(true); } else if (rl == null) { TargetDictionary[p] = new TemplateParameterSymbol(p, r); } // Error: Ambiguous assignment return(false); } }
public static AbstractType[] ResolveIdentifier(string id, ResolverContextStack ctxt, object idObject, bool ModuleScope = false) { var loc = idObject is ISyntaxRegion ? ((ISyntaxRegion)idObject).Location:CodeLocation.Empty; if (ModuleScope) { ctxt.PushNewScope(ctxt.ScopedBlock.NodeRoot as IAbstractSyntaxTree); } // If there are symbols that must be preferred, take them instead of scanning the ast else { var tstk = new Stack <ResolverContext>(); D_Parser.Resolver.Templates.TemplateParameterSymbol dedTemplateParam = null; while (!ctxt.CurrentContext.DeducedTemplateParameters.TryGetValue(id, out dedTemplateParam)) { if (ctxt.PrevContextIsInSameHierarchy) { tstk.Push(ctxt.Pop()); } else { break; } } while (tstk.Count > 0) { ctxt.Push(tstk.Pop()); } if (dedTemplateParam != null) { return new[] { dedTemplateParam } } ; } var matches = NameScan.SearchMatchesAlongNodeHierarchy(ctxt, loc, id); var res = HandleNodeMatches(matches, ctxt, null, idObject); if (ModuleScope) { ctxt.Pop(); } return(res); }