protected override void BuildCompletionDataInternal(IEditorData Editor, char enteredChar) { var dc = begunNode.Parent as DClassLike; if (dc == null || dc.ClassType != DTokens.Class) { return; } var classType = DResolver.ResolveClassOrInterface(dc, ResolutionContext.Create(Editor), null) as TemplateIntermediateType; if (classType == null) { return; } var typesToScan = new List <TemplateIntermediateType>(); IterateThroughBaseClassesInterfaces(typesToScan, classType); foreach (var t in typesToScan) { foreach (var n in t.Definition) { var dm = n as DMethod; if (dm == null || dm.ContainsAttribute(DTokens.Final, DTokens.Private, DTokens.Static)) { continue; //TODO: Other attributes? } CompletionDataGenerator.AddCodeGeneratingNodeItem(dm, GenerateOverridingMethodStub(dm, begunNode, !(t is InterfaceType))); } } }
protected override bool HandleItem(INode n) { // Find all class+interface definitions var dc = n as DClassLike; if (dc == null || dc.BaseClasses == null || dc.BaseClasses.Count < 0 || alreadyResolvedClasses.Contains(dc)) { return(false); } // resolve immediate base classes/interfaces; Rely on dc being either a class or an interface, nothing else. var t = DResolver.ResolveClassOrInterface(dc, ctxt, null); alreadyResolvedClasses.Add(dc); // Look for classes/interfaces that match dc (check all dcs to have better performance on ambiguous lastresults), var bt = DResolver.StripMemberSymbols(t.Base) as TemplateIntermediateType; while (bt != null) { var def = bt.Definition; if (def == typeNodeToFind) { if (!results.Contains(t)) { results.Add(t); } } if (!alreadyResolvedClasses.Contains(def)) { alreadyResolvedClasses.Add(def); } bt = DResolver.StripMemberSymbols(bt.Base) as TemplateIntermediateType; } return(false); }
public AbstractType Visit(TokenExpression x) { switch (x.Token) { // References current class scope case DTokens.This: var classDef = ctxt.ScopedBlock; while (!(classDef is DClassLike) && classDef != null) { classDef = classDef.Parent as IBlockNode; } if (classDef is DClassLike) { var res = TypeDeclarationResolver.HandleNodeMatch(classDef, ctxt, null, x); res.NonStaticAccess = true; return(res); } //TODO: Throw return(null); case DTokens.Super: // References super type of currently scoped class declaration classDef = ctxt.ScopedBlock; while (!(classDef is DClassLike) && classDef != null) { classDef = classDef.Parent as IBlockNode; } if (classDef is DClassLike) { var tr = DResolver.ResolveClassOrInterface(classDef as DClassLike, ctxt, null, true); if (tr.Base != null) { // Important: Overwrite type decl base with 'super' token tr.Base.DeclarationOrExpressionBase = x; tr.Base.NonStaticAccess = true; return(tr.Base); } } //TODO: Throw return(null); case DTokens.Null: return(null); case DTokens.Dollar: return(new PrimitiveType(DTokens.Int)); // Really integer or every kind of iterator type? case DTokens.False: case DTokens.True: return(new PrimitiveType(DTokens.Bool)); case DTokens.__FILE__: return(GetStringType()); case DTokens.__LINE__: return(new PrimitiveType(DTokens.Int)); case DTokens.__MODULE__: return(GetStringType()); case DTokens.__FUNCTION__: //TODO return(null); case DTokens.__PRETTY_FUNCTION__: return(GetStringType()); default: return(null); } }
/// <summary> /// Item1 - True, if isExpression returns true /// Item2 - If Item1 is true, it contains the type of the alias that is defined in the isExpression /// </summary> private Tuple <bool, AbstractType> evalIsExpression_EvalSpecToken(IsExpression isExpression, AbstractType typeToCheck, bool DoAliasHandling = false) { bool r = false; AbstractType res = null; switch (isExpression.TypeSpecializationToken) { /* * To handle semantic tokens like "return" or "super" it's just needed to * look into the current resolver context - * then, we'll be able to gather either the parent method or the currently scoped class definition. */ case DTokens.Struct: case DTokens.Union: case DTokens.Class: case DTokens.Interface: if (r = typeToCheck is UserDefinedType && ((TemplateIntermediateType)typeToCheck).Definition.ClassType == isExpression.TypeSpecializationToken) { res = typeToCheck; } break; case DTokens.Enum: if (!(typeToCheck is EnumType)) { break; } { var tr = (UserDefinedType)typeToCheck; r = true; res = tr.Base; } break; case DTokens.Function: case DTokens.Delegate: if (typeToCheck is DelegateType) { var isFun = false; var dgr = (DelegateType)typeToCheck; if (!dgr.IsFunctionLiteral) { r = isExpression.TypeSpecializationToken == ( (isFun = ((DelegateDeclaration)dgr.DeclarationOrExpressionBase).IsFunction) ? DTokens.Function : DTokens.Delegate); } // Must be a delegate otherwise else { isFun = !(r = isExpression.TypeSpecializationToken == DTokens.Delegate); } if (r) { //TODO if (isFun) { // TypeTuple of the function parameter types. For C- and D-style variadic functions, only the non-variadic parameters are included. // For typesafe variadic functions, the ... is ignored. } else { // the function type of the delegate } } } else // Normal functions are also accepted as delegates { r = isExpression.TypeSpecializationToken == DTokens.Delegate && typeToCheck is MemberSymbol && ((DSymbol)typeToCheck).Definition is DMethod; //TODO: Alias handling, same as couple of lines above } break; case DTokens.Super: //TODO: Test this var dc = DResolver.SearchClassLikeAt(ctxt.ScopedBlock, isExpression.Location) as DClassLike; if (dc != null) { var udt = DResolver.ResolveClassOrInterface(dc, ctxt, null, true) as ClassType; if (r = udt.Base != null && ResultComparer.IsEqual(typeToCheck, udt.Base)) { var l = new List <AbstractType>(); if (udt.Base != null) { l.Add(udt.Base); } if (udt.BaseInterfaces != null && udt.BaseInterfaces.Length != 0) { l.AddRange(udt.BaseInterfaces); } res = new DTuple(isExpression, l); } } break; case DTokens.Const: case DTokens.Immutable: case DTokens.InOut: // TODO? case DTokens.Shared: if (r = typeToCheck.Modifier == isExpression.TypeSpecializationToken) { res = typeToCheck; } break; case DTokens.Return: // TODO: Test IStatement _u = null; var dm = DResolver.SearchBlockAt(ctxt.ScopedBlock, isExpression.Location, out _u) as DMethod; if (dm != null) { var retType_ = TypeDeclarationResolver.GetMethodReturnType(dm, ctxt); if (r = retType_ != null && ResultComparer.IsEqual(typeToCheck, retType_)) { res = retType_; } } break; } return(new Tuple <bool, AbstractType>(r, res)); }