public override void AssignFrom(INode other) { base.AssignFrom(other); var tmxNode = other as NamedTemplateMixinNode; if (tmxNode != null) { Mixin = tmxNode.Mixin; } }
public override void Visit(TemplateMixin s) { if (s.MixinId == DTokens.IncompleteId) { explicitlyNoCompletion = true; halt = true; } else { base.Visit(s); } }
// http://dlang.org/template-mixin.html#TemplateMixin bool HandleUnnamedTemplateMixin(TemplateMixin tmx, bool treatAsDeclBlock, MemberFilter vis) { if (CompletionOptions.Instance.DisableMixinAnalysis) { return(false); } if (templateMixinsBeingAnalyzed == null) { templateMixinsBeingAnalyzed = new List <TemplateMixin>(); } if (templateMixinsBeingAnalyzed.Contains(tmx)) { return(false); } templateMixinsBeingAnalyzed.Add(tmx); var tmxTemplate = GetTemplateMixinContent(ctxt, tmx, false); bool res = false; if (tmxTemplate == null) { ctxt.LogError(tmx.Qualifier, "Mixin qualifier must resolve to a mixin template declaration."); } else { bool pop = !ctxt.ScopedBlockIsInNodeHierarchy(tmxTemplate.Definition); if (pop) { ctxt.PushNewScope(tmxTemplate.Definition); } ctxt.CurrentContext.IntroduceTemplateParameterTypes(tmxTemplate); dontHandleTemplateParamsInNodeScan = true; res |= DeepScanClass(tmxTemplate, vis); if (pop) { ctxt.Pop(); } else { ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(tmxTemplate); } } templateMixinsBeingAnalyzed.Remove(tmx); return(res); }
TemplateMixin TemplateMixin(INode Scope, IStatement Parent = null) { // mixin TemplateIdentifier !( TemplateArgumentList ) MixinIdentifier ; // |<-- optional -->| var r = new TemplateMixin { Attributes = GetCurrentAttributeSet_Array() }; if(Parent == null) r.ParentNode = Scope; else r.Parent = Parent; ITypeDeclaration preQualifier = null; Expect(Mixin); r.Location = t.Location; bool modScope = false; if (laKind == Dot) { modScope = true; Step(); } else if(laKind!=Identifier) {// See Dsymbol *Parser::parseMixin() if (laKind == Typeof) { preQualifier=TypeOf(); } else if (laKind == __vector) { //TODO: Parse vectors(?) } Expect(Dot); } r.Qualifier= IdentifierList(); if (r.Qualifier != null) r.Qualifier.InnerMost.InnerDeclaration = preQualifier; else r.Qualifier = preQualifier; if(modScope) { var innerMost = r.Qualifier.InnerMost; if(innerMost is IdentifierExpression) (innerMost as IdentifierExpression).ModuleScoped = true; else if(innerMost is TemplateInstanceExpression) (innerMost as TemplateInstanceExpression).ModuleScopedIdentifier = true; } // MixinIdentifier if (laKind == Identifier) { Step (); r.IdLocation = t.Location; r.MixinId = t.Value; } else if (r.Qualifier != null && IsEOF) r.MixinId = DTokens.IncompleteId; Expect(Semicolon); r.EndLocation = t.EndLocation; return r; }
public void Visit(TemplateMixin templateMixin) { }
TemplateMixin TemplateMixin() { // mixin TemplateIdentifier !( TemplateArgumentList ) MixinIdentifier ; // |<-- optional -->| var r = new TemplateMixin(); LastParsedObject = r; ITypeDeclaration preQualifier = null; Expect(Mixin); r.Location = t.Location; if (laKind == Dot) { Step(); } else if(laKind!=Identifier) { if (laKind == Typeof) { preQualifier=TypeOf(); } else if (laKind == __vector) { //TODO: Parse vectors(?) } Expect(Dot); } r.Qualifier= IdentifierList(); if (r.Qualifier != null) r.Qualifier.InnerMost.InnerDeclaration = preQualifier; else r.Qualifier = preQualifier; // MixinIdentifier if (laKind == Identifier) { Step(); r.MixinId = t.Value; } Expect(Semicolon); r.EndLocation = t.EndLocation; return r; }
public override void Visit(TemplateMixin s) { if (s.MixinId == DTokens.IncompleteId) { scopedStatement = s; explicitlyNoCompletion = true; halt = true; } else base.Visit (s); }
TemplateMixin TemplateMixin() { // mixin TemplateIdentifier !( TemplateArgumentList ) MixinIdentifier ; // |<-- optional -->| var r = new TemplateMixin(); LastParsedObject = r; Expect(Mixin); r.StartLocation = t.Location; if (Expect(Identifier)) { r.TemplateId = t.Value; if (laKind==Not) { Step(); if(Expect(OpenParenthesis) && laKind!=CloseParenthesis) { var args = new List<IExpression>(); bool init = true; while (init || laKind == (Comma)) { if (!init) Step(); init = false; if (IsAssignExpression()) args.Add(AssignExpression()); else args.Add(new TypeDeclarationExpression(Type())); r.Arguments = args.ToArray(); } } Expect(CloseParenthesis); } } // MixinIdentifier if (laKind == Identifier) { Step(); r.MixinId = t.Value; } Expect(Semicolon); r.EndLocation = t.EndLocation; return r; }
// http://dlang.org/template-mixin.html#TemplateMixin bool HandleUnnamedTemplateMixin(TemplateMixin tmx, bool treatAsDeclBlock, MemberFilter vis) { if (CompletionOptions.Instance.DisableMixinAnalysis) return false; if(templateMixinsBeingAnalyzed == null) templateMixinsBeingAnalyzed = new List<TemplateMixin>(); if(templateMixinsBeingAnalyzed.Contains(tmx)) return false; templateMixinsBeingAnalyzed.Add(tmx); var tmxTemplate = GetTemplateMixinContent(ctxt, tmx, false); bool res = false; if(tmxTemplate == null) ctxt.LogError(tmx.Qualifier, "Mixin qualifier must resolve to a mixin template declaration."); else { bool pop = !ctxt.ScopedBlockIsInNodeHierarchy(tmxTemplate.Definition); if(pop) ctxt.PushNewScope(tmxTemplate.Definition); ctxt.CurrentContext.IntroduceTemplateParameterTypes(tmxTemplate); dontHandleTemplateParamsInNodeScan = true; res |= DeepScanClass(tmxTemplate, vis); if(pop) ctxt.Pop(); else ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(tmxTemplate); } templateMixinsBeingAnalyzed.Remove(tmx); return res; }
public static MixinTemplateType GetTemplateMixinContent (ResolutionContext ctxt, TemplateMixin tmx, bool pushOnAnalysisStack = true) { if (pushOnAnalysisStack) { if(templateMixinsBeingAnalyzed == null) templateMixinsBeingAnalyzed = new List<TemplateMixin>(); if(templateMixinsBeingAnalyzed.Contains(tmx)) return null; templateMixinsBeingAnalyzed.Add(tmx); } AbstractType t; if(!templateMixinCache.TryGet(ctxt, tmx, out t)) { t = TypeDeclarationResolver.ResolveSingle(tmx.Qualifier, ctxt); // Deadly important: To prevent mem leaks, all references from the result to the TemplateMixin must be erased! // Elsewise there remains one reference from the dict value to the key - and won't get free'd THOUGH we can't access it anymore if(t != null) t.DeclarationOrExpressionBase = null; templateMixinCache.Add(ctxt, tmx, t); } if(pushOnAnalysisStack) templateMixinsBeingAnalyzed.Remove(tmx); return t as MixinTemplateType; }
public NamedTemplateMixinNode(TemplateMixin tmx) { Mixin = tmx; }
public static MixinTemplateType GetTemplateMixinContent(ResolutionContext ctxt, TemplateMixin tmx, bool pushOnAnalysisStack = true) { if (pushOnAnalysisStack) { if (templateMixinsBeingAnalyzed == null) { templateMixinsBeingAnalyzed = new List <TemplateMixin>(); } if (templateMixinsBeingAnalyzed.Contains(tmx)) { return(null); } templateMixinsBeingAnalyzed.Add(tmx); } AbstractType t; if (!templateMixinCache.TryGet(ctxt, tmx, out t)) { t = TypeDeclarationResolver.ResolveSingle(tmx.Qualifier, ctxt); // Deadly important: To prevent mem leaks, all references from the result to the TemplateMixin must be erased! // Elsewise there remains one reference from the dict value to the key - and won't get free'd THOUGH we can't access it anymore if (t != null) { t.DeclarationOrExpressionBase = null; } templateMixinCache.Add(ctxt, tmx, t); } if (pushOnAnalysisStack) { templateMixinsBeingAnalyzed.Remove(tmx); } return(t as MixinTemplateType); }