public void VisitAttribute(DeclarationCondition declCond) { if (declCond.Condition != null) { declCond.Condition.Accept(this); } }
public bool IsMatching(DeclarationCondition cond, ResolutionContext ctxt) { if(cond is VersionCondition) { var vc = (VersionCondition)cond; return vc.VersionId == null ? vc.VersionNumber >= versionNumber : setVersions.Contains(vc.VersionId); } else if(cond is DebugCondition) { var dc = (DebugCondition)cond; if (dc.HasNoExplicitSpecification) return IsDebug; return dc.DebugId == null ? debugLevel >= dc.DebugLevel : setDebugVersions.Contains(dc.DebugId); } else if(cond is StaticIfCondition) return IsMatching((StaticIfCondition)cond,ctxt); else if(cond is NegatedDeclarationCondition) { cond = ((NegatedDeclarationCondition)cond).FirstCondition; //TODO: Ensure that there's no double negation if(cond is VersionCondition) { var vc = (VersionCondition)cond; return vc.VersionId == null ? vc.VersionNumber < versionNumber : (!setVersions.Contains(vc.VersionId) || setVersions.Contains("!"+vc.VersionId)); } else if(cond is DebugCondition) { var dc = (DebugCondition)cond; if (dc.HasNoExplicitSpecification) return !IsDebug; return dc.DebugId == null ? debugLevel < dc.DebugLevel : (!setDebugVersions.Contains(dc.DebugId) || setDebugVersions.Contains("!" + dc.DebugId)); } else if(cond is StaticIfCondition) return !IsMatching((StaticIfCondition)cond,ctxt); } // True on default -- static if's etc. will be filtered later on return true; }
public bool IsMatching(DeclarationCondition dc, ResolutionContext ctxt) { if (ctxt.CancellationToken.IsCancellationRequested) return true; var r = true; if(dc is NegatedDeclarationCondition) { var ng = (NegatedDeclarationCondition)dc; if(ng.FirstCondition is StaticIfCondition){ if(!conditionsBeingChecked.Contains(ng.FirstCondition)) conditionsBeingChecked.Add(ng.FirstCondition); else return false; r = !GlobalFlags.IsMatching((StaticIfCondition)ng.FirstCondition, ctxt); conditionsBeingChecked.Remove(ng.FirstCondition); } else r = ((GlobalFlags == null || GlobalFlags.IsMatching(dc,ctxt)) && (LocalFlags == null || LocalFlags.IsMatching(dc,ctxt))); } else { if(dc is StaticIfCondition){ if(!conditionsBeingChecked.Contains(dc)) conditionsBeingChecked.Add(dc); else return false; r = GlobalFlags.IsMatching((StaticIfCondition)dc, ctxt); conditionsBeingChecked.Remove(dc); } else r = (GlobalFlags.IsMatching(dc,ctxt) || LocalFlags.IsMatching(dc,ctxt)); } return r; }
public bool MatchesDeclarationEnvironment(DeclarationCondition dc) { return declarationCondititons.IsMatching(dc,ctxt); }
public NegatedDeclarationCondition(DeclarationCondition dc) { this.FirstCondition = dc; }
void DeclDef(DBlockNode module) { //AttributeSpecifier while (IsAttributeSpecifier()) { AttributeSpecifier(); if (t.Kind == Colon) return; } if (laKind == Semicolon) { LastParsedObject = null; Step(); return; } //ImportDeclaration if (laKind == Import) module.Add(ImportDeclaration()); //Constructor else if (laKind == (This)) module.Add(Constructor(module is DClassLike ? ((DClassLike)module).ClassType == DTokens.Struct : false)); //Destructor else if (laKind == (Tilde) && Lexer.CurrentPeekToken.Kind == (This)) module.Add(Destructor()); //Invariant else if (laKind == (Invariant)) module.Add(_Invariant()); //UnitTest else if (laKind == (Unittest)) { Step(); var dbs = new DMethod(DMethod.MethodType.Unittest); LastParsedObject = dbs; dbs.Location = t.Location; FunctionBody(dbs); dbs.EndLocation = t.EndLocation; module.Add(dbs); } /* * VersionSpecification: * version = Identifier ; * version = IntegerLiteral ; * * DebugSpecification: * debug = Identifier ; * debug = IntegerLiteral ; */ else if ((laKind == Version || laKind == Debug) && Peek(1).Kind == Assign) { Step(); var ass = new VersionDebugSpecification { Token = t.Kind, Location = t.Location }; LastParsedObject = ass; Step(); if (laKind == Literal) { Step(); ass.SpecifiedValue = new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = t.Location, EndLocation = t.EndLocation }; } else if (Expect(Identifier)) ass.SpecifiedValue = new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = t.Location, EndLocation = t.EndLocation }; Expect(Semicolon); ass.EndLocation = t.EndLocation; module.Add(ass); } else if (laKind == Version || laKind == Debug || laKind == If) { Step(); var c = new DeclarationCondition(t.Kind); LastParsedObject = c; /* * http://www.d-programming-language.org/version.html#VersionSpecification * VersionCondition: * version ( IntegerLiteral ) * version ( Identifier ) * version ( unittest ) */ if (c.IsVersionCondition && Expect(OpenParenthesis)) { if (laKind == Unittest) { Step(); c.Condition = new TokenExpression(Unittest) { Location = t.Location, EndLocation = t.EndLocation }; } else if (laKind == Literal) { Step(); c.Condition = new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = t.Location, EndLocation = t.EndLocation }; } else if (Expect(Identifier)) c.Condition = new IdentifierExpression(t.Value, t.LiteralFormat) { Location = t.Location, EndLocation = t.EndLocation }; if (Expect(CloseParenthesis)) TrackerVariables.ExpectingIdentifier = false; } /* * DebugCondition: * debug * debug ( IntegerLiteral ) * debug ( Identifier ) */ else if (c.IsDebugCondition) { if (laKind == OpenParenthesis) { Step(); if (laKind == Literal) { Step(); c.Condition = new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = t.Location, EndLocation = t.EndLocation }; } else if (Expect(Identifier)) c.Condition = new IdentifierExpression(t.Value, t.LiteralFormat) { Location = t.Location, EndLocation = t.EndLocation }; Expect(CloseParenthesis); } } /* * StaticIfCondition: * static if ( AssignExpression ) */ else if (c.IsStaticIfCondition && Expect(OpenParenthesis)) { if (DAttribute.ContainsAttribute(DeclarationAttributes, Static)) DeclarationAttributes.Clear(); else SynErr(Static, "Conditional declaration checks must be static"); c.Condition = AssignExpression(); Expect(CloseParenthesis); } if (laKind == Colon) { Step(); PushAttribute(c, true); return; } else if (laKind == OpenCurlyBrace) { BlockAttributes.Push(c); ClassBody(module, true, false); BlockAttributes.Pop(); } else { DeclarationAttributes.Push(c); DeclDef(module); } if (laKind == Else) { Step(); c = c.Clone() as DeclarationCondition; c.Negate(); if (laKind == OpenCurlyBrace) { BlockAttributes.Push(c); ClassBody(module, true, false); BlockAttributes.Pop(); } else { DeclarationAttributes.Push(c); DeclDef(module); } } } //StaticAssert else if (laKind == (Assert)) { Step(); if (DAttribute.ContainsAttribute(DeclarationAttributes, Static)) { //HACK: Assume that there's only our 'static' attribute applied to the 'if'-statement DeclarationAttributes.Clear(); } else SynErr(Static, "Static assert statements must be explicitly marked as static"); if (Expect(OpenParenthesis)) { AssignExpression(); if (laKind == (Comma)) { Step(); AssignExpression(); } Expect(CloseParenthesis); } Expect(Semicolon); } //TemplateMixinDeclaration else if (laKind == Mixin) { if (Peek(1).Kind == Template) module.Add(TemplateDeclaration(module)); //TemplateMixin else if (Lexer.CurrentPeekToken.Kind == Identifier) module.Add(TemplateMixin()); //MixinDeclaration else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis) module.Add(MixinDeclaration()); else { Step(); SynErr(Identifier); } } // { else if (laKind == (OpenCurlyBrace)) { int popCount = DeclarationAttributes.Count; while (DeclarationAttributes.Count > 0) BlockAttributes.Push(DeclarationAttributes.Pop()); ClassBody(module, true, false); for (int i = popCount; i > 0; i--) BlockAttributes.Pop(); } // Class Allocators // Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;) else if (laKind == (New)) { Step(); var dm = new DMethod(DMethod.MethodType.Allocator) { Location=t.Location }; ApplyAttributes(dm); dm.Parameters = Parameters(dm); FunctionBody(dm); dm.EndLocation = t.EndLocation; module.Add(dm); } // Class Deallocators else if (laKind == Delete) { Step(); var dm = new DMethod(DMethod.MethodType.Deallocator) { Location=t.Location }; dm.Name = "delete"; ApplyAttributes(dm); dm.Parameters = Parameters(dm); FunctionBody(dm); dm.EndLocation = t.EndLocation; module.Add(dm); } // else: else module.AddRange(Declaration(module)); }
public void Add(DeclarationCondition cond) { if(cond is VersionCondition) { var vc = (VersionCondition)cond; if (vc.VersionId == null) AddVersionCondition(vc.VersionNumber); else AddVersionCondition(vc.VersionId); } else if(cond is DebugCondition) { var dc = (DebugCondition)cond; if (dc.DebugId == null) AddDebugCondition(dc.DebugLevel); else AddDebugCondition(dc.DebugId); } else if(cond is NegatedDeclarationCondition) { cond = ((NegatedDeclarationCondition)cond).FirstCondition; if (cond is VersionCondition) { var vc = (VersionCondition)cond; if (vc.VersionId != null) /*AddVersionCondition(vc.VersionNumber); -- TODO How are "negated" version numbers handled? else*/ AddVersionCondition("!"+vc.VersionId); } else if (cond is DebugCondition) { var dc = (DebugCondition)cond; if (dc.DebugId != null) /*AddDebugCondition(dc.DebugLevel); else*/ AddDebugCondition("!"+dc.DebugId); } } }