void parseThread(object pcl_shared) { DMethod dm = null; var pcl = (ParseCacheList)pcl_shared; var ctxt = new ResolverContextStack(pcl, new ResolverContext()); ctxt.ContextIndependentOptions |= ResolutionOptions.StopAfterFirstOverloads; while (queue.Count != 0) { lock (queue) { if (queue.Count == 0) { return; } dm = queue.Pop(); } ctxt.CurrentContext.ScopedBlock = dm; var firstArg_result = TypeDeclarationResolver.Resolve(dm.Parameters[0].Type, ctxt); if (firstArg_result != null && firstArg_result.Length != 0) { lock (CachedMethods) CachedMethods[dm] = firstArg_result[0]; } } }
void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null) { if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null) { var pop = ctxt.ScopedBlock != dm; if (pop) { ctxt.PushNewScope(dm); } var t = TypeDeclarationResolver.ResolveSingle(dm.Parameters [0].Type, ctxt); if (ResultComparer.IsImplicitlyConvertible(firstArgument, t, ctxt)) { var res = alreadyResolvedMethod ?? new MemberSymbol(dm, null, sr); res.Tag = new UfcsTag { firstArgument = firstArgument }; matches.Add(res); } if (pop) { ctxt.Pop(); } } }
public static DMethod ParseMethodDeclarationHeader(string headerCode, out ITypeDeclaration identifierChain) { using (var sr = new StringReader(headerCode)) { var p = Create(sr); p.Step(); var n = new DMethod(); p.CheckForStorageClasses(p.doc); p.ApplyAttributes(n); p.FunctionAttributes(n); n.Type = p.Type(null); identifierChain = p.IdentifierList(); if (identifierChain is IdentifierDeclaration) { n.NameHash = (identifierChain as IdentifierDeclaration).IdHash; } n.Parameters = p.Parameters(n); return(n); } }
public string Visit(DMethod n) { if (n.ContainsPropertyAttribute(BuiltInAtAttribute.BuiltInAttributes.Property)) { return("PROP"); } return("MTHD"); }
public override void Visit(DMethod n) { if (n.SpecialType != DMethod.MethodType.AnonymousDelegate && n.SpecialType != DMethod.MethodType.Lambda) { base.Visit(n); } }
public static long Measure(DMethod method) { Stopwatch sw = new Stopwatch(); sw.Start(); method(); sw.Stop(); return(sw.ElapsedMilliseconds); }
public IconId Visit(DMethod n) { //TODO: Getter or setter functions should be declared as a >single< property only if (n.ContainsPropertyAttribute()) { return(iconIdWithProtectionAttr(n, "property")); } return(methodIconIdWithProtectionAttr(n)); }
public override void Visit(DMethod bn) { var back = ctxt.ScopedBlock; using (ctxt.Push(bn)) { if (ctxt.ScopedBlock != back) { OnScopedBlockChanged(bn); } base.Visit(bn); } }
public string Visit(DMethod n) { if (n.ContainsPropertyAttribute(BuiltInAtAttribute.BuiltInAttributes.Property)) { return("PROP"); } if (n.Parent is DClassLike) { return("MTHD"); } else { return("FUNC"); } }
public override void Visit(DMethod dm) { var back = ctxt.ScopedBlock; if (back != dm) { ctxt.PushNewScope(dm); OnScopedBlockChanged(dm); } base.Visit(dm); if (back != dm) { ctxt.Pop(); } }
protected override BlockStatement PrepareParsing(BlockStatement bs, CodeLocation startLoc) { finalParentMethod = bs.ParentNode as DMethod; tempParentBlock = new DMethod(); //new DBlockNode(); tempParentBlock.Attributes = finalParentMethod.Attributes; // assign given attributes to the temporary block for allowing the completion to check whether static or non-static items may be shown var tempBlockStmt = new BlockStatement { ParentNode = tempParentBlock }; tempParentBlock.Body = tempBlockStmt; tempBlockStmt.Location = startLoc; tempParentBlock.Location = startLoc; return(tempBlockStmt); }
public virtual void Visit(DMethod n) { VisitDNode(n); if(n.Parameters!=null) foreach (var par in n.Parameters) par.Accept(this); if (n.In != null) n.In.Accept(this); if (n.Body != null) n.Body.Accept(this); if (n.Out != null) n.Out.Accept(this); if (n.OutResultVariable != null) n.OutResultVariable.Accept(this); }
public override void Visit(DMethod dm) { base.Visit(dm); Dictionary <int, byte> tc; if (!TypeCache.TryGetValue(dm, out tc)) { return; } // Reset locals if (dm.Parameters != null) { foreach (var n in dm.Parameters) { tc [n.NameHash] = 0; } } }
void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null) { if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null) { var loc = dm.Body != null ? dm.Body.Location : dm.Location; using (alreadyResolvedMethod != null ? ctxt.Push(alreadyResolvedMethod, loc) : ctxt.Push(dm, loc)) { var t = TypeDeclarationResolver.ResolveSingle(dm.Parameters[0].Type, ctxt); if (ResultComparer.IsImplicitlyConvertible(firstArgument, t, ctxt)) { var res = alreadyResolvedMethod ?? TypeDeclarationResolver.HandleNodeMatch(dm, ctxt, typeBase: sr); res.Tag = new UfcsTag { firstArgument = firstArgument }; matches.Add(res); } } } }
void parseThread(object pcl_shared) { Interlocked.Increment(ref parsingThreads); DMethod dm = null; try{ var ctxt = ResolutionContext.Create((ParseCacheView)pcl_shared, gFlags_shared, null); int count = 0; while (queue.TryPop(out dm)) { ctxt.CurrentContext.Set(dm); var firstArg_result = TypeDeclarationResolver.Resolve(dm.Parameters[0].Type, ctxt); if (firstArg_result != null && firstArg_result.Length != 0) { count++; CachedMethods[dm] = firstArg_result[0]; } } Interlocked.Add(ref methodCount, count); } catch (Exception ex) { if (CompletionOptions.Instance.DumpResolutionErrors) { Console.WriteLine("Исключение при анализе метода \"" + (dm != null ? dm.ToString(true) : "<no method>") + "\":"); Console.WriteLine(ex.Message); Console.WriteLine("-------------------------------"); Console.WriteLine("Трассировка стека"); Console.WriteLine(ex.StackTrace); Console.WriteLine("-------------------------------"); } } finally { if (Interlocked.Decrement(ref parsingThreads) < 1) { noticeFinish(); } } }
/// <summary> /// /// </summary> /// <param name="dm"></param> /// <param name="args"></param> /// <param name="baseValueProvider">Required for evaluating missing default parameters.</param> public static bool AssignCallArgumentsToIC(DMethod dm, ISymbolValue[] args, AbstractSymbolValueProvider baseValueProvider, out Dictionary <DVariable, ISymbolValue> targetArgs) { targetArgs = new Dictionary <DVariable, ISymbolValue>(); var argsRemaining = args != null ? args.Length : 0; int argu = 0; for (int para = 0; para < dm.Parameters.Count; para++) { var par = dm.Parameters[para] as DVariable; if (par.Type is VarArgDecl && argsRemaining > 0) { var va_args = new ISemantic[argsRemaining]; args.CopyTo(va_args, argu); argsRemaining = 0; //TODO: Assign a value tuple to par if (++para < dm.Parameters.Count) { return(false); } } if (argsRemaining > 0) { targetArgs[par] = args[argu++]; argsRemaining--; } else if (par.Initializer != null) { targetArgs[par] = Evaluation.EvaluateValue(par.Initializer, baseValueProvider); } else { return(false); } } return(argsRemaining == 0); }
public override void Visit (DMethod dm) { var back = ctxt.ScopedBlock; if (back != dm) { ctxt.PushNewScope (dm); OnScopedBlockChanged (dm); } base.Visit (dm); if(back != dm) ctxt.Pop (); }
string GetMethodMarkup(DMethod dm, string[] parameterMarkup, int currentParameter) { var s = ""; switch (dm.SpecialType) { case DMethod.MethodType.Constructor: s = "(Constructor) "; break; case DMethod.MethodType.Destructor: s = "(Destructor) "; break; case DMethod.MethodType.Allocator: s = "(Allocator) "; break; } if (dm.Attributes.Count > 0) { s = dm.AttributeString + ' '; } s += dm.Name; // Template parameters if (dm.TemplateParameters != null && dm.TemplateParameters.Length > 0) { s += "("; if (args.IsTemplateInstanceArguments) { s += string.Join(",", parameterMarkup); } else { foreach (var p in dm.TemplateParameters) { s += p.ToString() + ","; } } s = s.Trim(',') + ")"; } // Parameters s += "("; if (!args.IsTemplateInstanceArguments) { s += string.Join(",", parameterMarkup); } else { foreach (var p in dm.Parameters) { s += p.ToString() + ","; } } return(s.Trim(',') + ")"); }
void FunctionBody(DMethod par) { if (laKind == Semicolon) // Abstract or virtual functions { Step(); par.Description += CheckForPostSemicolonComment(); par.EndLocation = t.EndLocation; return; } var stk_Backup = BlockAttributes; BlockAttributes = new Stack<DAttribute> (); while ( (laKind == In && par.In == null) || (laKind == Out && par.Out == null)) { if (laKind == In) { Step(); par.InToken = t.Location; par.In = BlockStatement(par); } if (laKind == Out) { Step(); par.OutToken = t.Location; if (laKind == OpenParenthesis) { Step(); if (Expect(Identifier)) { par.OutResultVariable = new IdentifierDeclaration(t.Value) { Location=t.Location, EndLocation=t.EndLocation }; } Expect(CloseParenthesis); } par.Out = BlockStatement(par); } } // Although there can be in&out constraints, there doesn't have to be a direct body definition. Used on abstract class/interface methods. if (laKind == Body){ Step(); par.BodyToken = t.Location; } if ((par.In==null && par.Out==null) || laKind == OpenCurlyBrace) { par.Body = BlockStatement(par); } BlockAttributes = stk_Backup; par.EndLocation = t.EndLocation; }
INode Destructor() { Expect(Tilde); var dm = new DMethod{ Location = t.Location, NameLocation = la.Location }; Expect(This); LastParsedObject = dm; dm.SpecialType = DMethod.MethodType.Destructor; dm.Name = "~this"; if (IsTemplateParameterList()) TemplateParameterList(dm); dm.Parameters = Parameters(dm); if (laKind == (If)) Constraint(dm); FunctionBody(dm); return dm; }
public static DMethod ParseMethodDeclarationHeader(string headerCode, out ITypeDeclaration identifierChain) { using(var sr = new StringReader(headerCode)) { var p = Create(sr); p.Step(); var n = new DMethod(); p.CheckForStorageClasses(p.doc); p.ApplyAttributes(n); p.FunctionAttributes(n); n.Type = p.Type(); identifierChain = p.IdentifierList(); if(identifierChain is IdentifierDeclaration) n.NameHash = (identifierChain as IdentifierDeclaration).IdHash; n.Parameters = p.Parameters(n); return n; } }
AbstractType Type(char type = '\0') { if(type == '\0') type = (char)r.Read(); switch(type) { case 'O': var t = Type(); t.Modifier = DTokens.Shared; return t; case 'x': t = Type(); t.Modifier = DTokens.Const; return t; case 'y': t = Type(); t.Modifier = DTokens.Immutable; return t; case 'N': switch(r.Read()) { case 'g': t = Type(); t.Modifier = DTokens.InOut; return t; case 'e': // TypeNewArray ? Type(); return null; } break; case 'A': return new ArrayType(Type(), null); case 'G': var len = (int)Number(); return new ArrayType(Type(), len, null); case 'H': var keyType = Type(); t = Type(); return new AssocArrayType(t, keyType, null); case 'P': return new PointerType(Type(), null); case 'F': case 'U': case 'W': case 'V': case 'R': AbstractType ret; List<DAttribute> attrs; Dictionary<INode,AbstractType> pars; Function(out ret, out attrs, out pars, type); var dm = new DMethod(){ Parameters = pars.Keys.ToList(), Attributes = attrs }; return new MemberSymbol(dm, ret, null); case 'I': return new MemberSymbol(null,null, QualifiedName()); case 'C': return new ClassType(new DClassLike(DTokens.Class), QualifiedName(), null); case 'S': return new StructType(new DClassLike(DTokens.Struct), QualifiedName()); case 'E': return new EnumType(new DEnum(), null, QualifiedName()); case 'T': return new AliasedType(null, null, QualifiedName()); case 'D': Function(out ret, out attrs, out pars, type); var dgArgs = new List<AbstractType>(); foreach(var kv in pars) dgArgs.Add(new MemberSymbol(kv.Key as DNode, kv.Value, null)); return new DelegateType(ret,new DelegateDeclaration{ Parameters = pars.Keys.ToList() }, dgArgs); case 'v': return new PrimitiveType(DTokens.Void); case 'g': return new PrimitiveType(DTokens.Byte); case 'h': return new PrimitiveType(DTokens.Ubyte); case 's': return new PrimitiveType(DTokens.Short); case 't': return new PrimitiveType(DTokens.Ushort); case 'i': return new PrimitiveType(DTokens.Int); case 'k': return new PrimitiveType(DTokens.Uint); case 'l': return new PrimitiveType(DTokens.Long); case 'm': return new PrimitiveType(DTokens.Ulong); case 'f': return new PrimitiveType(DTokens.Float); case 'd': return new PrimitiveType(DTokens.Double); case 'e': return new PrimitiveType(DTokens.Real); case 'o': return new PrimitiveType(DTokens.Ifloat); case 'p': return new PrimitiveType(DTokens.Idouble); case 'j': return new PrimitiveType(DTokens.Ireal); case 'q': return new PrimitiveType(DTokens.Cfloat); case 'r': return new PrimitiveType(DTokens.Cdouble); case 'c': return new PrimitiveType(DTokens.Creal); case 'b': return new PrimitiveType(DTokens.Bool); case 'a': return new PrimitiveType(DTokens.Char); case 'u': return new PrimitiveType(DTokens.Wchar); case 'w': return new PrimitiveType(DTokens.Dchar); case 'n': return null; case 'B': len = (int)Number(); var items = new AbstractType[len]; var c = (char)r.Read(); for (int i = 0; i < len; i++) { Argument(ref c, out items[i]); } return new DTuple(null, items); } return null; }
public static AbstractType GetMethodReturnType(DMethod method, ResolutionContext ctxt) { if ((ctxt.Options & ResolutionOptions.DontResolveBaseTypes) == ResolutionOptions.DontResolveBaseTypes) { return(null); } /* * If a method's type equals null, assume that it's an 'auto' function.. * 1) Search for a return statement * 2) Resolve the returned expression * 3) Use that one as the method's type */ bool pushMethodScope = ctxt.ScopedBlock != method; if (method.Type != null) { if (pushMethodScope) { ctxt.PushNewScope(method); } //FIXME: Is it legal to explicitly return a nested type? var returnType = TypeDeclarationResolver.Resolve(method.Type, ctxt); if (pushMethodScope) { ctxt.Pop(); } ctxt.CheckForSingleResult(returnType, method.Type); if (returnType != null && returnType.Length > 0) { return(returnType[0]); } } else if (method.Body != null) { ReturnStatement returnStmt = null; var list = new List <IStatement> { method.Body }; var list2 = new List <IStatement>(); bool foundMatch = false; while (!foundMatch && list.Count > 0) { foreach (var stmt in list) { if (stmt is ReturnStatement) { returnStmt = stmt as ReturnStatement; var te = returnStmt.ReturnExpression as TokenExpression; if (te == null || te.Token != DTokens.Null) { foundMatch = true; break; } } var statementContainingStatement = stmt as StatementContainingStatement; if (statementContainingStatement != null) { list2.AddRange(statementContainingStatement.SubStatements); } } list = list2; list2 = new List <IStatement>(); } if (returnStmt != null && returnStmt.ReturnExpression != null) { if (pushMethodScope) { var dedTypes = ctxt.CurrentContext.DeducedTemplateParameters; ctxt.PushNewScope(method, returnStmt); if (dedTypes.Count != 0) { foreach (var kv in dedTypes) { ctxt.CurrentContext.DeducedTemplateParameters[kv.Key] = kv.Value; } } } var t = DResolver.StripMemberSymbols(ExpressionTypeEvaluation.EvaluateType(returnStmt.ReturnExpression, ctxt)); if (pushMethodScope) { ctxt.Pop(); } return(t); } return(new PrimitiveType(DTokens.Void)); } return(null); }
AbstractType Type(char type = '\0') { if (type == '\0') { type = (char)r.Read(); } switch (type) { case 'O': var t = Type(); t.Modifier = DTokens.Shared; return(t); case 'x': t = Type(); t.Modifier = DTokens.Const; return(t); case 'y': t = Type(); t.Modifier = DTokens.Immutable; return(t); case 'N': switch (r.Read()) { case 'g': t = Type(); t.Modifier = DTokens.InOut; return(t); case 'e': // TypeNewArray ? Type(); return(null); } break; case 'A': return(new ArrayType(Type(), null)); case 'G': var len = (int)Number(); return(new ArrayType(Type(), len, null)); case 'H': var keyType = Type(); t = Type(); return(new AssocArrayType(t, keyType, null)); case 'P': return(new PointerType(Type(), null)); case 'F': case 'U': case 'W': case 'V': case 'R': AbstractType ret; List <DAttribute> attrs; Dictionary <INode, AbstractType> pars; Function(out ret, out attrs, out pars, type); var dm = new DMethod() { Parameters = pars.Keys.ToList(), Attributes = attrs }; return(new MemberSymbol(dm, ret, null)); case 'I': return(new MemberSymbol(null, null, QualifiedName())); case 'C': return(new ClassType(new DClassLike(DTokens.Class), QualifiedName(), null)); case 'S': return(new StructType(new DClassLike(DTokens.Struct), QualifiedName())); case 'E': return(new EnumType(new DEnum(), null, QualifiedName())); case 'T': return(new AliasedType(null, null, QualifiedName())); case 'D': Function(out ret, out attrs, out pars, type); var dgArgs = new List <AbstractType>(); foreach (var kv in pars) { dgArgs.Add(new MemberSymbol(kv.Key as DNode, kv.Value, null)); } return(new DelegateType(ret, new DelegateDeclaration { Parameters = pars.Keys.ToList() }, dgArgs)); case 'v': return(new PrimitiveType(DTokens.Void)); case 'g': return(new PrimitiveType(DTokens.Byte)); case 'h': return(new PrimitiveType(DTokens.Ubyte)); case 's': return(new PrimitiveType(DTokens.Short)); case 't': return(new PrimitiveType(DTokens.Ushort)); case 'i': return(new PrimitiveType(DTokens.Int)); case 'k': return(new PrimitiveType(DTokens.Uint)); case 'l': return(new PrimitiveType(DTokens.Long)); case 'm': return(new PrimitiveType(DTokens.Ulong)); case 'f': return(new PrimitiveType(DTokens.Float)); case 'd': return(new PrimitiveType(DTokens.Double)); case 'e': return(new PrimitiveType(DTokens.Real)); case 'o': return(new PrimitiveType(DTokens.Ifloat)); case 'p': return(new PrimitiveType(DTokens.Idouble)); case 'j': return(new PrimitiveType(DTokens.Ireal)); case 'q': return(new PrimitiveType(DTokens.Cfloat)); case 'r': return(new PrimitiveType(DTokens.Cdouble)); case 'c': return(new PrimitiveType(DTokens.Creal)); case 'b': return(new PrimitiveType(DTokens.Bool)); case 'a': return(new PrimitiveType(DTokens.Char)); case 'u': return(new PrimitiveType(DTokens.Wchar)); case 'w': return(new PrimitiveType(DTokens.Dchar)); case 'n': return(null); case 'B': len = (int)Number(); var items = new AbstractType[len]; var c = (char)r.Read(); for (int i = 0; i < len; i++) { Argument(ref c, out items[i]); } return(new DTuple(null, items)); } return(null); }
public static ISymbolValue Execute(DMethod method, ISymbolValue[] arguments, AbstractSymbolValueProvider vp) { throw new NotImplementedException("CTFE is not implemented yet."); }
internal static bool TryHandleMethodArgumentTuple(ResolutionContext ctxt, ref bool add, List <ISemantic> callArguments, DMethod dm, DeducedTypeDictionary deducedTypeDict, int currentParameter, ref int currentArg) { // .. so only check if it's an identifer & if the id represents a tuple parameter var id = dm.Parameters[currentParameter].Type as IdentifierDeclaration; var curNode = dm as DNode; TemplateParameter tpar = null; while (curNode != null && !curNode.TryGetTemplateParameter(id.IdHash, out tpar)) { curNode = curNode.Parent as DNode; } if (!(tpar is TemplateTupleParameter)) { return(false); } int lastArgumentToTake = -1; /* * Note: an expression tuple parameter can occur also somewhere in between the parameter list! * void write(A...)(bool b, A a, double d) {} * * can be matched by * write(true, 1.2) as well as * write(true, "asdf", 1.2) as well as * write(true, 123, true, 'c', [3,4,5], 3.4) ! */ TemplateParameterSymbol tps; DTuple tuple = null; if (deducedTypeDict.TryGetValue(tpar, out tps) && tps != null) { if (tps.Base is DTuple) { tuple = tps.Base as DTuple; lastArgumentToTake = currentParameter + (tuple.Items == null ? 0 : (tuple.Items.Length - 1)); } else { // Error: Type param must be tuple! } } // - Get the (amount of) arguments that shall be put into the tuple else if (currentParameter == dm.Parameters.Count - 1) { // The usual case: A tuple of a variable length is put at the end of a parameter list.. // take all arguments from i until the end of the argument list.. // ; Also accept empty tuples lastArgumentToTake = callArguments.Count - 1; } else { // Get the type of the next expected parameter var nextExpectedParameter = DResolver.StripMemberSymbols(TypeDeclarationResolver.ResolveSingle(dm.Parameters[currentParameter + 1].Type, ctxt)); // Look for the first argument whose type is equal to the next parameter's type.. for (int k = currentArg; k < callArguments.Count; k++) { if (ResultComparer.IsEqual(AbstractType.Get(callArguments[k]), nextExpectedParameter)) { // .. and assume the tuple to go from i to the previous argument.. lastArgumentToTake = k - 1; break; } } } int argCountToHandle = lastArgumentToTake - currentArg + 1; if (tuple != null) { // - If there's been set an explicit type tuple, compare all arguments' types with those in the tuple if (tuple.Items != null) { foreach (ISemantic item in tuple.Items) { if (currentArg >= callArguments.Count || !ResultComparer.IsImplicitlyConvertible(callArguments[currentArg++], AbstractType.Get(item), ctxt)) { add = false; return(true); } } } } else { // - If there was no explicit initialization, put all arguments' types into a type tuple var argsToTake = new ISemantic[argCountToHandle]; callArguments.CopyTo(currentArg, argsToTake, 0, argsToTake.Length); currentArg += argsToTake.Length; var tt = new DTuple(null, argsToTake); tps = new TemplateParameterSymbol(tpar, tt); // and set the actual template tuple parameter deduction deducedTypeDict[tpar] = tps; } add = true; return(true); }
public override void Visit(DMethod n) { // Format header FormatAttributedNode(n, !n.IsAnonymous && n.Type != null); VisitDNode(n); // Stick name to type if (n.Type != null) { ForceSpacesBeforeRemoveNewLines(n.NameLocation, true); } // Put parenthesis '(' token directly after the name var nameLength = 0; switch (n.SpecialType) { case DMethod.MethodType.Destructor: case DMethod.MethodType.Constructor: nameLength = 4; // this break; case DMethod.MethodType.Normal: nameLength = n.Name.Length; break; } if (nameLength > 0) { ForceSpacesAfterRemoveLines(new CodeLocation(n.NameLocation.Column + nameLength, n.NameLocation.Line), false); } // Format parameters // Find in, out(...) and body tokens if (!n.InToken.IsEmpty) { FixIndentationForceNewLine(n.InToken); } if (!n.OutToken.IsEmpty) { FixIndentationForceNewLine(n.OutToken); } if (!n.BodyToken.IsEmpty) { FixIndentationForceNewLine(n.BodyToken); } // Visit body parts if (n.In != null) { n.In.Accept(this); } if (n.Body != null) { n.Body.Accept(this); } if (n.Out != null) { n.Out.Accept(this); } if (!n.IsAnonymous) { EnsureBlankLinesAfter(n.EndLocation, policy.LinesAfterNode); } }
public ulong Visit(DMethod dMethod) { return(1000037); }
public override void Visit(DMethod n) { base.Visit(n); VisitChildren(n); }
public static AbstractType GetMethodReturnType(DMethod method, ResolutionContext ctxt) { if ((ctxt.Options & ResolutionOptions.DontResolveBaseTypes) == ResolutionOptions.DontResolveBaseTypes) return null; /* * If a method's type equals null, assume that it's an 'auto' function.. * 1) Search for a return statement * 2) Resolve the returned expression * 3) Use that one as the method's type */ bool pushMethodScope = ctxt.ScopedBlock != method; if (method.Type != null) { if (pushMethodScope) ctxt.PushNewScope(method); //FIXME: Is it legal to explicitly return a nested type? var returnType = TypeDeclarationResolver.Resolve(method.Type, ctxt); if (pushMethodScope) ctxt.Pop(); ctxt.CheckForSingleResult(returnType, method.Type); if(returnType != null && returnType.Length > 0) return returnType[0]; } else if (method.Body != null) { ReturnStatement returnStmt = null; var list = new List<IStatement> { method.Body }; var list2 = new List<IStatement>(); bool foundMatch = false; while (!foundMatch && list.Count > 0) { foreach (var stmt in list) { if (stmt is ReturnStatement) { returnStmt = stmt as ReturnStatement; var te = returnStmt.ReturnExpression as TokenExpression; if (te == null || te.Token != DTokens.Null) { foundMatch = true; break; } } var statementContainingStatement = stmt as StatementContainingStatement; if (statementContainingStatement != null) list2.AddRange(statementContainingStatement.SubStatements); } list = list2; list2 = new List<IStatement>(); } if (returnStmt != null && returnStmt.ReturnExpression != null) { if (pushMethodScope) { var dedTypes = ctxt.CurrentContext.DeducedTemplateParameters; ctxt.PushNewScope(method,returnStmt); if (dedTypes.Count != 0) foreach (var kv in dedTypes) ctxt.CurrentContext.DeducedTemplateParameters[kv.Key] = kv.Value; } var t =DResolver.StripMemberSymbols(Evaluation.EvaluateType(returnStmt.ReturnExpression, ctxt)); if (pushMethodScope) ctxt.Pop(); return t; } return new PrimitiveType (DTokens.Void); } return null; }
public static void UpdateBlockPartly(this BlockStatement bs, string code, int caretOffset, CodeLocation caretLocation, out bool isInsideNonCodeSegment) { isInsideNonCodeSegment = false; var finalParentMethod = bs.ParentNode as DMethod; var finalStmtsList = bs._Statements; var startLoc = bs.Location; int startStmtIndex; for (startStmtIndex = finalStmtsList.Count - 1; startStmtIndex >= 0; startStmtIndex--) { var n = finalStmtsList [startStmtIndex]; if (n.EndLocation.Line > 0 && n.EndLocation.Line < caretLocation.Line) { startLoc = --startStmtIndex == -1 ? bs.Location : finalStmtsList [startStmtIndex].EndLocation; break; } } var startOff = startLoc.Line > 1 ? DocumentHelper.GetOffsetByRelativeLocation(code, caretLocation, caretOffset, startLoc) : 0; if (startOff >= caretOffset) { return; } var tempParentBlock = new DMethod(); var tempBlockStmt = new BlockStatement { ParentNode = tempParentBlock }; try{ using (var sv = new StringView(code, startOff, caretOffset - startOff)) using (var p = DParser.Create(sv)) { p.Lexer.SetInitialLocation(startLoc); p.Step(); if (p.laKind == DTokens.OpenCurlyBrace) { p.Step(); } while (!p.IsEOF) { if (p.laKind == DTokens.CloseCurlyBrace) { p.Step(); /*if (metaDecls.Count > 0) * metaDecls.RemoveAt (metaDecls.Count - 1);*/ continue; } var stmt = p.Statement(true, true, tempParentBlock, tempBlockStmt); if (stmt != null) { tempBlockStmt.Add(stmt); } } tempBlockStmt.EndLocation = new CodeLocation(p.la.Column + 1, p.la.Line); if (isInsideNonCodeSegment = p.Lexer.endedWhileBeingInNonCodeSequence) { return; } } }catch (Exception ex) { Console.WriteLine(ex.Message); } // Remove old statements from startLoc until caretLocation int i = startStmtIndex + 1; while (i < finalStmtsList.Count && finalStmtsList [i].Location < caretLocation) { finalStmtsList.RemoveAt(i); } // Insert new statements if (tempBlockStmt.EndLocation > bs.EndLocation) { bs.EndLocation = tempBlockStmt.EndLocation; } foreach (var stmt in tempBlockStmt._Statements) { stmt.ParentNode = finalParentMethod; stmt.Parent = bs; } AssignInStatementDeclarationsToNewParentNode(tempBlockStmt, finalParentMethod); finalStmtsList.InsertRange(startStmtIndex + 1, tempBlockStmt._Statements); if (finalParentMethod != null) { var finalParentChildren = finalParentMethod.AdditionalChildren; // Remove old parent block children int startDeclIndex; for (startDeclIndex = finalParentChildren.Count - 1; startDeclIndex >= 0; startDeclIndex--) { var n = finalParentChildren [startDeclIndex]; if (n == null) { finalParentChildren.RemoveAt(startDeclIndex); continue; } if (n.Location < startLoc) { break; } if (n.Location < caretLocation) { finalParentChildren.RemoveAt(startDeclIndex); } } // Insert new special declarations foreach (var decl in tempParentBlock) { decl.Parent = finalParentMethod; } finalParentChildren.InsertRange(startDeclIndex + 1, tempParentBlock); finalParentMethod.UpdateChildrenArray(); if (bs.EndLocation > finalParentMethod.EndLocation) { finalParentMethod.EndLocation = bs.EndLocation; } } //TODO: Handle DBlockNode parents? }
static string GenerateOverridingMethodStub(DMethod dm, DNode begunNode, bool generateExecuteSuperFunctionStmt = true) { var sb = new StringBuilder(); // Append missing attributes var remainingAttributes = new List <DAttribute>(dm.Attributes); if (begunNode != null && begunNode.Attributes != null) { foreach (var attr in begunNode.Attributes) { var mod = attr as Modifier; if (mod == null) { continue; } foreach (var remAttr in remainingAttributes) { var remMod = remAttr as Modifier; if (remMod == null) { continue; } if (mod.Token == remMod.Token) { remainingAttributes.Remove(remAttr); break; } } } } foreach (var attr in remainingAttributes) { if (attr.Location < dm.NameLocation) { sb.Append(attr.ToString()).Append(' '); } } // Type if (dm.Type != null) { sb.Append(dm.Type.ToString()).Append(' '); } // Name sb.Append(dm.Name); // Template Parameters if (dm.TemplateParameters != null && dm.TemplateParameters.Length != 0) { sb.Append('('); foreach (var tp in dm.TemplateParameters) { sb.Append(tp.ToString()).Append(','); } if (sb[sb.Length - 1] == ',') { sb.Length--; } sb.Append(')'); } // Parameters sb.Append('('); foreach (var p in dm.Parameters) { sb.Append((p is AbstractNode ? (p as AbstractNode).ToString(false) : p.ToString())).Append(','); } if (sb[sb.Length - 1] == ',') { sb.Length--; } sb.Append(") "); // Post-param attributes foreach (var attr in remainingAttributes) { if (attr.Location > dm.NameLocation) { sb.Append(attr.ToString()).Append(' '); } } // Return stub sb.AppendLine("{"); if (generateExecuteSuperFunctionStmt) { if (dm.Type == null || !(dm.Type is DTokenDeclaration && (dm.Type as DTokenDeclaration).Token == DTokens.Void)) { sb.Append("return "); } sb.Append("super.").Append(dm.Name); if (dm.TemplateParameters != null && dm.TemplateParameters.Length != 0) { sb.Append("!("); foreach (var tp in dm.TemplateParameters) { sb.Append(tp.Name).Append(','); } if (sb[sb.Length - 1] == ',') { sb.Length--; } sb.Append(')'); } if (dm.Parameters.Count != 0) // super.foo will also call the base overload; { sb.Append('('); foreach (var p in dm.Parameters) { sb.Append(p.Name).Append(','); } if (sb[sb.Length - 1] == ',') { sb.Length--; } sb.Append(')'); } sb.AppendLine(";"); } else { sb.AppendLine(); } sb.AppendLine("}"); return(sb.ToString()); }
/// <summary> /// Parse parameters /// </summary> List<INode> Parameters(DMethod Parent) { var ret = new List<INode>(); Expect(OpenParenthesis); // Empty parameter list if (laKind == (CloseParenthesis)) { Step(); return ret; } var stk_backup = BlockAttributes; BlockAttributes = new Stack<DAttribute>(); DNode p; if (laKind != TripleDot && (p = Parameter(Parent)) != null) { p.Parent = Parent; ret.Add(p); } while (laKind == (Comma)) { Step(); if (laKind == TripleDot || laKind==CloseParenthesis || (p = Parameter(Parent)) == null) break; p.Parent = Parent; ret.Add(p); } // It's not specified in the official D syntax spec, but we treat id-only typed anonymous parameters as non-typed id-full parameters if(Parent != null && Parent.SpecialType == DMethod.MethodType.AnonymousDelegate) { foreach(var r in ret) if (r.NameHash == 0 && r.Type is IdentifierDeclaration && r.Type.InnerDeclaration == null) { r.NameHash = (r.Type as IdentifierDeclaration).IdHash; r.Type = null; } } /* * There can be only one '...' in every parameter list */ if (laKind == TripleDot) { // If it doesn't have a comma, add a VarArgDecl to the last parameter bool HadComma = t.Kind == (Comma); Step(); if (!HadComma && ret.Count > 0) { // Put a VarArgDecl around the type of the last parameter ret[ret.Count - 1].Type = new VarArgDecl(ret[ret.Count - 1].Type); } else { var dv = new DVariable(); LastParsedObject = dv; dv.Type = new VarArgDecl(); dv.Parent = Parent; ret.Add(dv); } } Expect(CloseParenthesis); BlockAttributes = stk_backup; return ret; }
private bool TryHandleMethodArgumentTuple(ref bool add, List<ISemantic> callArguments, DMethod dm, DeducedTypeDictionary deducedTypeDict, int currentParameter,ref int currentArg) { // .. so only check if it's an identifer & if the id represents a tuple parameter var id = dm.Parameters[currentParameter].Type as IdentifierDeclaration; var curNode = dm as DNode; TemplateParameter tpar = null; while (curNode != null && !curNode.TryGetTemplateParameter(id.IdHash, out tpar)) curNode = curNode.Parent as DNode; if (tpar is TemplateTupleParameter) { int lastArgumentToTake = -1; /* * Note: an expression tuple parameter can occur also somewhere in between the parameter list! * void write(A...)(bool b, A a, double d) {} * * can be matched by * write(true, 1.2) as well as * write(true, "asdf", 1.2) as well as * write(true, 123, true, 'c', [3,4,5], 3.4) ! */ TemplateParameterSymbol tps; DTuple tuple = null; if (deducedTypeDict.TryGetValue(tpar.NameHash, out tps) && tps != null) { if (tps.Parameter == tpar) { if (tps.Base is DTuple) { tuple = tps.Base as DTuple; lastArgumentToTake = currentParameter + (tuple.Items == null ? 0 : (tuple.Items.Length-1)); } else { // Error: Type param must be tuple! } } else { // Error: Wrong parameter } } // - Get the (amount of) arguments that shall be put into the tuple else if (currentParameter == dm.Parameters.Count - 1) { // The usual case: A tuple of a variable length is put at the end of a parameter list.. // take all arguments from i until the end of the argument list.. lastArgumentToTake = callArguments.Count - 1; // Also accept empty tuples.. if (callArguments.Count == 0) lastArgumentToTake = 0; } else { // Get the type of the next expected parameter var nextExpectedParameter = DResolver.StripMemberSymbols(TypeDeclarationResolver.ResolveSingle(dm.Parameters[currentParameter + 1].Type, ctxt)); // Look for the first argument whose type is equal to the next parameter's type.. for (int k = currentArg; k < callArguments.Count; k++) { if (ResultComparer.IsEqual(AbstractType.Get(callArguments[k]), nextExpectedParameter)) { // .. and assume the tuple to go from i to the previous argument.. lastArgumentToTake = k - 1; break; } } } if (lastArgumentToTake < 0) { // An error occurred somewhere.. add = false; return true; } int argCountToHandle = lastArgumentToTake - currentArg; if (argCountToHandle > 0) argCountToHandle++; if (tuple != null) { // - If there's been set an explicit type tuple, compare all arguments' types with those in the tuple if(tuple.Items != null) foreach (ISemantic item in tuple.Items) { if (currentArg >= callArguments.Count || !ResultComparer.IsImplicitlyConvertible(callArguments[currentArg++], AbstractType.Get(item), ctxt)) { add = false; return true; } } } else { // - If there was no explicit initialization, put all arguments' types into a type tuple var argsToTake = new ISemantic[argCountToHandle]; callArguments.CopyTo(currentArg, argsToTake, 0, argsToTake.Length); currentArg += argsToTake.Length; var tt = new DTuple(null, argsToTake); tps = new TemplateParameterSymbol(tpar, tt); // and set the actual template tuple parameter deduction deducedTypeDict[tpar.NameHash] = tps; } add = true; return true; } return false; }
DMethod _Invariant() { var inv = new DMethod { SpecialType= DMethod.MethodType.ClassInvariant }; LastParsedObject = inv; Expect(Invariant); inv.Location = t.Location; if (laKind == OpenParenthesis) { Step(); Expect(CloseParenthesis); } if(!IsEOF) inv.Body=BlockStatement(); inv.EndLocation = t.EndLocation; return inv; }
public AbstractType Visit(DMethod m) { return(new MemberSymbol(m, CanResolveBase(m) ? GetMethodReturnType(m, ctxt) : null, typeBase)); }
internal void LambdaSingleStatementBody(DMethod lambdaFunction) { lambdaFunction.Body = new BlockStatement { Location= la.Location, ParentNode = lambdaFunction }; var ae = AssignExpression(lambdaFunction); lambdaFunction.Body.Add(new ReturnStatement { Location = ae.Location, EndLocation = ae.EndLocation, ReturnExpression=ae }); lambdaFunction.Body.EndLocation = t.EndLocation; }
INode Constructor(DBlockNode scope,bool IsStruct) { Expect(This); var dm = new DMethod(){ Parent = scope, SpecialType = DMethod.MethodType.Constructor, Location = t.Location, Name = DMethod.ConstructorIdentifier, NameLocation = t.Location }; dm.Description = GetComments(); LastParsedObject = dm; if (IsTemplateParameterList()) TemplateParameterList(dm); // http://dlang.org/struct.html#StructPostblit if (IsStruct && laKind == (OpenParenthesis) && Peek(1).Kind == (This)) { var dv = new DVariable(); LastParsedObject = dv; dv.Parent = dm; dv.Name = "this"; dm.Parameters.Add(dv); Step(); Step(); Expect(CloseParenthesis); } else { dm.Parameters = Parameters(dm); } // handle post argument attributes FunctionAttributes(dm); if (!IsEOF) LastParsedObject = dm; if (laKind == If) Constraint(dm); // handle post argument attributes FunctionAttributes(dm); if(IsFunctionBody) FunctionBody(dm); return dm; }
public static string GeneratePrototype(DMethod dm, bool isTemplateParamInsight = false, int currentParam = -1) { var sb = new StringBuilder(""); string name; switch (dm.SpecialType) { case DMethod.MethodType.Constructor: sb.Append("Constructor"); name = dm.Parent.Name; break; case DMethod.MethodType.Destructor: sb.Append("Destructor"); name = dm.Parent.Name; break; case DMethod.MethodType.Allocator: sb.Append("Allocator"); name = dm.Parent.Name; break; default: sb.Append("Method"); name = dm.Name; break; } sb.Append(" in "); sb.Append(AbstractNode.GetNodePath(dm, false)); sb.Append(": "); if (dm.Attributes != null && dm.Attributes.Count > 0) { sb.Append(dm.AttributeString + ' '); } if (dm.Type != null) { sb.Append(dm.Type.ToString(true)); sb.Append(" "); } else if (dm.Attributes != null && dm.Attributes.Count != 0) { foreach (var attr in dm.Attributes) { var m = attr as Modifier; if (m != null && DTokens.StorageClass[m.Token]) { sb.Append(DTokens.GetTokenString(m.Token)); sb.Append(" "); break; } } } sb.Append(name); // Template parameters if (dm.TemplateParameters != null && dm.TemplateParameters.Length > 0) { sb.Append("("); for (int i = 0; i < dm.TemplateParameters.Length; i++) { var p = dm.TemplateParameters[i]; if (isTemplateParamInsight && i == currentParam) { sb.Append(p.ToString()); } else { sb.Append(p.ToString()); } if (i < dm.TemplateParameters.Length - 1) { sb.Append(","); } } sb.Append(")"); } // Parameters sb.Append("("); for (int i = 0; i < dm.Parameters.Count; i++) { var p = dm.Parameters[i] as DNode; if (!isTemplateParamInsight && i == currentParam) { sb.Append(p.ToString(true, false)); } else { sb.Append(p.ToString(true, false)); } if (i < dm.Parameters.Count - 1) { sb.Append(","); } } sb.Append(")"); return(sb.ToString()); }
protected void SerializeDNode(DNode node, StringBuilder sb, int level) { StringBuilder indent = new StringBuilder(); for (int i = 0; i < level; i++) { indent.Append('\t'); } SerializeCodeLocation(node.StartLocation, sb); sb.Append("-"); SerializeCodeLocation(node.EndLocation, sb); sb.Append(" "); if (node is DModule) { DModule module = node as DModule; sb.Append(indent).Append("ML:").Append(module.ModuleName); foreach (ITypeDeclaration td in module.Imports.Keys) { sb.Append(indent).Append("~IM:").Append(td.ToString()); } sb.AppendLine(); } else if (node is DMethod) { DMethod method = node as DMethod; sb.Append(indent).Append("MD:").Append(method.Type != null ? method.Type.ToString() : "<NULL>").Append("~").AppendLine(method.Name); foreach (DNode paramNode in method.Parameters) { SerializeDNode(paramNode, sb, level + 1); } } else if (node is DClassLike) { DClassLike clss = node as DClassLike; sb.Append(indent).Append("CLS:").Append(clss.ClassType).Append("~").AppendLine(clss.Name); } else if (node is DVariable) { DVariable variable = node as DVariable; sb.Append(indent).Append("VAR:").Append((variable.Type == null) ? "<NULL>" : variable.Type.ToString()).Append("~").Append(variable.Name); if (variable.Initializer != null) { sb.Append(indent).Append("~INIT:").Append(variable.Initializer.ToString()); } sb.AppendLine(); } else { object o = node; } if (node is DStatementBlock) { DStatementBlock block = node as DStatementBlock; //if (block.Expression != null) // sb.Append(indent).Append("EXP:").Append(block.Expression.ToString()); foreach (DNode childNode in block) { SerializeDNode(childNode, sb, level + 1); } } else if (node is DBlockStatement) { DBlockStatement block = node as DBlockStatement; foreach (DNode childNode in block.Children) { SerializeDNode(childNode, sb, level + 1); } } }
public override void Visit(DMethod n) { // Format header FormatAttributedNode(n, !n.IsAnonymous && n.Type != null); VisitDNode(n); // Stick name to type if(n.Type != null) ForceSpacesBeforeRemoveNewLines(n.NameLocation, true); // Put parenthesis '(' token directly after the name var nameLength = 0; switch(n.SpecialType) { case DMethod.MethodType.Destructor: case DMethod.MethodType.Constructor: nameLength = 4; // this break; case DMethod.MethodType.Normal: nameLength = n.Name.Length; break; } if(nameLength > 0) ForceSpacesAfterRemoveLines(new CodeLocation(n.NameLocation.Column + nameLength, n.NameLocation.Line),false); // Format parameters // Find in, out(...) and body tokens if(!n.InToken.IsEmpty){ FixIndentationForceNewLine(n.InToken); } if(!n.OutToken.IsEmpty){ FixIndentationForceNewLine(n.OutToken); } if(!n.BodyToken.IsEmpty){ FixIndentationForceNewLine(n.BodyToken); } // Visit body parts if (n.In != null) n.In.Accept (this); if (n.Body != null) n.Body.Accept (this); if (n.Out != null) n.Out.Accept (this); if (!n.IsAnonymous) EnsureBlankLinesAfter (n.EndLocation, policy.LinesAfterNode); }
void HandleIndexSliceExpression(PostfixExpression x) { res.IsMethodArguments = true; res.ParsedExpression = x; var overloads = new List <AbstractType>(); if (x.PostfixForeExpression == null) { return; } var b = ExpressionTypeEvaluation.EvaluateType(x.PostfixForeExpression, ctxt); var bases = AmbiguousType.TryDissolve(b); var ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpSliceIdHash, bases, ctxt, x, false); if (ov != null) { overloads.AddRange(ov); } ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpIndexIdHash, bases, ctxt, x, false); if (ov != null) { overloads.AddRange(ov); } if (overloads.Count == 0) { b = DResolver.StripMemberSymbols(b); var toTypeDecl = new DTypeToTypeDeclVisitor(); var aa = b as AssocArrayType; if (aa != null) { var retType = aa.ValueType != null?aa.ValueType.Accept(toTypeDecl) : null; var dm = new DMethod { Name = "opIndex", Type = retType }; dm.Parameters.Add(new DVariable { Name = "index", Type = aa.KeyType != null ? aa.KeyType.Accept(toTypeDecl) : null }); overloads.Add(new MemberSymbol(dm, aa.ValueType, x)); if ((aa is ArrayType) && !(aa as ArrayType).IsStaticArray) { dm = new DMethod { Name = "opSlice", Type = retType }; overloads.Add(new MemberSymbol(dm, aa.ValueType, x)); } } else if (b is PointerType) { b = (b as PointerType).Base; var dm = new DMethod { Name = "opIndex", Type = b != null?b.Accept(toTypeDecl) : null }; dm.Parameters.Add(new DVariable { Name = "index", Type = new IdentifierDeclaration("size_t") }); overloads.Add(new MemberSymbol(dm, b, x)); } } res.ResolvedTypesOrMethods = overloads.ToArray(); }
/// <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, INode parent) { DNode ret = new DVariable() { Type=basicType, Location = la.Location, Parent = parent }; ApplyAttributes (ret); LastParsedObject = ret; while (IsBasicType2()) { if (ret.Type == null) ret.Type = BasicType2(); else { var ttd = BasicType2(); if(ttd!=null) ttd.InnerDeclaration = ret.Type; ret.Type = ttd; } } // Only return no variable if the BasicType2 wasn't parsed properly to ensure good code completion if (IsEOF && ret != LastParsedObject) return null; if (laKind != (OpenParenthesis)) { // On external function declarations, no parameter names are required. // extern void Cfoo(HANDLE,char**); if (IsParam && laKind != (Identifier)) { if(ret.Type!=null && IsEOF) ExpectingNodeName = true; return ret; } if (Expect(Identifier)) { ret.Name = t.Value; ret.NameLocation = t.Location; if (laKind == OpenParenthesis && ret.Type == null) { OverPeekBrackets (DTokens.OpenParenthesis, true); var k = Lexer.LastToken.Kind; if (k == DTokens.Alias || k == DTokens.Enum) { if (ret.Attributes == null) ret.Attributes = new List<DAttribute> (); ret.Attributes.Add (new Modifier (k)); } // enum asdf(...) = ...; if (Lexer.CurrentPeekToken.Kind == Assign) { var eponymousTemplateDecl = new EponymousTemplate (); eponymousTemplateDecl.AssignFrom (ret); ret = eponymousTemplateDecl; TemplateParameterList (eponymousTemplateDecl); return ret; } } } else { if (IsEOF || IsParam) { ExpectingNodeName = true; return ret; } return null; // Code error! - to prevent infinite declaration loops, step one token forward anyway! if(laKind != CloseCurlyBrace && laKind != CloseParenthesis) Step(); return null; } } else OldCStyleFunctionPointer(ret, IsParam); if (IsDeclaratorSuffix || IsFunctionAttribute) { var dm = new DMethod { Parent = parent, Parameters = null }; dm.AssignFrom(ret); LastParsedObject = dm; DeclaratorSuffixes(dm); if (dm.Parameters != null) ret = dm; else LastParsedObject = ret; } return ret; }
public static TooltipInformation Generate(DMethod dm, bool isTemplateParamInsight = false, int currentParam = -1) { var tti = new TooltipInformation(); var sb = new StringBuilder("<i>("); string name; switch (dm.SpecialType) { case DMethod.MethodType.Constructor: sb.Append("Constructor"); name = dm.Parent.Name; break; case DMethod.MethodType.Destructor: sb.Append("Destructor"); name = dm.Parent.Name; break; case DMethod.MethodType.Allocator: sb.Append("Allocator"); name = dm.Parent.Name; break; default: sb.Append("Method"); name = dm.Name; break; } sb.Append(")</i> "); if (dm.Type != null) { sb.Append(dm.Type.ToString(true)); sb.Append(" "); } else if (dm.Attributes != null && dm.Attributes.Count != 0) { foreach (var attr in dm.Attributes) { var m = attr as Modifier; if (m != null && DTokens.StorageClass[m.Token]) { sb.Append(DTokens.GetTokenString(m.Token)); sb.Append(" "); break; } } } sb.Append(name); /*TODO: Show attributes? * if (dm.Attributes != null && dm.Attributes.Count > 0) * s = dm.AttributeString + ' '; */ // Template parameters if (dm.TemplateParameters != null && dm.TemplateParameters.Length > 0) { sb.Append("("); for (int i = 0; i < dm.TemplateParameters.Length; i++) { var p = dm.TemplateParameters[i]; if (isTemplateParamInsight && i == currentParam) { sb.Append("<u>"); tti.AddCategory(p.Name, p.ToString()); sb.Append(p.ToString()); sb.Append("</u>"); } else { sb.Append(p.ToString()); } if (i < dm.TemplateParameters.Length - 1) { sb.Append(","); } } sb.Append(")"); } // Parameters sb.Append("("); for (int i = 0; i < dm.Parameters.Count; i++) { var p = dm.Parameters[i] as DNode; if (!isTemplateParamInsight && i == currentParam) { sb.Append("<u>"); if (!string.IsNullOrEmpty(p.Description)) { tti.AddCategory(p.Name, p.Description); } sb.Append(p.ToString(true, false)); sb.Append("</u>"); } else { sb.Append(p.ToString(true, false)); } if (i < dm.Parameters.Count - 1) { sb.Append(","); } } sb.Append(")"); tti.SignatureMarkup = sb.ToString(); tti.SummaryMarkup = dm.Description; tti.FooterMarkup = dm.ToString(); return(tti); }
void DeclDef(DBlockNode module) { //AttributeSpecifier while (IsAttributeSpecifier()) { AttributeSpecifier(module); if (t.Kind == Colon || laKind == CloseCurlyBrace || IsEOF) return; } if (laKind == Semicolon) { LastParsedObject = null; Step(); return; } //ImportDeclaration if (laKind == Import) module.Add(ImportDeclaration(module)); //Constructor else if (laKind == (This)) module.Add(Constructor(module, 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); ApplyAttributes(dbs); 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) { DebugSpecification ds = null; VersionSpecification vs = null; if (laKind == Version) LastParsedObject = vs = new VersionSpecification { Location = la.Location, Attributes = GetCurrentAttributeSet_Array() }; else LastParsedObject = ds = new DebugSpecification { Location = la.Location, Attributes = GetCurrentAttributeSet_Array() }; Step(); Step(); if (laKind == Literal) { Step(); if (t.LiteralFormat != LiteralFormat.Scalar) SynErr(t.Kind, "Integer literal expected!"); try { if (vs != null) vs.SpecifiedNumber = Convert.ToInt32(t.LiteralValue); else ds.SpecifiedDebugLevel = Convert.ToInt32(t.LiteralValue); } catch { } } else if (laKind == Identifier) { Step(); if (vs != null) vs.SpecifiedId = t.Value; else ds.SpecifiedId = t.Value; } else if (ds == null) Expect(Identifier); Expect(Semicolon); if (vs == null) ds.EndLocation = t.EndLocation; else vs.EndLocation = t.EndLocation; module.Add(vs as StaticStatement ?? ds); } else if (laKind == Version || laKind == Debug || (laKind == Static && Lexer.CurrentPeekToken.Kind == If)) DeclarationCondition(module); //StaticAssert else if (laKind == (Assert)) { Step(); if (!Modifier.ContainsAttribute(DeclarationAttributes, Static)) SynErr(Static, "Static assert statements must be explicitly marked as static"); var ass = new StaticAssertStatement { Attributes = GetCurrentAttributeSet_Array(), Location = t.Location }; if (Expect(OpenParenthesis)) { ass.AssertedExpression = AssignExpression(); if (laKind == (Comma)) { Step(); ass.Message = AssignExpression(); } if(Expect(CloseParenthesis)) Expect(Semicolon); } ass.EndLocation = t.EndLocation; module.Add(ass); } //TemplateMixinDeclaration else if (laKind == Mixin) { if (Peek(1).Kind == Template) module.Add(TemplateDeclaration(module)); //TemplateMixin else if (Lexer.CurrentPeekToken.Kind == Identifier) { var tmx = TemplateMixin(module); if(tmx.MixinId==null) module.Add(tmx); else module.Add(new NamedTemplateMixinNode(tmx)); } //MixinDeclaration else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis) module.Add(MixinDeclaration(module,null)); else { Step(); SynErr(Identifier); } } // { else if (laKind == (OpenCurlyBrace)) AttributeBlock(module); // 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 { var decls = Declaration(module); if(module != null && decls!=null) module.AddRange(decls); } }