public virtual void Visit(DelegateDeclaration td) { VisitInner(td); // ReturnType == InnerDeclaration if (td.Modifiers != null && td.Modifiers.Length != 0) { foreach (var attr in td.Modifiers) { attr.Accept(this); } } foreach (var p in td.Parameters) { p.Accept(this); } }
public static TooltipInformation Generate(DelegateDeclaration dd, int currentParam = -1) { var sb = new StringBuilder("<i>(Delegate)</i> "); if (dd.ReturnType != null) sb.Append(dd.ReturnType.ToString(true)).Append(' '); if (dd.IsFunction) sb.Append("function"); else sb.Append("delegate"); sb.Append('('); if (dd.Parameters != null && dd.Parameters.Count != 0) { for (int i = 0; i < dd.Parameters.Count; i++) { var p = dd.Parameters[i] as DNode; if (i == currentParam) { sb.Append("<u>"); sb.Append(p.ToString(false)); sb.Append("</u>,"); } else sb.Append(p.ToString(false)).Append(','); } sb.Remove(sb.Length - 1, 1); } sb.Append(')'); var tti = new TooltipInformation(); tti.SignatureMarkup = sb.ToString(); return tti; }
public DelegateType(AbstractType ReturnType,DelegateDeclaration Declaration, IEnumerable<AbstractType> Parameters = null) : base(ReturnType, Declaration) { this.IsFunction = Declaration.IsFunction; if (Parameters is AbstractType[]) this.Parameters = (AbstractType[])Parameters; else if(Parameters!=null) this.Parameters = Parameters.ToArray(); }
bool HandleDecl(TemplateTypeParameter par, DelegateDeclaration d, DelegateType dr) { // Delegate literals or other expressions are not allowed if(dr==null || dr.IsFunctionLiteral) return false; var dr_decl = (DelegateDeclaration)dr.DeclarationOrExpressionBase; // Compare return types if( d.IsFunction == dr_decl.IsFunction && dr.ReturnType != null && HandleDecl(par, d.ReturnType,dr.ReturnType)) { // If no delegate args expected, it's valid if ((d.Parameters == null || d.Parameters.Count == 0) && dr_decl.Parameters == null || dr_decl.Parameters.Count == 0) return true; // If parameter counts unequal, return false else if (d.Parameters == null || dr_decl.Parameters == null || d.Parameters.Count != dr_decl.Parameters.Count) return false; // Compare & Evaluate each expected with given parameter var dr_paramEnum = dr_decl.Parameters.GetEnumerator(); foreach (var p in d.Parameters) { // Compare attributes with each other if (p is DNode) { if (!(dr_paramEnum.Current is DNode)) return false; var dn = (DNode)p; var dn_arg = (DNode)dr_paramEnum.Current; if ((dn.Attributes == null || dn.Attributes.Count == 0) && (dn_arg.Attributes == null || dn_arg.Attributes.Count == 0)) return true; else if (dn.Attributes == null || dn_arg.Attributes == null || dn.Attributes.Count != dn_arg.Attributes.Count) return false; foreach (var attr in dn.Attributes) { if(!dn_arg.ContainsAttribute(attr)) return false; } } // Compare types if (p.Type!=null && dr_paramEnum.MoveNext() && dr_paramEnum.Current.Type!=null) { var dr_resolvedParamType = TypeDeclarationResolver.ResolveSingle(dr_paramEnum.Current.Type, ctxt); if (dr_resolvedParamType == null || !HandleDecl(par, p.Type, dr_resolvedParamType)) return false; } else return false; } } return false; }
/// <summary> /// Add some syntax possibilities here /// int (x); /// int(*foo); /// This way of declaring function pointers is deprecated /// </summary> void OldCStyleFunctionPointer(DNode ret, bool IsParam) { Step(); //SynErr(OpenParenthesis,"C-style function pointers are deprecated. Use the function() syntax instead."); // Only deprecated in D2 var cd = new DelegateDeclaration() as ITypeDeclaration; ret.Type = cd; var deleg = cd as DelegateDeclaration; /* * Parse all basictype2's that are following the initial '(' */ while (IsBasicType2()) { var ttd = BasicType2(); if (deleg.ReturnType == null) deleg.ReturnType = ttd; else { if(ttd!=null) ttd.InnerDeclaration = deleg.ReturnType; deleg.ReturnType = ttd; } } /* * Here can be an identifier with some optional DeclaratorSuffixes */ if (laKind != (CloseParenthesis)) { if (IsParam && laKind != (Identifier)) { /* If this Declarator is a parameter of a function, don't expect anything here * except a '*' that means that here's an anonymous function pointer */ if (t.Kind != (Times)) SynErr(Times); } else { if(Expect(Identifier)) ret.Name = t.Value; /* * Just here suffixes can follow! */ if (laKind != (CloseParenthesis)) { DeclaratorSuffixes(ret); } } } ret.Type = cd; Expect(CloseParenthesis); }
ITypeDeclaration BasicType2() { // * if (laKind == (Times)) { Step(); return new PointerDecl() { Location=t.Location, EndLocation=t.EndLocation }; } // [ ... ] else if (laKind == (OpenSquareBracket)) { var startLoc = la.Location; Step(); // [ ] if (laKind == (CloseSquareBracket)) { Step(); return new ArrayDecl() { Location=startLoc, EndLocation=t.EndLocation }; } ITypeDeclaration cd = null; // [ Type ] Lexer.PushLookAheadBackup(); bool weaktype = AllowWeakTypeParsing; AllowWeakTypeParsing = true; var keyType = Type(); AllowWeakTypeParsing = weaktype; if (keyType != null && laKind == CloseSquareBracket && !(keyType is IdentifierDeclaration)) { //HACK: Both new int[size_t] as well as new int[someConstNumber] are legal. So better treat them as expressions. cd = new ArrayDecl() { KeyType = keyType, ClampsEmpty = false, Location = startLoc }; Lexer.PopLookAheadBackup(); } else { Lexer.RestoreLookAheadBackup(); var fromExpression = AssignExpression(); // [ AssignExpression .. AssignExpression ] if (laKind == DoubleDot) { Step(); cd = new ArrayDecl() { Location=startLoc, ClampsEmpty=false, KeyType=null, KeyExpression= new PostfixExpression_Slice() { FromExpression=fromExpression, ToExpression=AssignExpression()}}; } else cd = new ArrayDecl() { KeyType=null, KeyExpression=fromExpression,ClampsEmpty=false,Location=startLoc }; } if ((AllowWeakTypeParsing && laKind != CloseSquareBracket) || IsEOF) return null; Expect(CloseSquareBracket); if(cd!=null) cd.EndLocation = t.EndLocation; return cd; } // delegate | function else if (laKind == (Delegate) || laKind == (Function)) { Step(); var dd = new DelegateDeclaration() { Location=t.Location}; dd.IsFunction = t.Kind == Function; if (AllowWeakTypeParsing && laKind != OpenParenthesis) return null; dd.Parameters = Parameters(null); var attributes = new List<DAttribute>(); FunctionAttributes(ref attributes); dd.Modifiers= attributes.Count > 0 ? attributes.ToArray() : null; dd.EndLocation = t.EndLocation; return dd; } else SynErr(Identifier); return null; }
public virtual void Visit(DelegateDeclaration td) { VisitInner(td); // ReturnType == InnerDeclaration if (td.Modifiers != null && td.Modifiers.Length != 0) foreach (var attr in td.Modifiers) if(attr != null) attr.Accept(this); foreach (var p in td.Parameters) if(p != null) p.Accept(this); }
/// <summary> /// Parses a type declarator /// </summary> /// <returns>A dummy node that contains the return type, the variable name and possible parameters of a function declaration</returns> DNode Declarator(ITypeDeclaration basicType,bool IsParam) { DNode ret = new DVariable() { Type=basicType, Location = la.Location }; LastParsedObject = ret; ITypeDeclaration ttd = null; while (IsBasicType2()) { if (ret.Type == null) ret.Type = BasicType2(); else { ttd = BasicType2(); if(ttd!=null) ttd.InnerDeclaration = ret.Type; ret.Type = ttd; } } /* * Add some syntax possibilities here * like * int (x); * int(*foo); */ #region This way of declaring function pointers is deprecated if (laKind == (OpenParenthesis)) { Step(); //SynErr(OpenParenthesis,"C-style function pointers are deprecated. Use the function() syntax instead."); // Only deprecated in D2 var cd = new DelegateDeclaration() as ITypeDeclaration; LastParsedObject = cd; ret.Type = cd; var deleg = cd as DelegateDeclaration; /* * Parse all basictype2's that are following the initial '(' */ while (IsBasicType2()) { ttd = BasicType2(); if (deleg.ReturnType == null) deleg.ReturnType = ttd; else { if(ttd!=null) ttd.InnerDeclaration = deleg.ReturnType; deleg.ReturnType = ttd; } } /* * Here can be an identifier with some optional DeclaratorSuffixes */ if (laKind != (CloseParenthesis)) { if (IsParam && laKind != (Identifier)) { /* If this Declarator is a parameter of a function, don't expect anything here * except a '*' that means that here's an anonymous function pointer */ if (t.Kind != (Times)) SynErr(Times); } else { if(Expect(Identifier)) ret.Name = t.Value; /* * Just here suffixes can follow! */ if (laKind != (CloseParenthesis)) { ITemplateParameter[] _unused2 = null; List<INode> _unused = null; List<DAttribute> _unused3 = new List<DAttribute>(); ttd = DeclaratorSuffixes(out _unused2, out _unused, _unused3); if (ttd != null) { ttd.InnerDeclaration = cd; cd = ttd; } } } } ret.Type = cd; Expect(CloseParenthesis); } #endregion else { // On external function declarations, no parameter names are required. // extern void Cfoo(HANDLE,char**); if (IsParam && laKind != (Identifier)) { if(ret.Type!=null) ExpectingIdentifier = true; return ret; } if (Expect(Identifier)) { ret.Name = t.Value; ret.NameLocation = t.Location; } else { // Code error! - to prevent infinite declaration loops, step one token forward anyway! Step(); return ret; } } if (IsDeclaratorSuffix || MemberFunctionAttribute[laKind]) { var dm = new DMethod(); LastParsedObject = dm; // DeclaratorSuffixes List<INode> _Parameters; ttd = DeclaratorSuffixes(out (ret as DNode).TemplateParameters, out _Parameters, ret.Attributes); if (ttd != null) { ttd.InnerDeclaration = ret.Type; ret.Type = ttd; } if (_Parameters == null) LastParsedObject = ret; if (_Parameters != null) { dm.AssignFrom(ret); dm.Parameters = _Parameters; foreach (var pp in dm.Parameters) pp.Parent = dm; return dm; } } return ret; }
ITypeDeclaration BasicType2() { // * if (laKind == (Times)) { Step(); return new PointerDecl() { Location=t.Location, EndLocation=t.EndLocation }; } // [ ... ] else if (laKind == (OpenSquareBracket)) { var startLoc = la.Location; Step(); // [ ] if (laKind == (CloseSquareBracket)) { Step(); return new ArrayDecl() { Location=startLoc, EndLocation=t.EndLocation }; } ITypeDeclaration cd = null; // [ Type ] if (!IsAssignExpression()) { var la_backup = la; bool weaktype = AllowWeakTypeParsing; AllowWeakTypeParsing = true; var keyType = Type(); AllowWeakTypeParsing = weaktype; if (keyType != null && laKind == CloseSquareBracket) cd = new ArrayDecl() { KeyType = keyType, Location=startLoc }; else la = la_backup; } if(cd==null) { var fromExpression = AssignExpression(); // [ AssignExpression .. AssignExpression ] if (laKind == DoubleDot) { Step(); cd = new ArrayDecl() { Location=startLoc ,KeyExpression= new PostfixExpression_Slice() { FromExpression=fromExpression, ToExpression=AssignExpression()}}; } else cd = new ArrayDecl() { KeyExpression=fromExpression,Location=startLoc }; } if (AllowWeakTypeParsing && laKind != CloseSquareBracket) return null; Expect(CloseSquareBracket); if(cd!=null) cd.EndLocation = t.EndLocation; return cd; } // delegate | function else if (laKind == (Delegate) || laKind == (Function)) { Step(); ITypeDeclaration td = null; var dd = new DelegateDeclaration() { Location=t.Location}; dd.IsFunction = t.Kind == Function; dd.Parameters = Parameters(null); td = dd; //TODO: add attributes to declaration while (FunctionAttribute[laKind]) { Step(); td = new DTokenDeclaration(t.Kind, td) { Location=t.Location, EndLocation=t.EndLocation }; } td.EndLocation = t.EndLocation; return td; } else SynErr(Identifier); return null; }
public static DelegateType Resolve(DelegateDeclaration dg, ResolutionContext ctxt) { var returnTypes = Resolve(dg.ReturnType, ctxt); ctxt.CheckForSingleResult(returnTypes, dg.ReturnType); if (returnTypes != null && returnTypes.Length != 0) { List<AbstractType> paramTypes=null; if(dg.Parameters!=null && dg.Parameters.Count != 0) { paramTypes = new List<AbstractType>(); foreach(var par in dg.Parameters) paramTypes.Add(ResolveSingle(par.Type, ctxt)); } return new DelegateType(returnTypes[0], dg, paramTypes); } return null; }
public static DelegateType Resolve(DelegateDeclaration dg, ResolverContextStack ctxt) { var returnTypes = Resolve(dg.ReturnType, ctxt); ctxt.CheckForSingleResult(returnTypes, dg.ReturnType); if (returnTypes != null && returnTypes.Length != 0) return new DelegateType(returnTypes[0], dg); // Parameter types will be resolved later on return null; }