public virtual void Visit(MemberFunctionAttributeDecl td) { VisitInner(td); if (td.InnerType != null) { td.InnerType.Accept(this); } }
bool HandleDecl(TemplateTypeParameter p, MemberFunctionAttributeDecl m, AbstractType r) { if (r == null || r.Modifier == 0) return false; // Modifiers must be equal on both sides if (m.Modifier != r.Modifier) return false; // Strip modifier, but: immutable(int[]) becomes immutable(int)[] ?! AbstractType newR; if (r is AssocArrayType) { var aa = r as AssocArrayType; var clonedValueType = aa.Modifier != r.Modifier ? aa.ValueType.Clone(false) : aa.ValueType; clonedValueType.Modifier = r.Modifier; var at = aa as ArrayType; if (at != null) newR = at.IsStaticArray ? new ArrayType(clonedValueType, at.FixedLength, r.DeclarationOrExpressionBase) : new ArrayType(clonedValueType, r.DeclarationOrExpressionBase); else newR = new AssocArrayType(clonedValueType, aa.KeyType, r.DeclarationOrExpressionBase); } else { newR = r.Clone(false); newR.Modifier = 0; } // Now compare the type inside the parentheses with the given type 'r' return m.InnerType != null && HandleDecl(p, m.InnerType, newR); }
ITypeDeclaration BasicType() { bool isModuleScoped = laKind == Dot; if (isModuleScoped) Step(); ITypeDeclaration td = null; if (IsBasicType(laKind)) { Step(); return new DTokenDeclaration(t.Kind) { Location=t.Location, EndLocation=t.EndLocation }; } if (IsMemberFunctionAttribute(laKind)) { Step(); var md = new MemberFunctionAttributeDecl(t.Kind) { Location=t.Location }; bool p = false; if (laKind == OpenParenthesis) { Step(); p = true; if (IsEOF) return md; } // e.g. cast(const) if (laKind != CloseParenthesis) md.InnerType = p ? Type() : BasicType(); if (p) Expect(CloseParenthesis); md.EndLocation = t.EndLocation; return md; } //TODO if (laKind == Ref) Step(); if (laKind == (Typeof)) { td = TypeOf(); if (laKind != Dot) return td; } else if (laKind == __vector) { td = Vector(); if (laKind != Dot) return td; } if (AllowWeakTypeParsing && laKind != Identifier) return null; if (td == null) td = IdentifierList(); else td.InnerMost = IdentifierList(); if(isModuleScoped && td != null) { var innerMost = td.InnerMost; if (innerMost is IdentifierDeclaration) ((IdentifierDeclaration)innerMost).ModuleScoped = true; else if (innerMost is TemplateInstanceExpression) ((TemplateInstanceExpression)innerMost).ModuleScopedIdentifier = true; } return td; }
public virtual void Visit(MemberFunctionAttributeDecl td) { VisitInner(td); if (td.InnerType != null) td.InnerType.Accept(this); }
ITypeDeclaration BasicType() { ITypeDeclaration td = null; if (BasicTypes[laKind]) { Step(); return new DTokenDeclaration(t.Kind) { Location=t.Location, EndLocation=t.EndLocation }; } if (MemberFunctionAttribute[laKind]) { Step(); var md = new MemberFunctionAttributeDecl(t.Kind) { Location=t.Location }; bool p = false; if (laKind == OpenParenthesis) { Step(); p = true; } // e.g. cast(const) if (laKind != CloseParenthesis) md.InnerType = Type(); if (p) Expect(CloseParenthesis); md.EndLocation = t.EndLocation; return md; } //TODO if (laKind == Ref) Step(); if (laKind == (Typeof)) { td = TypeOf(); if (laKind != (Dot)) return td; } if (laKind == (Dot)) Step(); if (AllowWeakTypeParsing&& laKind != Identifier) return null; if (td == null) td = IdentifierList(); else td.InnerMost = IdentifierList(); // A type is never a declaration identifier if(td==null) ExpectingIdentifier = false; return td; }
IExpression PrimaryExpression(IBlockNode Scope=null) { bool isModuleScoped = false; // For minimizing possible overhead, skip 'useless' tokens like an initial dot <<< TODO if (isModuleScoped= laKind == Dot) Step(); if (laKind == __FILE__ || laKind == __LINE__) { Step(); object id = null; if (t.Kind == __FILE__ && doc != null) id = doc.FileName; else if(t.Kind==__LINE__) id = t.line; return new IdentifierExpression(id) { Location=t.Location, EndLocation=t.EndLocation }; } // Dollar (== Array length expression) if (laKind == Dollar) { Step(); return new TokenExpression(laKind) { Location = t.Location, EndLocation = t.EndLocation }; } // TemplateInstance if (laKind == (Identifier) && Lexer.CurrentPeekToken.Kind == (Not) && (Peek().Kind != Is && Lexer.CurrentPeekToken.Kind != In) /* Very important: The 'template' could be a '!is'/'!in' expression - With two tokens each! */) return TemplateInstance(); // Identifier if (laKind == (Identifier)) { Step(); return new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation }; } // SpecialTokens (this,super,null,true,false,$) // $ has been handled before if (laKind == (This) || laKind == (Super) || laKind == (Null) || laKind == (True) || laKind == (False)) { Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; } #region Literal if (laKind == Literal) { Step(); var startLoc = t.Location; // Concatenate multiple string literals here if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { var a = t.LiteralValue as string; while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { Step(); a += t.LiteralValue as string; } return new IdentifierExpression(a, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation }; } //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation }; return new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation }; } #endregion #region ArrayLiteral | AssocArrayLiteral if (laKind == (OpenSquareBracket)) { Step(); var startLoc = t.Location; // Empty array literal if (laKind == CloseSquareBracket) { Step(); return new ArrayLiteralExpression() {Location=startLoc, EndLocation = t.EndLocation }; } var firstExpression = AssignExpression(); // Associtative array if (laKind == Colon) { Step(); var ae = new AssocArrayExpression() { Location=startLoc}; LastParsedObject = ae; var firstValueExpression = AssignExpression(); ae.KeyValuePairs.Add(firstExpression, firstValueExpression); while (laKind == Comma) { Step(); var keyExpr = AssignExpression(); Expect(Colon); var valueExpr = AssignExpression(); ae.KeyValuePairs.Add(keyExpr, valueExpr); } Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } else // Normal array literal { var ae = new ArrayLiteralExpression() { Location=startLoc}; LastParsedObject = ae; var expressions = new List<IExpression>(); expressions.Add(firstExpression); while (laKind == Comma) { Step(); if (laKind == CloseSquareBracket) // And again, empty expressions are allowed break; expressions.Add(AssignExpression()); } ae.Expressions = expressions; Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } } #endregion #region FunctionLiteral if (laKind == Delegate || laKind == Function || laKind == OpenCurlyBrace || (laKind == OpenParenthesis && IsFunctionLiteral())) { var fl = new FunctionLiteral() { Location=la.Location}; LastParsedObject = fl; fl.AnonymousMethod.StartLocation = la.Location; if (laKind == Delegate || laKind == Function) { Step(); fl.LiteralToken = t.Kind; } // file.d:1248 /* listdir (".", delegate bool (DirEntry * de) { auto s = std.string.format("%s : c %s, w %s, a %s", de.name, toUTCString (de.creationTime), toUTCString (de.lastWriteTime), toUTCString (de.lastAccessTime)); return true; } ); */ if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate { if (!MemberFunctionAttribute[laKind] && Lexer.CurrentPeekToken.Kind == OpenParenthesis) fl.AnonymousMethod.Type = BasicType(); else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace) fl.AnonymousMethod.Type = Type(); if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); } FunctionBody(fl.AnonymousMethod); fl.EndLocation = t.EndLocation; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; } #endregion #region AssertExpression if (laKind == (Assert)) { Step(); var startLoc = t.Location; Expect(OpenParenthesis); var ce = new AssertExpression() { Location=startLoc}; LastParsedObject = ce; var exprs = new List<IExpression>(); exprs.Add(AssignExpression()); if (laKind == (Comma)) { Step(); exprs.Add(AssignExpression()); } ce.AssignExpressions = exprs.ToArray(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion #region MixinExpression | ImportExpression if (laKind == Mixin) { Step(); var e = new MixinExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } if (laKind == Import) { Step(); var e = new ImportExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } #endregion if (laKind == (Typeof)) { var startLoc = la.Location; return new TypeDeclarationExpression(TypeOf()) {Location=startLoc,EndLocation=t.EndLocation}; } // TypeidExpression if (laKind == (Typeid)) { Step(); var ce = new TypeidExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); AllowWeakTypeParsing = true; ce.Type = Type(); AllowWeakTypeParsing = false; if (ce.Type==null) ce.Expression = AssignExpression(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #region IsExpression if (laKind == Is) { Step(); var ce = new IsExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); var LookAheadBackup = la; AllowWeakTypeParsing = true; ce.TestedType = Type(); AllowWeakTypeParsing = false; if (ce.TestedType!=null && laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal || Lexer.CurrentPeekToken.Kind == Colon)) { Step(); ce.TypeAliasIdentifier = strVal; } else // D Language specs mistake: In an IsExpression there also can be expressions! if(ce.TestedType==null || !(laKind==CloseParenthesis || laKind==Equal||laKind==Colon)) { // Reset lookahead token to prior position la = LookAheadBackup; // Reset wrongly parsed type declaration ce.TestedType = null; ce.TestedExpression = ConditionalExpression(); } if(ce.TestedExpression==null && ce.TestedType==null) SynErr(laKind,"In an IsExpression, either a type or an expression is required!"); if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } if (laKind == Colon || laKind == Equal) { Step(); ce.EqualityTest = t.Kind == Equal; } else if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } /* TypeSpecialization: Type struct union class interface enum function delegate super const immutable inout shared return */ if (ClassLike[laKind] || laKind==Typedef || // typedef is possible although it's not yet documented in the syntax docs laKind==Enum || laKind==Delegate || laKind==Function || laKind==Super || laKind==Return) { Step(); ce.TypeSpecializationToken = t.Kind; } else ce.TypeSpecialization = Type(); if (laKind == Comma) { Step(); ce.TemplateParameterList = TemplateParameterList(false); } Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion // ( Expression ) if (laKind == OpenParenthesis) { Step(); var ret = new SurroundingParenthesesExpression() {Location=t.Location }; LastParsedObject = ret; ret.Expression = Expression(); Expect(CloseParenthesis); ret.EndLocation = t.EndLocation; return ret; } // TraitsExpression if (laKind == (__traits)) return TraitsExpression(); #region BasicType . Identifier if (laKind == (Const) || laKind == (Immutable) || laKind == (Shared) || laKind == (InOut) || BasicTypes[laKind]) { Step(); var startLoc = t.Location; IExpression left = null; if (!BasicTypes[t.Kind]) { int tk = t.Kind; // Put an artificial parenthesis around the following type declaration if (laKind != OpenParenthesis) { var mttd = new MemberFunctionAttributeDecl(tk); LastParsedObject = mttd; mttd.InnerType = Type(); left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation }; } else { Expect(OpenParenthesis); var mttd = new MemberFunctionAttributeDecl(tk); LastParsedObject = mttd; mttd.InnerType = Type(); Expect(CloseParenthesis); left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation }; } } else left = new TokenExpression(t.Kind) {Location=startLoc,EndLocation=t.EndLocation }; if (laKind == (Dot) && Peek(1).Kind==Identifier) { Step(); Step(); var meaex = new PostfixExpression_Access() { PostfixForeExpression=left, TemplateOrIdentifier=new IdentifierDeclaration(t.Value),EndLocation=t.EndLocation }; return meaex; } return left; } #endregion // TODO? Expressions can of course be empty... //return null; SynErr(Identifier); Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; }
public static AbstractType Resolve(MemberFunctionAttributeDecl attrDecl, ResolutionContext ctxt) { if (attrDecl != null) { var ret = Resolve(attrDecl.InnerType, ctxt); ctxt.CheckForSingleResult(ret, attrDecl.InnerType); if (ret != null && ret.Length != 0 && ret[0] != null) { ret[0].Modifier = attrDecl.Modifier; return ret[0]; } } return null; }
bool HandleDecl(TemplateTypeParameter p, MemberFunctionAttributeDecl m, AbstractType r) { if (r == null || r.Modifier == 0) return false; // Modifiers must be equal on both sides if (m.Modifier != r.Modifier) return false; // Now compare the type inside the parentheses with the given type 'r' return m.InnerType != null && HandleDecl(p, m.InnerType, r); }