protected override string Process(EditorData editorData, bool moduleOnly) { var sr = DResolver.GetScopedCodeObject(editorData); var rr = sr != null?LooseResolution.ResolveTypeLoosely(editorData, sr, out _, true) : null; var refs = new StringBuilder(); if (rr != null) { var n = ExpressionTypeEvaluation.GetResultMember(rr); if (n != null) { var ctxt = ResolutionContext.Create(editorData, true); if (moduleOnly || n.ContainsAnyAttribute(DTokens.Private) || (n is DVariable variable && variable.IsLocal)) { GetReferencesInModule(editorData.SyntaxTree, refs, n, ctxt); } else { foreach (var rootPackage in editorData.ParseCache.EnumRootPackagesSurroundingModule(editorData.SyntaxTree)) { foreach (var module in rootPackage) { GetReferencesInModule(module, refs, n, ctxt); } } } } //var res = TypeReferenceFinder.Scan(_editorData, System.Threading.CancellationToken.None, null); }
protected override void BuildCompletionDataInternal(IEditorData Editor, char enteredChar) { ed = Editor; ctxt = ResolutionContext.Create(Editor, false); AbstractType t = null; CodeCompletion.DoTimeoutableCompletionTask(CompletionDataGenerator, ctxt, () => { ctxt.Push(Editor); if (AccessExpression is IExpression) { t = ExpressionTypeEvaluation.EvaluateType(AccessExpression as IExpression, ctxt); } else if (AccessExpression is ITypeDeclaration) { t = TypeDeclarationResolver.ResolveSingle(AccessExpression as ITypeDeclaration, ctxt); } }); if (t == null) //TODO: Add after-space list creation when an unbound . (Dot) was entered which means to access the global scope { return; } t.Accept(this); }
public void IsExpressionAlias() { var ctxt = ResolutionTests.CreateCtxt("A", @"module A; static if(is(const(int)* U == const(U)*)) U var; U derp; "); IExpression x; AbstractType t; DSymbol ds; x = DParser.ParseExpression("var"); (x as IdentifierExpression).Location = new CodeLocation(2, 3); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); ds = t as DSymbol; Assert.That(t, Is.TypeOf(typeof(MemberSymbol))); Assert.That(ds.Base, Is.TypeOf(typeof(TemplateParameterSymbol))); ds = ds.Base as DSymbol; Assert.That(ds.Base, Is.TypeOf(typeof(PrimitiveType))); Assert.That((ds.Base as PrimitiveType).Modifier, Is.EqualTo(0)); ctxt.CurrentContext.DeducedTemplateParameters.Clear(); var dv = ctxt.ParseCache[0]["A"]["derp"].First() as DVariable; t = TypeDeclarationResolver.HandleNodeMatch(dv, ctxt); Assert.That(t, Is.TypeOf(typeof(MemberSymbol))); Assert.That((t as MemberSymbol).Base, Is.Null); }
public void BasicResolution() { var ctxt = ResolutionTests.CreateCtxt("modA", @"module modA; void writeln(T...)(T t) {} int[] foo(string a) {} int foo(int a) {} string globStr; int globI; "); IExpression x; AbstractType t; x = DParser.ParseExpression("globStr.foo()"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(ArrayType))); x = DParser.ParseExpression("globI.foo()"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(PrimitiveType))); x = DParser.ParseExpression("globStr.writeln()"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(PrimitiveType))); Assert.That((t as PrimitiveType).TypeToken, Is.EqualTo(DTokens.Void)); }
static AbstractType DeduceEponymousTemplate(EponymousTemplateType ept, ResolutionContext ctxt) { if (ept.Definition.Initializer == null && ept.Definition.Type == null) { ctxt.LogError(ept.Definition, "Can't deduce type from empty initializer!"); return(null); } // Introduce the deduced params to the current resolution context ctxt.CurrentContext.IntroduceTemplateParameterTypes(ept); // Get actual overloads AbstractType deducedType = null; var def = ept.Definition; deducedType = new MemberSymbol(def, def.Type != null ? TypeDeclarationResolver.ResolveSingle(def.Type, ctxt) : ExpressionTypeEvaluation.EvaluateType(def.Initializer, ctxt), null, ept.DeducedTypes); //ept; //ExpressionTypeEvaluation.EvaluateType (ept.Definition.Initializer, ctxt); deducedType.Tag = ept.Tag; // Currently requried for proper UFCS resolution - sustain ept's Tag // Undo context-related changes ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ept); return(deducedType); }
/// <summary> /// /// </summary> /// <param name="dm"></param> /// <param name="args"></param> /// <param name="baseValueProvider">Required for evaluating missing default parameters.</param> public static bool AssignCallArgumentsToIC <T>(MemberSymbol mr, T[] args, AbstractSymbolValueProvider baseValueProvider, out Dictionary <DVariable, T> targetArgs, ResolutionContext ctxt = null) where T : class, ISemantic { var dm = mr.Definition as DMethod; int para = 0; ISemantic firstArg; if (TypeResolution.UFCSResolver.IsUfcsResult(mr, out firstArg)) { para++; } targetArgs = new Dictionary <DVariable, T>(); var argsRemaining = args != null ? args.Length : 0; int argu = 0; for (; para < dm.Parameters.Count; para++) { var par = dm.Parameters[para] as DVariable; if (par.Type is VarArgDecl && argsRemaining > 0) { var va_args = new T[argsRemaining]; args.CopyTo(va_args, argu); argsRemaining = 0; //TODO: Assign a value tuple to par if (++para < dm.Parameters.Count) { return(false); } } if (argsRemaining > 0) { targetArgs[par] = args[argu++]; argsRemaining--; } else if (par.Initializer != null) { if (typeof(T) == typeof(AbstractType)) { targetArgs[par] = ExpressionTypeEvaluation.EvaluateType(par.Initializer, ctxt) as T; } else if (typeof(T) == typeof(ISymbolValue)) { targetArgs[par] = Evaluation.EvaluateValue(par.Initializer, baseValueProvider) as T; } } else { return(false); } } return(argsRemaining == 0); }
public override void Visit(IdentifierExpression id) { if (id.IsIdentifier && id.ValueStringHash == searchHash) { ctxt.CurrentContext.Set(id.Location); if (TryAdd(ExpressionTypeEvaluation.EvaluateType(id, ctxt, false), id)) { return; } } }
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 void IsExpressionAlias_InMethod() { var ctxt = ResolutionTests.CreateCtxt("A", @"module A; void main(){ pre; static if(is(const(int)* U == const(U)*)) { U var; } post; } "); IExpression x; AbstractType t; DSymbol ds; var main = ctxt.ParseCache[0]["A"]["main"].First() as DMethod; ctxt.PushNewScope(main, main.Body.SubStatements.First()); t = TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("U") { Location = main.Body.SubStatements.First().Location }, ctxt); Assert.That(t, Is.Null); ctxt.Pop(); ctxt.PushNewScope(main, main.Body.SubStatements.ElementAt(2)); t = TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("U") { Location = main.Body.SubStatements.ElementAt(2).Location }, ctxt); Assert.That(t, Is.Null); ctxt.Pop(); x = DParser.ParseExpression("var"); IStatement stmt; DResolver.SearchBlockAt(main, (x as IdentifierExpression).Location = new CodeLocation(3, 7), out stmt); ctxt.PushNewScope(main, stmt); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); ds = t as DSymbol; Assert.That(t, Is.TypeOf(typeof(MemberSymbol))); Assert.That(ds.Base, Is.TypeOf(typeof(TemplateParameterSymbol))); ds = ds.Base as DSymbol; Assert.That(ds.Base, Is.TypeOf(typeof(PrimitiveType))); Assert.That((ds.Base as PrimitiveType).Modifier, Is.EqualTo(0)); }
static DNode GetResultMember(AbstractType abstractType) { var nodeSymbolToFind = ExpressionTypeEvaluation.GetResultMember(abstractType); // Slightly hacky: To keep highlighting the id of e.g. a NewExpression, take the ctor's parent node (i.e. the class node) if (nodeSymbolToFind is DMethod dm && dm.SpecialType == DMethod.MethodType.Constructor) { nodeSymbolToFind = ((abstractType as DSymbol).Base as DSymbol)?.Definition; } return(nodeSymbolToFind); }
public override void Visit(PostfixExpression_Access acc) { var resolvedSymbol = TryPopPFAStack(); if ((acc.AccessExpression is IdentifierExpression && (acc.AccessExpression as IdentifierExpression).ValueStringHash != searchHash) || (acc.AccessExpression is TemplateInstanceExpression && ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash)) { acc.PostfixForeExpression.Accept(this); return; } else if (acc.AccessExpression is NewExpression) { var nex = acc.AccessExpression as NewExpression; if ((nex.Type is IdentifierDeclaration && ((IdentifierDeclaration)nex.Type).IdHash != searchHash) || (nex.Type is TemplateInstanceExpression && ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash)) { acc.PostfixForeExpression.Accept(this); return; } // Are there other types to test for? } else { // Are there other types to test for? } var s = resolvedSymbol ?? ExpressionTypeEvaluation.EvaluateType(acc, ctxt) as DerivedDataType; if (s is DSymbol) { if (((DSymbol)s).Definition == symbol) { l.Add(acc.AccessExpression); } } else if (s == null || !(s.Base is DSymbol)) { acc.PostfixForeExpression.Accept(this); return; } // Scan down for other possible symbols if (s.Base is DSymbol) { postfixForeExprAccessStack.Push(s.Base as DSymbol); } acc.PostfixForeExpression.Accept(this); }
public void Visit(PostfixExpression_MethodCall call) { res.IsMethodArguments = true; res.MethodIdentifier = call.PostfixForeExpression; res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetUnfilteredMethodOverloads(call.PostfixForeExpression, ctxt, call); if (call.Arguments != null) { res.CurrentlyTypedArgumentIndex = call.ArgumentCount; } }
public void EponymousTemplates() { var ctxt = ResolutionTests.CreateDefCtxt(@"module B; alias Tuple(T...) = T; alias Tup = Tuple!(int, float, string); enum isIntOrFloat(F) = is(F == int) || is(F == float); "); IExpression x; ISymbolValue v; AbstractType t; x = DParser.ParseExpression("isIntOrFloat!(Tup[0])"); v = Evaluation.EvaluateValue(x, ctxt); Assert.That(v, Is.TypeOf(typeof(PrimitiveValue))); Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m)); DToken tk; var td = DParser.ParseBasicType("Tuple!(int, float, string)", out tk); //t = TypeDeclarationResolver.ResolveSingle (td, ctxt); //Assert.That (t, Is.TypeOf(typeof(MemberSymbol))); //Assert.That ((t as MemberSymbol).Base, Is.TypeOf(typeof(DTuple))); x = DParser.ParseExpression("Tup[0]"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(PrimitiveType))); x = DParser.ParseExpression("Tup[1]"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(PrimitiveType))); x = DParser.ParseExpression("Tup[2]"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(ArrayType))); x = DParser.ParseExpression("isIntOrFloat!int"); v = Evaluation.EvaluateValue(x, ctxt); Assert.That(v, Is.TypeOf(typeof(PrimitiveValue))); Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m)); x = DParser.ParseExpression("isIntOrFloat!float"); v = Evaluation.EvaluateValue(x, ctxt); Assert.That(v, Is.TypeOf(typeof(PrimitiveValue))); Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m)); x = DParser.ParseExpression("isIntOrFloat!string"); v = Evaluation.EvaluateValue(x, ctxt); Assert.That(v, Is.TypeOf(typeof(PrimitiveValue))); Assert.That((v as PrimitiveValue).Value, Is.EqualTo(0m)); }
public static AbstractType[] Resolve(ITypeDeclaration declaration, ResolutionContext ctxt) { if (declaration is IdentifierDeclaration) { return(Resolve((IdentifierDeclaration)declaration, ctxt)); } else if (declaration is TemplateInstanceExpression) { return(ExpressionTypeEvaluation.GetOverloads((TemplateInstanceExpression)declaration, ctxt)); } var t = ResolveSingle(declaration, ctxt); return(t == null ? null : new[] { t }); }
public AbstractType TryGetDType(IDBacktraceSymbol s) { if (!s.HasParent) { TryUpdateStackFrameInfo(); if (ctxt == null) { return(null); } return(AmbiguousType.Get(ExpressionTypeEvaluation.GetOverloads(new IdentifierExpression(s.Name), ctxt, null))); } return(null); }
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 override void Visit(PostfixExpression_Access acc) { acc.PostfixForeExpression.Accept(this); if ((acc.AccessExpression is IdentifierExpression && (acc.AccessExpression as IdentifierExpression).ValueStringHash != searchHash) || (acc.AccessExpression is TemplateInstanceExpression && ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash)) { return; } else if (acc.AccessExpression is NewExpression) { var nex = acc.AccessExpression as NewExpression; if ((nex.Type is IdentifierDeclaration && ((IdentifierDeclaration)nex.Type).IdHash != searchHash) || (nex.Type is TemplateInstanceExpression && ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash)) { return; } // Are there other types to test for? } else { // Are there other types to test for? } ctxt.CurrentContext.Set(acc.Location); var ov = ExpressionTypeEvaluation.GetAccessedOverloads(acc, ctxt, null, false); if (ov == null) { return; } foreach (var o in ov) { if (TryAdd(o, acc.AccessExpression)) { return; } } }
bool HandleDecl(VectorDeclaration v, AbstractType r) { if (r.DeclarationOrExpressionBase is VectorDeclaration) { var v_res = ExpressionTypeEvaluation.EvaluateType(v.Id, ctxt); var r_res = ExpressionTypeEvaluation.EvaluateType(((VectorDeclaration)r.DeclarationOrExpressionBase).Id, ctxt); if (v_res == null || r_res == null) { return(false); } else { return(ResultComparer.IsImplicitlyConvertible(r_res, v_res)); } } return(false); }
public AbstractType Visit(DVariable variable) { AbstractType bt; if (CanResolveBase(variable)) { var bts = TypeDeclarationResolver.Resolve(variable.Type, ctxt); if (bts != null && bts.Length != 0) { bt = bts[0]; } // For auto variables, use the initializer to get its type else if (variable.Initializer != null) { bt = DResolver.StripMemberSymbols(ExpressionTypeEvaluation.EvaluateType(variable.Initializer, ctxt)); } else { bt = null; } // Check if inside an foreach statement header if (bt == null && ctxt.ScopedStatement != null) { bt = GetForeachIteratorType(variable); } if (bt == null) { ctxt.CheckForSingleResult(bts, variable.Type as ISyntaxRegion ?? variable.Initializer); } } else { bt = null; } // Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type return(variable.IsAlias ? new AliasedType(variable, bt, typeBase) : new MemberSymbol(variable, bt, typeBase)); }
public override void Visit(IdentifierExpression id) { var resolvedSymbol = TryPopPFAStack(); if (id.IsIdentifier && id.ValueStringHash == searchHash) { if (resolvedSymbol == null) { resolvedSymbol = ExpressionTypeEvaluation.EvaluateType(id, ctxt) as DSymbol; } if (resolvedSymbol != null && resolvedSymbol.Definition == symbol) { l.Add(id); return; } } base.Visit(id); }
public override void Visit(TemplateInstanceExpression tix) { var resolvedSymbol = TryPopPFAStack(); if (tix.TemplateIdHash == searchHash) { if (resolvedSymbol == null) { resolvedSymbol = ExpressionTypeEvaluation.EvaluateType(tix, ctxt) as DSymbol; } if (resolvedSymbol != null && resolvedSymbol.Definition == symbol) { l.Add(tix); return; } } base.Visit(tix); }
public static AbstractType Resolve(TypeOfDeclaration typeOf, ResolutionContext ctxt) { // typeof(return) if (typeOf.Expression is TokenExpression && (typeOf.Expression as TokenExpression).Token == DTokens.Return) { var m = HandleNodeMatch(ctxt.ScopedBlock, ctxt, null, typeOf); if (m != null) { return(m); } } // typeOf(myInt) => int else if (typeOf.Expression != null) { var wantedTypes = ExpressionTypeEvaluation.EvaluateType(typeOf.Expression, ctxt); return(DResolver.StripMemberSymbols(wantedTypes)); } return(null); }
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 void AliasedTypeTuple() { var ctxt = ResolutionTests.CreateDefCtxt(@"module A; template Tuple(T...) { alias Tuple = T; } alias Tup = Tuple!(int, float, string); template isIntOrFloat(T) { static if (is(T == int) || is(T == float)) enum isIntOrFloat = true; else enum isIntOrFloat = false; } "); IExpression x; ISymbolValue v; AbstractType t; x = DParser.ParseExpression("Tup[2]"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(ArrayType))); x = DParser.ParseExpression("isIntOrFloat!(Tup[2])"); v = Evaluation.EvaluateValue(x, ctxt); Assert.That(v, Is.TypeOf(typeof(PrimitiveValue))); Assert.That((v as PrimitiveValue).Value, Is.EqualTo(0m)); x = DParser.ParseExpression("Tup[0]"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(PrimitiveType))); x = DParser.ParseExpression("Tup[1]"); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); Assert.That(t, Is.TypeOf(typeof(PrimitiveType))); x = DParser.ParseExpression("isIntOrFloat!(Tup[0])"); v = Evaluation.EvaluateValue(x, ctxt); Assert.That(v, Is.TypeOf(typeof(PrimitiveValue))); Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m)); }
protected override void BuildCompletionDataInternal(IEditorData Editor, char enteredChar) { ed = Editor; ctxt = ResolutionContext.Create(Editor.ParseCache, new ConditionalCompilationFlags(Editor), ScopedBlock, ScopedStatement); ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.ReturnMethodReferencesOnly; AbstractType t; if (AccessExpression is IExpression) { t = ExpressionTypeEvaluation.EvaluateType(AccessExpression as IExpression, ctxt); } else if (AccessExpression is ITypeDeclaration) { t = TypeDeclarationResolver.ResolveSingle(AccessExpression as ITypeDeclaration, ctxt); } else { return; } t = DResolver.StripAliasSymbol(t); if (t == null) //TODO: Add after-space list creation when an unbound . (Dot) was entered which means to access the global scope { return; } isVariableInstance = false; if (t.DeclarationOrExpressionBase is ITypeDeclaration) { isVariableInstance |= (t.DeclarationOrExpressionBase as ITypeDeclaration).ExpressesVariableAccess; } t.Accept(this); }
public static AbstractType[] ResolveType(IEditorData editor, ResolutionContext ctxt = null) { if (ctxt == null) { ctxt = ResolutionContext.Create(editor); } var o = GetScopedCodeObject(editor); var optionBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.ReturnMethodReferencesOnly; AbstractType[] ret; if (o is IExpression) { ret = ExpressionTypeEvaluation.EvaluateTypes((IExpression)o, ctxt); } else if (o is ITypeDeclaration) { ret = TypeDeclarationResolver.Resolve((ITypeDeclaration)o, ctxt); } else if (o is INode) { ret = new[] { TypeDeclarationResolver.HandleNodeMatch(o as INode, ctxt) } } ; else { ret = null; } ctxt.CurrentContext.ContextDependentOptions = optionBackup; return(ret); }
public static AbstractType ResolveType(IEditorData editor, ResolutionContext ctxt = null) { var o = GetScopedCodeObject(editor); if (ctxt == null) { ctxt = ResolutionContext.Create(editor, false); } AbstractType ret = null; CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => { ctxt.Push(editor); var optionBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.ReturnMethodReferencesOnly; if (o is IExpression) { ret = ExpressionTypeEvaluation.EvaluateType((IExpression)o, ctxt, false); } else if (o is ITypeDeclaration) { ret = TypeDeclarationResolver.ResolveSingle((ITypeDeclaration)o, ctxt); } else if (o is INode) { ret = TypeDeclarationResolver.HandleNodeMatch(o as INode, ctxt); } ctxt.CurrentContext.ContextDependentOptions = optionBackup; }); return(ret); }
void HandleIndexSliceExpression(PostfixExpression x) { res.IsMethodArguments = true; res.ParsedExpression = x; var overloads = new List <AbstractType>(); if (x.PostfixForeExpression == null) { return; } var b = ExpressionTypeEvaluation.EvaluateType(x.PostfixForeExpression, ctxt); var bases = AmbiguousType.TryDissolve(b); var ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpSliceIdHash, bases, ctxt, x, false); if (ov != null) { overloads.AddRange(ov); } ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpIndexIdHash, bases, ctxt, x, false); if (ov != null) { overloads.AddRange(ov); } if (overloads.Count == 0) { b = DResolver.StripMemberSymbols(b); var toTypeDecl = new DTypeToTypeDeclVisitor(); var aa = b as AssocArrayType; if (aa != null) { var retType = aa.ValueType != null?aa.ValueType.Accept(toTypeDecl) : null; var dm = new DMethod { Name = "opIndex", Type = retType }; dm.Parameters.Add(new DVariable { Name = "index", Type = aa.KeyType != null ? aa.KeyType.Accept(toTypeDecl) : null }); overloads.Add(new MemberSymbol(dm, aa.ValueType, x)); if ((aa is ArrayType) && !(aa as ArrayType).IsStaticArray) { dm = new DMethod { Name = "opSlice", Type = retType }; overloads.Add(new MemberSymbol(dm, aa.ValueType, x)); } } else if (b is PointerType) { b = (b as PointerType).Base; var dm = new DMethod { Name = "opIndex", Type = b != null?b.Accept(toTypeDecl) : null }; dm.Parameters.Add(new DVariable { Name = "index", Type = new IdentifierDeclaration("size_t") }); overloads.Add(new MemberSymbol(dm, b, x)); } } res.ResolvedTypesOrMethods = overloads.ToArray(); }
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); }
/// <summary> /// Reparses the given method's fucntion body until the cursor position, /// searches the last occurring method call or template instantiation, /// counts its already typed arguments /// and returns a wrapper containing all the information. /// </summary> public static ArgumentsResolutionResult ResolveArgumentContext( IEditorData Editor, ResolutionContext ctxt) { IBlockNode curBlock = null; IStatement stmt; bool inNonCode; var sr = CodeCompletion.FindCurrentCaretContext(Editor, ref curBlock, out stmt, out inNonCode); IExpression lastParamExpression = null; var paramInsightVis = new ParamInsightVisitor(); if (sr is INode) { (sr as INode).Accept(paramInsightVis); } else if (sr is IStatement) { (sr as IStatement).Accept(paramInsightVis); } else if (sr is IExpression) { (sr as IExpression).Accept(paramInsightVis); } lastParamExpression = paramInsightVis.LastCallExpression; /* * Then handle the lastly found expression regarding the following points: * * 1) foo( -- normal arguments only * 2) foo!(...)( -- normal arguments + template args * 3) foo!( -- template args only * 4) new myclass( -- ctor call * 5) new myclass!( -- ditto * 6) new myclass!(...)( * 7) mystruct( -- opCall call */ var res = new ArgumentsResolutionResult() { ParsedExpression = lastParamExpression }; // 1), 2) if (lastParamExpression is PostfixExpression_MethodCall) { res.IsMethodArguments = true; var call = (PostfixExpression_MethodCall)lastParamExpression; res.MethodIdentifier = call.PostfixForeExpression; res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetUnfilteredMethodOverloads(call.PostfixForeExpression, ctxt, call); if (call.Arguments != null) { res.CurrentlyTypedArgumentIndex = call.ArgumentCount; } } // 3) else if (lastParamExpression is TemplateInstanceExpression) { HandleTemplateInstance(lastParamExpression as TemplateInstanceExpression, res, Editor, ctxt, curBlock); } else if (lastParamExpression is NewExpression) { HandleNewExpression((NewExpression)lastParamExpression, res, Editor, ctxt, curBlock); } /* * alias int function(int a, bool b) myDeleg; * alias myDeleg myDeleg2; * * myDeleg dg; * * dg( -- it's not needed to have myDeleg but the base type for what it stands for * * ISSUE: * myDeleg( -- not allowed though * myDeleg2( -- allowed neither! */ if (res.ResolvedTypesOrMethods != null) { res.ResolvedTypesOrMethods = DResolver.StripAliasSymbols(res.ResolvedTypesOrMethods); } return(res); }