ISemantic E(TemplateInstanceExpression tix, bool ImplicitlyExecute = true) { var o = DResolver.StripAliasSymbols(GetOverloads(tix, ctxt)); if (eval) { return(TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute)); } else { ctxt.CheckForSingleResult(o, tix); if (o != null) { if (o.Length == 1) { return(o[0]); } else if (o.Length > 1) { return(new InternalOverloadValue(o, tix)); } } return(null); } }
DNode[] ResolveTemplateInstanceId(TemplateInstanceExpression tix) { /* * Again a very unclear/buggy situation: * When having a cascaded tix as parameter, it uses the left-most part (i.e. the inner most) of the typedeclaration construct. * * class C(A!X.SubClass, X) {} can be instantiated via C!(A!int), but not via C!(A!int.SubClass) - totally confusing * (dmd v2.060) */ if (tix.InnerDeclaration != null) { if (tix.InnerMost is TemplateInstanceExpression) { tix = (TemplateInstanceExpression)tix.InnerMost; } else { return(new DNode[0]); } } var optBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions = ResolutionOptions.DontResolveBaseClasses | ResolutionOptions.DontResolveBaseTypes | ResolutionOptions.StopAfterFirstOverloads; var initialResults = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdentifier.Id, ctxt, tix); var l = _handleResStep(initialResults); ctxt.CurrentContext.ContextDependentOptions = optBackup; return(l.ToArray()); }
public static AbstractType[] DeduceParamsAndFilterOverloads(IEnumerable<AbstractType> rawOverloadList, TemplateInstanceExpression templateInstanceExpr, ResolutionContext ctxt, bool isMethodCall = false) { bool hasUndeterminedArgs; var args = PreResolveTemplateArgs(templateInstanceExpr, ctxt, out hasUndeterminedArgs); return DeduceParamsAndFilterOverloads(rawOverloadList, args, isMethodCall, ctxt, hasUndeterminedArgs); }
public ISymbolValue Visit(TemplateInstanceExpression tix) { var ImplicitlyExecute = this.ImplicitlyExecute; this.ImplicitlyExecute = true; return(TryDoCTFEOrGetValueRefs(AmbiguousType.Get(ExpressionTypeEvaluation.GetOverloads(tix, ctxt), tix), tix, ImplicitlyExecute)); }
public static AbstractType[] DeduceParamsAndFilterOverloads(IEnumerable <AbstractType> rawOverloadList, TemplateInstanceExpression templateInstanceExpr, ResolutionContext ctxt, bool isMethodCall = false) { var args = PreResolveTemplateArgs(templateInstanceExpr, ctxt); return(DeduceParamsAndFilterOverloads(rawOverloadList, args, isMethodCall, ctxt)); }
public override void Visit(TemplateInstanceExpression x) { if (DoPrimaryIdCheck(x.TemplateIdHash)) { AddResult(x); } base.Visit(x); }
public ISymbolValue Visit(TemplateInstanceExpression tix) { var ImplicitlyExecute = this.ImplicitlyExecute; this.ImplicitlyExecute = true; var o = DResolver.StripAliasSymbols(ExpressionTypeEvaluation.GetOverloads(tix, ctxt)); return TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute); }
ITypeDeclaration QualifiedName() { ITypeDeclaration td = null; int n; while (PeekIsDecNumber) { // Read number of either the first LName or TemplateInstanceName n = (int)Number(); sb.Clear(); if ((char)r.Peek() == '_') { r.Read(); sb.Append('_'); if ((char)r.Peek() == '_') { r.Read(); sb.Append('_'); if ((char)r.Peek() == 'T') { r.Read(); // We've got to handle a Template instance: // Number __T LName TemplateArgs Z var tpi = new TemplateInstanceExpression(new IdentifierDeclaration(LName())); tpi.InnerDeclaration = td; td = tpi; var xx = new List <IExpression>(); while (r.Peek() != -1) { var arg = TemplateArg(); if (arg == null) { break; } xx.Add(arg); } tpi.Arguments = xx.ToArray(); continue; } } } // Just an LName if (n > sb.Length) { sb.Append(LName(n - sb.Length)); } var ttd = new IdentifierDeclaration(sb.ToString()); ttd.InnerDeclaration = td; td = ttd; } return(td); }
public static List <ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolverContextStack ctxt) { // Resolve given argument expressions var templateArguments = new List <ISemantic>(); if (tix != null && tix.Arguments != null) { foreach (var arg in tix.Arguments) { if (arg is TypeDeclarationExpression) { var tde = (TypeDeclarationExpression)arg; var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt); if (ctxt.CheckForSingleResult(res, tde.Declaration) || res != null) { var mr = res[0] as MemberSymbol; if (mr != null && mr.Definition is DVariable) { var dv = (DVariable)mr.Definition; if (dv.IsAlias || dv.Initializer == null) { templateArguments.Add(mr); continue; } ISemantic eval = null; try { eval = new StandardValueProvider(ctxt)[dv]; } catch (System.Exception ee) // Should be a non-const-expression error here only { ctxt.LogError(dv.Initializer, ee.Message); } templateArguments.Add(eval == null ? (ISemantic)mr : eval); } else { templateArguments.Add(res[0]); } } } else { templateArguments.Add(Evaluation.EvaluateValue(arg, ctxt)); } } } return(templateArguments); }
public ISymbolValue Visit(TemplateInstanceExpression tix) { var ImplicitlyExecute = this.ImplicitlyExecute; this.ImplicitlyExecute = true; var o = DResolver.StripAliasSymbols(ExpressionTypeEvaluation.GetOverloads(tix, ctxt)); return(TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute)); }
public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolverContextStack ctxt, IEnumerable<AbstractType> resultBases = null, bool deduceParameters = true) { AbstractType[] res = null; if (resultBases == null) res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdentifier.Id, ctxt, tix, tix.TemplateIdentifier.ModuleScoped); else res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdentifier.Id, resultBases, ctxt, tix); return !ctxt.Options.HasFlag(ResolutionOptions.NoTemplateParameterDeduction) && deduceParameters ? TemplateInstanceHandler.EvalAndFilterOverloads(res, tix, ctxt) : res; }
public override void Visit(TemplateInstanceExpression x) { byte type; if (DoPrimaryIdCheck(x.TemplateIdHash, out type)) { AddResult(x, type); } base.Visit(x); }
public override void Visit(TemplateInstanceExpression id) { if (id.TemplateIdHash == searchHash) { ctxt.CurrentContext.Set(id.Location); if (TryAdd(ExpressionTypeEvaluation.EvaluateType(id, ctxt, false), id)) { return; } } }
ISemantic E(TemplateInstanceExpression tix, bool ImplicitlyExecute = true) { var o = DResolver.StripAliasSymbols(GetOverloads(tix, ctxt)); if (eval) return TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute); else { ctxt.CheckForSingleResult(o, tix); if (o != null && o.Length == 1) return o[0]; return null; } }
public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolutionContext ctxt, IEnumerable<AbstractType> resultBases = null, bool deduceParameters = true) { if(resultBases == null && tix.InnerDeclaration != null) resultBases = TypeDeclarationResolver.Resolve(tix.InnerDeclaration, ctxt); AbstractType[] res; if (resultBases == null) res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdHash, ctxt, tix, tix.ModuleScopedIdentifier); else res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdHash, resultBases, ctxt, tix); return (ctxt.Options & ResolutionOptions.NoTemplateParameterDeduction) == 0 && deduceParameters ? TemplateInstanceHandler.DeduceParamsAndFilterOverloads(res, tix, ctxt) : res; }
public static List<ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolverContextStack ctxt) { // Resolve given argument expressions var templateArguments = new List<ISemantic>(); if (tix != null && tix.Arguments!=null) foreach (var arg in tix.Arguments) { if (arg is TypeDeclarationExpression) { var tde = (TypeDeclarationExpression)arg; var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt); if (ctxt.CheckForSingleResult(res, tde.Declaration) || res != null) { var mr = res[0] as MemberSymbol; if (mr != null && mr.Definition is DVariable) { var dv = (DVariable)mr.Definition; if (dv.IsAlias || dv.Initializer == null) { templateArguments.Add(mr); continue; } ISemantic eval = null; try { eval = new StandardValueProvider(ctxt)[dv]; } catch(System.Exception ee) // Should be a non-const-expression error here only { ctxt.LogError(dv.Initializer, ee.Message); } templateArguments.Add(eval==null ? (ISemantic)mr : eval); } else templateArguments.Add(res[0]); } } else templateArguments.Add(Evaluation.EvaluateValue(arg, ctxt)); } return templateArguments; }
public virtual void Visit(TemplateInstanceExpression x) { if (x.Identifier != null) { x.Identifier.Accept(this); } if (x.Arguments != null) { foreach (var arg in x.Arguments) { arg.Accept(this); } } }
public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolverContextStack ctxt, IEnumerable <AbstractType> resultBases = null, bool deduceParameters = true) { AbstractType[] res = null; if (resultBases == null) { res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdentifier.Id, ctxt, tix, tix.TemplateIdentifier.ModuleScoped); } else { res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdentifier.Id, resultBases, ctxt, tix); } return(!ctxt.Options.HasFlag(ResolutionOptions.NoTemplateParameterDeduction) && deduceParameters? TemplateInstanceHandler.DeduceParamsAndFilterOverloads(res, tix, ctxt) : res); }
ITypeDeclaration VisitDSymbol(DSymbol t) { var def = t.Definition; ITypeDeclaration td = new IdentifierDeclaration(def != null ? def.NameHash : 0); if (def != null && t.DeducedTypes != null && def.TemplateParameters != null) { var args = new List <IExpression>(); foreach (var tp in def.TemplateParameters) { IExpression argEx = null; foreach (var tps in t.DeducedTypes) { if (tps != null && tps.Parameter == tp) { if (tps.ParameterValue != null) { //TODO: Convert ISymbolValues back to IExpression } else { argEx = new TypeDeclarationExpression(AcceptType(tps)); } break; } } args.Add(argEx ?? new IdentifierExpression(tp.NameHash)); } td = new TemplateInstanceExpression(td) { Arguments = args.ToArray() }; } var ret = td; while (def != null && def != (def = def.Parent as DNode) && def != null && !(def is DModule)) { td = td.InnerDeclaration = new IdentifierDeclaration(def.NameHash); } return(ret); }
public void Visit(TemplateInstanceExpression tix) { res.IsTemplateInstanceArguments = true; res.MethodIdentifier = tix; ctxt.ContextIndependentOptions = ResolutionOptions.NoTemplateParameterDeduction; res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, null, false); if (tix.Arguments != null) { res.CurrentlyTypedArgumentIndex = tix.Arguments.Length; } else { res.CurrentlyTypedArgumentIndex = 0; } }
public AbstractType Visit(TemplateInstanceExpression tix) { var o = DResolver.StripAliasSymbols(GetOverloads(tix, ctxt)); ctxt.CheckForSingleResult(o, tix); if (o != null) { if (o.Length == 1) { return(o[0]); } else if (o.Length > 1) { return(new AmbiguousType(o)); } } return(null); }
public override void Visit(TemplateInstanceExpression tix) { var resolvedSymbol = TryPopPFAStack(); if (tix.TemplateIdHash == searchHash) { if (resolvedSymbol == null) { resolvedSymbol = Evaluation.EvaluateType(tix, ctxt) as DSymbol; } if (resolvedSymbol != null && resolvedSymbol.Definition == symbol) { l.Add(tix); return; } } base.Visit(tix); }
void GetRawCallOverloads(ResolutionContext ctxt, IExpression callForeExpression, out AbstractType[] baseExpression, out TemplateInstanceExpression tix) { tix = null; if (callForeExpression is PostfixExpression_Access) { var pac = (PostfixExpression_Access)callForeExpression; tix = pac.AccessExpression as TemplateInstanceExpression; baseExpression = Evaluation.EvalPostfixAccessExpression(this, ctxt, pac, null, false, false); } else { // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one var optBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes; if (callForeExpression is TokenExpression) { baseExpression = ExpressionTypeEvaluation.GetResolvedConstructorOverloads((TokenExpression)callForeExpression, ctxt); } else { if (callForeExpression is TemplateInstanceExpression) { baseExpression = ExpressionTypeEvaluation.GetOverloads(tix = (TemplateInstanceExpression)callForeExpression, ctxt, null, false); } else if (callForeExpression is IdentifierExpression) { baseExpression = ExpressionTypeEvaluation.GetOverloads(callForeExpression as IdentifierExpression, ctxt, deduceParameters: false); } else { baseExpression = new[] { callForeExpression != null?AbstractType.Get(callForeExpression.Accept(this)) : null } }; } ctxt.CurrentContext.ContextDependentOptions = optBackup; } }
public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolutionContext ctxt, IEnumerable <AbstractType> resultBases = null, bool deduceParameters = true) { if (resultBases == null && tix.InnerDeclaration != null) { resultBases = TypeDeclarationResolver.Resolve(tix.InnerDeclaration, ctxt); } AbstractType[] res; if (resultBases == null) { res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdHash, ctxt, tix, tix.ModuleScopedIdentifier); } else { res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdHash, resultBases, ctxt, tix); } return((ctxt.Options & ResolutionOptions.NoTemplateParameterDeduction) == 0 && deduceParameters? TemplateInstanceHandler.DeduceParamsAndFilterOverloads(res, tix, ctxt) : res); }
static void HandleTemplateInstance(TemplateInstanceExpression tix, ArgumentsResolutionResult res, IEditorData Editor, ResolutionContext ctxt, IBlockNode curBlock, IEnumerable <AbstractType> resultBases = null) { res.IsTemplateInstanceArguments = true; res.MethodIdentifier = tix; res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, resultBases, false); if (tix.Arguments != null) { res.CurrentlyTypedArgumentIndex = tix.Arguments.Length; } else { res.CurrentlyTypedArgumentIndex = 0; } }
public TemplateInstanceExpression TemplateInstance() { if (!Expect(Identifier)) return null; var td = new TemplateInstanceExpression() { TemplateIdentifier = new IdentifierDeclaration(t.Value) { Location=t.Location, EndLocation=t.EndLocation }, Location = t.Location }; LastParsedObject = td; var args = new List<IExpression>(); if (!Expect(Not)) return td; if (laKind == (OpenParenthesis)) { Step(); if (laKind != CloseParenthesis) { bool init = true; while (init || laKind == (Comma)) { if (!init) Step(); init = false; if (IsAssignExpression()) args.Add(AssignExpression()); else args.Add(new TypeDeclarationExpression(Type())); } } Expect(CloseParenthesis); } else { Step(); if (t.Kind == Literal) args.Add(new IdentifierExpression(t.LiteralValue, LiteralFormat.Scalar)); else if (t.Kind == Identifier) args.Add(new IdentifierExpression(t.Value)); else args.Add(new TokenExpression(t.Kind)); } td.Arguments = args.ToArray(); td.EndLocation = t.EndLocation; return td; }
bool HandleDecl(TemplateTypeParameter parameter, TemplateInstanceExpression tix, AbstractType r) { /* * TODO: Scan down r for having at least one templateinstanceexpression as declaration base. * If a tix was found, check if the definition of the respective result base level * and the un-aliased identifier of the 'tix' parameter match. * Attention: if the alias represents an undeduced type (i.e. a type bundle of equally named type nodes), * it is only important that the definition is inside this bundle. * Therefore, it's needed to manually resolve the identifier, and look out for aliases or such unprecise aliases..confusing as s**t! * * If the param tix id is part of the template param list, the behaviour is currently undefined! - so instantly return false, I'll leave it as TODO/FIXME */ var paramTix_TemplateMatchPossibilities = ResolveTemplateInstanceId(tix); TemplateIntermediateType tixBasedArgumentType = null; var r_ = r as DSymbol; while (r_ != null) { if (r_.DeclarationOrExpressionBase is TemplateInstanceExpression) { var tit = r_ as TemplateIntermediateType; if (tit != null && CheckForTixIdentifierEquality(paramTix_TemplateMatchPossibilities, tit.Definition)) { tixBasedArgumentType = tit; break; } } r_ = r_.Base as DSymbol; } /* * This part is very tricky: * I still dunno what is allowed over here-- * * class Foo(T:Bar!E[],E) {} * ... * Foo!(Bar!string[]) f; -- E will be 'string' then * * class DerivateBar : Bar!string[] {} -- new Foo!DerivateBar() is also allowed, but now DerivateBar * obviously is not a template instance expression - it's a normal identifier only. */ if (tixBasedArgumentType != null) { var argEnum_given = ((TemplateInstanceExpression)tixBasedArgumentType.DeclarationOrExpressionBase).Arguments.GetEnumerator(); foreach (var p in tix.Arguments) { if (!argEnum_given.MoveNext() || argEnum_given.Current == null) { return(false); } // Convert p to type declaration var param_Expected = ConvertToTypeDeclarationRoughly(p); if (param_Expected == null) { return(false); } var result_Given = ExpressionTypeEvaluation.EvaluateType(argEnum_given.Current as IExpression, ctxt); if (result_Given == null || !HandleDecl(parameter, param_Expected, result_Given)) { return(false); } } // Too many params passed.. if (argEnum_given.MoveNext()) { return(false); } return(true); } return(false); }
public override void Visit (TemplateInstanceExpression id) { if (id.TemplateIdHash == searchHash) { ctxt.CurrentContext.Set(id.Location); if (TryAdd(ExpressionTypeEvaluation.EvaluateType(id, ctxt, false), id)) return; } }
public TemplateInstanceExpression TemplateInstance() { if (!Expect(Identifier)) return null; var td = new TemplateInstanceExpression() { TemplateIdentifier = new IdentifierDeclaration(t.Value) { Location=t.Location, EndLocation=t.EndLocation }, Location = t.Location }; LastParsedObject = td; var args = new List<IExpression>(); if (!Expect(Not)) return td; if (laKind == (OpenParenthesis)) { Step(); if (laKind != CloseParenthesis) { bool init = true; while (laKind == Comma || init) { if (!init) Step(); init = false; if (IsEOF) { args.Add(new TokenExpression(DTokens.INVALID) { Location= la.Location, EndLocation=la.EndLocation }); break; } var la_Backup = la; bool wp = AllowWeakTypeParsing; AllowWeakTypeParsing = true; var typeArg = Type(); AllowWeakTypeParsing = wp; if (typeArg != null && (laKind == CloseParenthesis || laKind==Comma)) args.Add(new TypeDeclarationExpression(typeArg)); else { la = la_Backup; Peek(1); args.Add(AssignExpression()); } } } Expect(CloseParenthesis); } else { Step(); /* * TemplateSingleArgument: * Identifier * BasicTypeX * CharacterLiteral * StringLiteral * IntegerLiteral * FloatLiteral * true * false * null * __FILE__ * __LINE__ */ IExpression arg= null; if (t.Kind == Literal) arg = new IdentifierExpression(t.LiteralValue, LiteralFormat.Scalar) { Location = t.Location, EndLocation = t.EndLocation }; else if (t.Kind == Identifier) arg = new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation }; else if (BasicTypes[t.Kind]) arg = new TypeDeclarationExpression(new DTokenDeclaration(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }); else if ( t.Kind == True || t.Kind == False || t.Kind == Null || t.Kind == __FILE__ || t.Kind == __LINE__) arg = new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; else if (IsEOF) { ExpectingIdentifier = false; return td; } args.Add(arg); } td.Arguments = args.ToArray(); td.EndLocation = t.EndLocation; return td; }
void GetRawCallOverloads(ResolutionContext ctxt, PostfixExpression_MethodCall call, out AbstractType[] baseExpression, out ISymbolValue baseValue, out TemplateInstanceExpression tix) { baseValue = null; tix = null; if (call.PostfixForeExpression is PostfixExpression_Access) { var pac = (PostfixExpression_Access)call.PostfixForeExpression; tix = pac.AccessExpression as TemplateInstanceExpression; var vs = EvalPostfixAccessExpression(this, ctxt, pac, null, false, false); baseExpression = TypeDeclarationResolver.Convert(vs); } else { // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one var optBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes; if (call.PostfixForeExpression is TokenExpression) { baseExpression = ExpressionTypeEvaluation.GetResolvedConstructorOverloads((TokenExpression)call.PostfixForeExpression, ctxt); } else { var fore = call.PostfixForeExpression; if (fore is TemplateInstanceExpression) { ImplicitlyExecute = false; tix = call.PostfixForeExpression as TemplateInstanceExpression; } else if (fore is IdentifierExpression) { ImplicitlyExecute = false; } if (call.PostfixForeExpression != null) { baseValue = call.PostfixForeExpression.Accept(this) as ISymbolValue; } if (baseValue is InternalOverloadValue) { baseExpression = ((InternalOverloadValue)baseValue).Overloads; } else if (baseValue != null) { baseExpression = new[] { baseValue.RepresentedType } } ; else { baseExpression = null; } } ctxt.CurrentContext.ContextDependentOptions = optBackup; } }
public override void Visit(TemplateInstanceExpression x) { byte type; if (DoPrimaryIdCheck(x.TemplateIdHash, out type)) AddResult(x, type); base.Visit (x); }
public static AbstractType[] DeduceParamsAndFilterOverloads(IEnumerable <AbstractType> rawOverloadList, TemplateInstanceExpression templateInstanceExpr, ResolverContextStack ctxt) { return(DeduceParamsAndFilterOverloads(rawOverloadList, PreResolveTemplateArgs(templateInstanceExpr, ctxt), false, ctxt)); }
public AbstractType Visit(TemplateInstanceExpression tix) { return(TryPretendMethodExecution(AmbiguousType.Get(GetOverloads(tix, ctxt), tix))); }
ISemantic E(PostfixExpression_MethodCall call, bool returnBaseTypeOnly = true) { // Deduce template parameters later on AbstractType[] baseExpression = null; ISymbolValue baseValue = null; TemplateInstanceExpression tix = null; bool isUFCSFunction = false; GetRawCallOverloads(call, out baseExpression, out baseValue, out tix, out isUFCSFunction); var methodOverloads = new List <AbstractType>(); #region Search possible methods, opCalls or delegates that could be called bool requireStaticItems = true; //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit IEnumerable <AbstractType> scanResults = DResolver.StripAliasSymbols(baseExpression); var nextResults = new List <AbstractType>(); while (scanResults != null) { foreach (var b in scanResults) { if (b is MemberSymbol) { var mr = (MemberSymbol)b; if (mr.Definition is DMethod) { methodOverloads.Add(mr); continue; } else if (mr.Definition is DVariable) { // If we've got a variable here, get its base type/value reference if (eval) { var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue; if (dgVal != null) { nextResults.Add(dgVal.Definition); continue; } else { throw new EvaluationException(call, "Variable must be a delegate, not anything else", mr); } } else { var bt = DResolver.StripAliasSymbol(mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt)); // Must be of type delegate if (bt is DelegateType) { //TODO: Ensure that there's no further overload - inform the user elsewise if (returnBaseTypeOnly) { return(bt); } else { return(new MemberSymbol(mr.Definition, bt, mr.DeclarationOrExpressionBase)); } } else { /* * If mr.Node is not a method, so e.g. if it's a variable * pointing to a delegate * * class Foo * { * string opCall() { return "asdf"; } * } * * Foo f=new Foo(); * f(); -- calls opCall, opCall is not static */ nextResults.Add(bt); requireStaticItems = false; } //TODO: Can other types work as function/are callable? } } } else if (b is DelegateType) { var dg = (DelegateType)b; /* * int a = delegate(x) { return x*2; } (12); // a is 24 after execution * auto dg=delegate(x) {return x*3;}; * int b = dg(4); */ if (dg.IsFunctionLiteral) { methodOverloads.Add(dg); } else { // If it's just wanted to pass back the delegate's return type, skip the remaining parts of this method. if (eval) { throw new EvaluationException(call, "TODO", dg); } //TODO //if(returnBaseTypeOnly) //TODO: Check for multiple definitions. Also, make a parameter-argument check to inform the user about wrong arguments. return(dg); } } else if (b is ClassType) { /* * auto a = MyStruct(); -- opCall-Overloads can be used */ var classDef = ((ClassType)b).Definition; if (classDef == null) { continue; } foreach (var i in classDef) { if (i.Name == "opCall" && i is DMethod && (!requireStaticItems || (i as DNode).IsStatic)) { methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol); } } } /* * Every struct can contain a default ctor: * * struct S { int a; bool b; } * * auto s = S(1,true); -- ok * auto s2= new S(2,false); -- error, no constructor found! */ else if (b is StructType && methodOverloads.Count == 0) { //TODO: Deduce parameters return(b); } /* * If the overload is a template, it quite exclusively means that we'll handle a method that is the only * child inside a template + that is named as the template. */ else if (b is TemplateType && ImplicitTemplateProperties.ContainsEquallyNamedChildrenOnly(((TemplateType)b).Definition)) { methodOverloads.Add(b); } } scanResults = nextResults.Count == 0 ? null : nextResults.ToArray(); nextResults.Clear(); } #endregion if (methodOverloads.Count == 0) { return(null); } // Get all arguments' types var callArguments = new List <ISemantic>(); // If it's sure that we got a ufcs call here, add the base expression's type as first argument type if (isUFCSFunction) { callArguments.Add(eval ? (ISemantic)baseValue : ((MemberSymbol)baseExpression[0]).Base); } if (call.Arguments != null) { foreach (var arg in call.Arguments) { callArguments.Add(E(arg)); } } #region Deduce template parameters and filter out unmatching overloads // First add optionally given template params // http://dlang.org/template.html#function-templates var tplParamDeductionArguments = tix == null ? new List <ISemantic>() : TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt); // Then add the arguments[' member types] foreach (var arg in callArguments) { if (arg is VariableValue) { tplParamDeductionArguments.Add(ValueProvider[((VariableValue)arg).Variable]); } else if (arg is AbstractType) { tplParamDeductionArguments.Add(DResolver.StripMemberSymbols((AbstractType)arg)); } else { tplParamDeductionArguments.Add(arg); } } var templateParamFilteredOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads( methodOverloads, tplParamDeductionArguments.Count > 0 ? tplParamDeductionArguments.ToArray() : null, true, ctxt); #endregion #region Filter by parameter-argument comparison var argTypeFilteredOverloads = new List <AbstractType>(); if (templateParamFilteredOverloads != null) { foreach (var ov in templateParamFilteredOverloads) { if (ov is MemberSymbol) { var ms = (MemberSymbol)ov; var dm = ms.Definition as DMethod; bool add = false; if (dm != null) { ctxt.CurrentContext.IntroduceTemplateParameterTypes(ms); add = false; if (callArguments.Count == 0 && dm.Parameters.Count == 0) { add = true; } else { for (int i = 0; i < dm.Parameters.Count; i++) { var paramType = TypeDeclarationResolver.ResolveSingle(dm.Parameters[i].Type, ctxt); // TODO: Expression tuples & variable argument lengths if (i >= callArguments.Count || !ResultComparer.IsImplicitlyConvertible(callArguments[i], paramType, ctxt)) { continue; } add = true; } } if (add) { var bt = ms.Base ?? TypeDeclarationResolver.GetMethodReturnType(dm, ctxt); if (returnBaseTypeOnly) { argTypeFilteredOverloads.Add(bt); } else { argTypeFilteredOverloads.Add(ms.Base == null ? new MemberSymbol(dm, bt, ms.DeclarationOrExpressionBase, ms.DeducedTypes) : ms); } } ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ms); } } else if (ov is DelegateType) { var dg = (DelegateType)ov; var bt = TypeDeclarationResolver.GetMethodReturnType(dg, ctxt); //TODO: Param-Arg check if (returnBaseTypeOnly) { argTypeFilteredOverloads.Add(bt); } else { argTypeFilteredOverloads.Add(new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters)); } } } } #endregion if (eval) { // Convert ISemantic[] to ISymbolValue[] var args = new List <ISymbolValue>(callArguments.Count); foreach (var a in callArguments) { args.Add(a as ISymbolValue); } // Execute/Evaluate the variable contents etc. return(TryDoCTFEOrGetValueRefs(argTypeFilteredOverloads.ToArray(), call.PostfixForeExpression, true, args.ToArray())); } else { // Check if one overload remains and return that one. ctxt.CheckForSingleResult(argTypeFilteredOverloads.ToArray(), call); return(argTypeFilteredOverloads != null && argTypeFilteredOverloads.Count != 0 ? argTypeFilteredOverloads[0] : null); } }
DNode[] ResolveTemplateInstanceId(TemplateInstanceExpression tix) { /* * Again a very unclear/buggy situation: * When having a cascaded tix as parameter, it uses the left-most part (i.e. the inner most) of the typedeclaration construct. * * class C(A!X.SubClass, X) {} can be instantiated via C!(A!int), but not via C!(A!int.SubClass) - totally confusing * (dmd v2.060) */ if (tix.InnerDeclaration != null) { if (tix.InnerMost is TemplateInstanceExpression) tix = (TemplateInstanceExpression)tix.InnerMost; else return new DNode[0]; } var optBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions = ResolutionOptions.DontResolveBaseClasses | ResolutionOptions.DontResolveBaseTypes; var initialResults = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdHash, ctxt, tix); var l = new List<DNode>(); foreach (var res in initialResults) if (res is DSymbol) l.Add((res as DSymbol).Definition); ctxt.CurrentContext.ContextDependentOptions = optBackup; return l.ToArray(); }
public override void Visit(TemplateInstanceExpression tix) { var resolvedSymbol = TryPopPFAStack (); if (tix.TemplateIdHash == searchHash) { if(resolvedSymbol == null) resolvedSymbol = ExpressionTypeEvaluation.EvaluateType(tix, ctxt, false) as DSymbol; if (resolvedSymbol != null && resolvedSymbol.Definition == symbol) { l.Add (tix); return; } } base.Visit (tix); }
public TemplateInstanceExpression TemplateInstance(IBlockNode Scope) { var loc = la.Location; var mod = INVALID; if (DTokens.StorageClass [laKind]) { mod = laKind; Step (); } if (!Expect (Identifier)) return null; ITypeDeclaration td = new IdentifierDeclaration (t.Value) { Location = t.Location, EndLocation = t.EndLocation }; td = new TemplateInstanceExpression(mod != DTokens.INVALID ? new MemberFunctionAttributeDecl(mod) { InnerType = td } : td) { Location = loc }; LastParsedObject = td; var args = new List<IExpression>(); if (!Expect(Not)) return td as TemplateInstanceExpression; if (laKind == (OpenParenthesis)) { Step(); if (laKind != CloseParenthesis) { bool init = true; while (laKind == Comma || init) { if (!init) Step(); init = false; if (laKind == CloseParenthesis) break; if (IsEOF) { args.Add(new TokenExpression(DTokens.INVALID) { Location= la.Location, EndLocation=la.EndLocation }); break; } Lexer.PushLookAheadBackup(); bool wp = AllowWeakTypeParsing; AllowWeakTypeParsing = true; var typeArg = Type(); AllowWeakTypeParsing = wp; if (typeArg != null && (laKind == CloseParenthesis || laKind==Comma)){ Lexer.PopLookAheadBackup(); args.Add(new TypeDeclarationExpression(typeArg)); }else { Lexer.RestoreLookAheadBackup(); args.Add(AssignExpression(Scope)); } } } Expect(CloseParenthesis); } else { Step(); /* * TemplateSingleArgument: * Identifier * BasicTypeX * CharacterLiteral * StringLiteral * IntegerLiteral * FloatLiteral * true * false * null * __FILE__ * __LINE__ */ IExpression arg= null; if (t.Kind == Literal) arg = new IdentifierExpression(t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral ? t.Value : t.LiteralValue, t.LiteralFormat, t.Subformat) { Location = t.Location, EndLocation = t.EndLocation }; else if (t.Kind == Identifier) arg = new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation }; else if (BasicTypes[t.Kind]) arg = new TypeDeclarationExpression(new DTokenDeclaration(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }); else if ( t.Kind == True || t.Kind == False || t.Kind == Null || t.Kind == __FILE__ || t.Kind == __LINE__) arg = new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; else if (IsEOF) { TrackerVariables.ExpectingIdentifier = false; td.EndLocation = CodeLocation.Empty; return td as TemplateInstanceExpression; } args.Add(arg); } (td as TemplateInstanceExpression).Arguments = args.ToArray(); td.EndLocation = t.EndLocation; return td as TemplateInstanceExpression; }
public static List<ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolutionContext ctxt, out bool hasNonFinalArgument) { hasNonFinalArgument = false; // Resolve given argument expressions var templateArguments = new List<ISemantic>(); if (tix != null && tix.Arguments!=null) foreach (var arg in tix.Arguments) { if (arg is TypeDeclarationExpression) { var tde = (TypeDeclarationExpression)arg; var res = TypeDeclarationResolver.ResolveSingle(tde.Declaration, ctxt); // Might be a simple symbol without any applied template arguments that is then passed to an template alias parameter if (res == null && tde.Declaration is IdentifierDeclaration) res = TypeDeclarationResolver.ResolveSingle(tde.Declaration as IdentifierDeclaration, ctxt, null, false); var amb = res as AmbiguousType; if (amb != null) { // Error res = amb.Overloads[0]; } var mr = res as MemberSymbol; if (mr != null && mr.Definition is DVariable) { var dv = (DVariable)mr.Definition; if (dv.IsAlias || dv.Initializer == null) { templateArguments.Add(mr); continue; } ISemantic eval = null; try { eval = new StandardValueProvider(ctxt)[dv]; } catch(System.Exception ee) // Should be a non-const-expression error here only { ctxt.LogError(dv.Initializer, ee.Message); } templateArguments.Add(eval ?? (ISemantic)mr); } else{ if(!hasNonFinalArgument) hasNonFinalArgument = IsNonFinalArgument(res); templateArguments.Add(res); } } else { ISemantic v = Evaluation.EvaluateValue(arg, ctxt, true); if (v is VariableValue) { var vv = v as VariableValue; if (vv.Variable.IsConst && vv.Variable.Initializer != null) v = Evaluation.EvaluateValue(vv, new StandardValueProvider(ctxt)); } if(!hasNonFinalArgument) hasNonFinalArgument = IsNonFinalArgument(v); v = DResolver.StripValueTypeWrappers(v); templateArguments.Add(v); } } return templateArguments; }
public AbstractType[] GetOverloads(TemplateInstanceExpression tix, IEnumerable <AbstractType> resultBases = null, bool deduceParameters = true) { return(GetOverloads(tix, ctxt, resultBases, deduceParameters)); }
public override void Visit(TemplateInstanceExpression x) { CallExpressionStack.Push(x); base.Visit(x); CallExpressionStack.Pop(); }
public override void Visit(TemplateInstanceExpression x) { CallExpressionStack.Push (x); base.Visit (x); CallExpressionStack.Pop (); }
public static List <ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolutionContext ctxt, out bool hasNonFinalArgument) { hasNonFinalArgument = false; // Resolve given argument expressions var templateArguments = new List <ISemantic>(); if (tix != null && tix.Arguments != null) { foreach (var arg in tix.Arguments) { if (arg is TypeDeclarationExpression) { var tde = (TypeDeclarationExpression)arg; var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt); // Might be a simple symbol without any applied template arguments that is then passed to an template alias parameter if (res == null && tde.Declaration is IdentifierDeclaration) { res = TypeDeclarationResolver.Resolve(tde.Declaration as IdentifierDeclaration, ctxt, null, false); } if (ctxt.CheckForSingleResult(res, tde.Declaration) || (res != null && res.Length > 0)) { var mr = res[0] as MemberSymbol; if (mr != null && mr.Definition is DVariable) { var dv = (DVariable)mr.Definition; if (dv.IsAlias || dv.Initializer == null) { templateArguments.Add(mr); continue; } ISemantic eval = null; try { eval = new StandardValueProvider(ctxt)[dv]; } catch (System.Exception ee) // Should be a non-const-expression error here only { ctxt.LogError(dv.Initializer, ee.Message); } templateArguments.Add(eval ?? (ISemantic)mr); } else { if (!hasNonFinalArgument) { hasNonFinalArgument = IsNonFinalArgument(res[0]); } templateArguments.Add(res[0]); } } } else { ISemantic v = Evaluation.EvaluateValue(arg, ctxt, true); if (v is VariableValue) { var vv = v as VariableValue; if (vv.Variable.IsConst && vv.Variable.Initializer != null) { v = Evaluation.EvaluateValue(vv, new StandardValueProvider(ctxt)); } } if (!hasNonFinalArgument) { hasNonFinalArgument = IsNonFinalArgument(v); } v = DResolver.StripValueTypeWrappers(v); templateArguments.Add(v); } } } return(templateArguments); }
public static AbstractType EvalMethodCall(AbstractType[] baseExpression, ISymbolValue baseValue, TemplateInstanceExpression tix, ResolutionContext ctxt, PostfixExpression_MethodCall call, out List <ISemantic> callArguments, out ISymbolValue delegateValue, bool returnBaseTypeOnly, AbstractSymbolValueProvider ValueProvider = null) { //TODO: Refactor this crap! delegateValue = null; callArguments = null; var methodOverloads = new List <AbstractType>(); #region Search possible methods, opCalls or delegates that could be called bool requireStaticItems = true; //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit IEnumerable <AbstractType> scanResults = baseExpression; var nextResults = new List <AbstractType>(); while (scanResults != null) { foreach (var b in scanResults) { if (b is AmbiguousType) { nextResults.AddRange((b as AmbiguousType).Overloads); } else if (b is TemplateParameterSymbol) { nextResults.Add((b as TemplateParameterSymbol).Base); } else if (b is MemberSymbol) { var mr = (MemberSymbol)b; if (mr.Definition is DMethod) { methodOverloads.Add(mr); continue; } else if (mr.Definition is DVariable) { // If we've got a variable here, get its base type/value reference if (ValueProvider != null) { var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue; if (dgVal != null) { nextResults.Add(dgVal.Definition); continue; } else { ValueProvider.LogError(call, "Variable must be a delegate, not anything else"); return(null); } } else { var bt = mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt); // Must be of type delegate if (bt is DelegateType) { var ret = HandleCallDelegateType(ValueProvider, bt as DelegateType, methodOverloads, returnBaseTypeOnly); if (ret is ISymbolValue) { delegateValue = ret as ISymbolValue; return(null); } else if (ret is AbstractType) { return(ret as AbstractType); } } else { /* * If mr.Node is not a method, so e.g. if it's a variable * pointing to a delegate * * class Foo * { * string opCall() { return "asdf"; } * } * * Foo f=new Foo(); * f(); -- calls opCall, opCall is not static */ nextResults.Add(bt); requireStaticItems = false; } //TODO: Can other types work as function/are callable? } } } else if (b is DelegateType) { var ret = HandleCallDelegateType(ValueProvider, b as DelegateType, methodOverloads, returnBaseTypeOnly); if (ret is ISymbolValue) { delegateValue = ret as ISymbolValue; return(null); } else if (ret is AbstractType) { return(ret as AbstractType); } } else if (b is ClassType || b is StructType) { var tit = (TemplateIntermediateType)b; /* * auto a = MyStruct(); -- opCall-Overloads can be used */ var classDef = tit.Definition; if (classDef == null) { continue; } foreach (var i in ExpressionTypeEvaluation.GetOpCalls(tit, requireStaticItems)) { methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol); } /* * Every struct can contain a default ctor: * * struct S { int a; bool b; } * * auto s = S(1,true); -- ok * auto s2= new S(2,false); -- error, no constructor found! */ if (b is StructType && methodOverloads.Count == 0) { //TODO: Deduce parameters return(b); } } /* * If the overload is a template, it quite exclusively means that we'll handle a method that is the only * child inside a template + that is named as the template. */ else if (b is TemplateType) { methodOverloads.Add(b); } else if (b is PrimitiveType) // dmd 2.066: Uniform Construction Syntax. creal(3) is of type creal. { methodOverloads.Add(b); } } scanResults = nextResults.Count == 0 ? null : nextResults.ToArray(); nextResults.Clear(); } #endregion if (methodOverloads.Count == 0) { return(null); } // Get all arguments' types callArguments = new List <ISemantic>(); if (call.Arguments != null) { if (ValueProvider != null) { foreach (var arg in call.Arguments) { callArguments.Add(arg != null ? Evaluation.EvaluateValue(arg, ValueProvider) : null); } } else { foreach (var arg in call.Arguments) { callArguments.Add(arg != null ? ExpressionTypeEvaluation.EvaluateType(arg, ctxt) : null); } } } #region If explicit template type args were given, try to associate them with each overload if (tix != null) { var args = TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt); var deducedOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(methodOverloads, args, true, ctxt); methodOverloads.Clear(); if (deducedOverloads != null) { methodOverloads.AddRange(deducedOverloads); } } #endregion #region Filter by parameter-argument comparison var argTypeFilteredOverloads = new List <AbstractType>(); bool hasHandledUfcsResultBefore = false; AbstractType untemplatedMethodResult = null; foreach (var ov in methodOverloads) { if (ov is MemberSymbol) { HandleDMethodOverload(ctxt, ValueProvider != null, baseValue, callArguments, returnBaseTypeOnly, argTypeFilteredOverloads, ref hasHandledUfcsResultBefore, ov as MemberSymbol, ref untemplatedMethodResult); } else if (ov is DelegateType) { var dg = ov as DelegateType; var bt = dg.Base ?? TypeDeclarationResolver.GetMethodReturnType(dg, ctxt); //TODO: Param-Arg check if (returnBaseTypeOnly) { argTypeFilteredOverloads.Add(bt); } else { if (dg.Base == null) { if (dg.IsFunctionLiteral) { dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters); } else { dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as DelegateDeclaration, dg.Parameters); } } argTypeFilteredOverloads.Add(new DelegateCallSymbol(dg, call)); } } else if (ov is PrimitiveType) // dmd 2.066: Uniform Construction Syntax. creal(3) is of type creal. { if (ValueProvider != null) { if (callArguments == null || callArguments.Count != 1) { ValueProvider.LogError(call, "Uniform construction syntax expects exactly one argument"); } else { var pv = callArguments[0] as PrimitiveValue; if (pv == null) { ValueProvider.LogError(call, "Uniform construction syntax expects one built-in scalar value as first argument"); } else { delegateValue = new PrimitiveValue(pv.Value, ov as PrimitiveType, pv.ImaginaryPart); } } } argTypeFilteredOverloads.Add(ov); } } // Prefer untemplated methods over templated ones if (untemplatedMethodResult != null) { return(untemplatedMethodResult); } #endregion return(AmbiguousType.Get(argTypeFilteredOverloads, tix)); }
public TemplateInstanceExpression TemplateInstance(IBlockNode Scope) { var loc = la.Location; var mod = INVALID; if (DTokens.IsStorageClass(laKind)) { mod = laKind; Step (); } if (!Expect (Identifier)) return null; ITypeDeclaration td = new IdentifierDeclaration (t.Value) { Location = t.Location, EndLocation = t.EndLocation }; td = new TemplateInstanceExpression(mod != DTokens.INVALID ? new MemberFunctionAttributeDecl(mod) { InnerType = td } : td) { Location = loc }; var args = new List<IExpression>(); if (!Expect(Not)) return td as TemplateInstanceExpression; if (laKind == (OpenParenthesis)) { Step(); if (laKind != CloseParenthesis) { bool init = true; while (laKind == Comma || init) { if (!init) Step(); init = false; if (laKind == CloseParenthesis) break; Lexer.PushLookAheadBackup(); bool wp = AllowWeakTypeParsing; AllowWeakTypeParsing = true; var typeArg = Type(); AllowWeakTypeParsing = wp; if (typeArg != null && (laKind == CloseParenthesis || laKind==Comma)){ Lexer.PopLookAheadBackup(); args.Add(new TypeDeclarationExpression(typeArg)); }else { Lexer.RestoreLookAheadBackup(); args.Add(AssignExpression(Scope)); } } } Expect(CloseParenthesis); } else { /* * TemplateSingleArgument: * Identifier * BasicTypeX * CharacterLiteral * StringLiteral * IntegerLiteral * FloatLiteral * true * false * null * this * __FILE__ * __MODULE__ * __LINE__ * __FUNCTION__ * __PRETTY_FUNCTION__ */ switch (laKind) { case Literal: case True: case False: case Null: case This: case __FILE__: case __MODULE__: case __LINE__: case __FUNCTION__: case __PRETTY_FUNCTION__: args.Add(PrimaryExpression(Scope)); break; case Identifier: Step(); args.Add(new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation }); break; default: if (IsBasicType(laKind)) { Step (); args.Add (new TypeDeclarationExpression (new DTokenDeclaration (t.Kind) { Location = t.Location, EndLocation = t.EndLocation })); break; } else if (IsEOF) goto case Literal; SynErr(laKind, "Illegal token found on template instance expression argument"); Step(); break; } if (laKind == Not && Peek(1).Kind != Is && Peek(1).Kind != In) { SynErr(laKind, "multiple ! arguments are not allowed"); Step(); } } (td as TemplateInstanceExpression).Arguments = args.ToArray(); td.EndLocation = t.EndLocation; return td as TemplateInstanceExpression; }
public override void Visit (TemplateInstanceExpression x) { if (DoPrimaryIdCheck(x.TemplateIdHash)) AddResult(x); base.Visit (x); }
public void Visit(TemplateInstanceExpression tix) { res.IsTemplateInstanceArguments = true; res.MethodIdentifier = tix; ctxt.ContextIndependentOptions = ResolutionOptions.NoTemplateParameterDeduction; res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, null, false); if (tix.Arguments != null) res.CurrentlyTypedArgumentIndex = tix.Arguments.Length; else res.CurrentlyTypedArgumentIndex = 0; }
bool HandleDecl(TemplateTypeParameter parameter, TemplateInstanceExpression tix, AbstractType r) { /* * TODO: Scan down r for having at least one templateinstanceexpression as declaration base. * If a tix was found, check if the definition of the respective result base level * and the un-aliased identifier of the 'tix' parameter match. * Attention: if the alias represents an undeduced type (i.e. a type bundle of equally named type nodes), * it is only important that the definition is inside this bundle. * Therefore, it's needed to manually resolve the identifier, and look out for aliases or such unprecise aliases..confusing as s**t! * * If the param tix id is part of the template param list, the behaviour is currently undefined! - so instantly return false, I'll leave it as TODO/FIXME */ var paramTix_TemplateMatchPossibilities = ResolveTemplateInstanceId(tix); TemplateIntermediateType tixBasedArgumentType = null; var r_ = r as DSymbol; while (r_ != null) { if (r_.DeclarationOrExpressionBase is TemplateInstanceExpression) { var tit = r_ as TemplateIntermediateType; if (tit != null && CheckForTixIdentifierEquality(paramTix_TemplateMatchPossibilities, tit.Definition)) { tixBasedArgumentType = tit; break; } } r_ = r_.Base as DSymbol; } /* * This part is very tricky: * I still dunno what is allowed over here-- * * class Foo(T:Bar!E[],E) {} * ... * Foo!(Bar!string[]) f; -- E will be 'string' then * * class DerivateBar : Bar!string[] {} -- new Foo!DerivateBar() is also allowed, but now DerivateBar * obviously is not a template instance expression - it's a normal identifier only. */ if (tixBasedArgumentType != null) { var argEnum_given = ((TemplateInstanceExpression)tixBasedArgumentType.DeclarationOrExpressionBase).Arguments.GetEnumerator(); foreach (var p in tix.Arguments) { if (!argEnum_given.MoveNext() || argEnum_given.Current == null) return false; // Convert p to type declaration var param_Expected = ConvertToTypeDeclarationRoughly(p); if (param_Expected == null) return false; var result_Given = ExpressionTypeEvaluation.EvaluateType(argEnum_given.Current as IExpression, ctxt); if (result_Given == null || !HandleDecl(parameter, param_Expected, result_Given)) return false; } // Too many params passed.. if (argEnum_given.MoveNext()) return false; return true; } return false; }
void GetRawCallOverloads(PostfixExpression_MethodCall call, out AbstractType[] baseExpression, out ISymbolValue baseValue, out TemplateInstanceExpression tix) { baseExpression = null; baseValue = null; tix = null; if (call.PostfixForeExpression is PostfixExpression_Access) { var pac = (PostfixExpression_Access)call.PostfixForeExpression; tix = pac.AccessExpression as TemplateInstanceExpression; var vs = E(pac, null, false, false); if (vs != null && vs.Length != 0) { if (vs[0] is ISymbolValue) { baseValue = (ISymbolValue)vs[0]; baseExpression = new[] { baseValue.RepresentedType }; } else if (vs[0] is InternalOverloadValue) baseExpression = ((InternalOverloadValue)vs[0]).Overloads; else baseExpression = TypeDeclarationResolver.Convert(vs); } } else { // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one var optBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes; if (call.PostfixForeExpression is TokenExpression) baseExpression = GetResolvedConstructorOverloads((TokenExpression)call.PostfixForeExpression, ctxt); else if (eval) { if (call.PostfixForeExpression is TemplateInstanceExpression) baseValue = E(tix = call.PostfixForeExpression as TemplateInstanceExpression, false) as ISymbolValue; else if (call.PostfixForeExpression is IdentifierExpression) baseValue = E((IdentifierExpression)call.PostfixForeExpression, false) as ISymbolValue; else baseValue = E(call.PostfixForeExpression) as ISymbolValue; if (baseValue is InternalOverloadValue) baseExpression = ((InternalOverloadValue)baseValue).Overloads; else if (baseValue != null) baseExpression = new[] { baseValue.RepresentedType }; else baseExpression = null; } else { if (call.PostfixForeExpression is TemplateInstanceExpression) baseExpression = GetOverloads(tix = (TemplateInstanceExpression)call.PostfixForeExpression, null, false); else if (call.PostfixForeExpression is IdentifierExpression) baseExpression = GetOverloads(call.PostfixForeExpression as IdentifierExpression, deduceParameters:false); else baseExpression = new[] { AbstractType.Get(E(call.PostfixForeExpression)) }; } ctxt.CurrentContext.ContextDependentOptions = optBackup; } }
static void HandleTemplateInstance(TemplateInstanceExpression tix, ArgumentsResolutionResult res, IEditorData Editor, ResolutionContext ctxt, IBlockNode curBlock, IEnumerable<AbstractType> resultBases = null) { res.IsTemplateInstanceArguments = true; res.MethodIdentifier = tix; res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, resultBases, false); if (tix.Arguments != null) res.CurrentlyTypedArgumentIndex = tix.Arguments.Length; else res.CurrentlyTypedArgumentIndex = 0; }
void GetRawCallOverloads(PostfixExpression_MethodCall call, out AbstractType[] baseExpression, out ISymbolValue baseValue, out TemplateInstanceExpression tix) { baseExpression = null; baseValue = null; tix = null; if (call.PostfixForeExpression is PostfixExpression_Access) { var pac = (PostfixExpression_Access)call.PostfixForeExpression; tix = pac.AccessExpression as TemplateInstanceExpression; var vs = E(pac, null, false, false); if (vs != null && vs.Length != 0) { if (vs[0] is ISymbolValue) { baseValue = (ISymbolValue)vs[0]; baseExpression = new[] { baseValue.RepresentedType }; } else if (vs[0] is InternalOverloadValue) { baseExpression = ((InternalOverloadValue)vs[0]).Overloads; } else { baseExpression = TypeDeclarationResolver.Convert(vs); } } } else { // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one var optBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes; if (call.PostfixForeExpression is TokenExpression) { baseExpression = GetResolvedConstructorOverloads((TokenExpression)call.PostfixForeExpression, ctxt); } else if (eval) { if (call.PostfixForeExpression is TemplateInstanceExpression) { baseValue = E(tix = call.PostfixForeExpression as TemplateInstanceExpression, false) as ISymbolValue; } else if (call.PostfixForeExpression is IdentifierExpression) { baseValue = E((IdentifierExpression)call.PostfixForeExpression, false) as ISymbolValue; } else { baseValue = E(call.PostfixForeExpression) as ISymbolValue; } if (baseValue is InternalOverloadValue) { baseExpression = ((InternalOverloadValue)baseValue).Overloads; } else if (baseValue != null) { baseExpression = new[] { baseValue.RepresentedType } } ; else { baseExpression = null; } } else { if (call.PostfixForeExpression is TemplateInstanceExpression) { baseExpression = GetOverloads(tix = (TemplateInstanceExpression)call.PostfixForeExpression, null, false); } else if (call.PostfixForeExpression is IdentifierExpression) { baseExpression = GetOverloads((IdentifierExpression)call.PostfixForeExpression, false); } else { baseExpression = new[] { AbstractType.Get(E(call.PostfixForeExpression)) } }; } ctxt.CurrentContext.ContextDependentOptions = optBackup; } }
public virtual void Visit(TemplateInstanceExpression x) { if (x.Identifier != null) x.Identifier.Accept(this); if (x.Arguments != null) foreach (var arg in x.Arguments) arg.Accept(this); }
public AbstractType[] GetOverloads(TemplateInstanceExpression tix, IEnumerable<AbstractType> resultBases = null, bool deduceParameters = true) { return GetOverloads(tix, ctxt, resultBases, deduceParameters); }
ITypeDeclaration QualifiedName() { ITypeDeclaration td = null; int n; while(PeekIsDecNumber) { // Read number of either the first LName or TemplateInstanceName n = (int)Number(); sb.Clear(); if((char)r.Peek() == '_') { r.Read(); sb.Append('_'); if((char)r.Peek() == '_') { r.Read(); sb.Append('_'); if((char)r.Peek() == 'T') { r.Read(); // We've got to handle a Template instance: // Number __T LName TemplateArgs Z var tpi = new TemplateInstanceExpression(new IdentifierDeclaration(LName())); tpi.InnerDeclaration = td; td = tpi; var xx = new List<IExpression>(); while(r.Peek() != -1) { var arg = TemplateArg(); if(arg == null) break; xx.Add(arg); } tpi.Arguments = xx.ToArray(); continue; } } } // Just an LName if(n > sb.Length) sb.Append(LName(n-sb.Length)); var ttd = new IdentifierDeclaration(sb.ToString()); ttd.InnerDeclaration = td; td = ttd; } return td; }
public static AbstractType[] EvalAndFilterOverloads(IEnumerable<AbstractType> rawOverloadList, TemplateInstanceExpression templateInstanceExpr, ResolverContextStack ctxt) { return EvalAndFilterOverloads(rawOverloadList, PreResolveTemplateArgs(templateInstanceExpr, ctxt), false, ctxt); }