private static Signature ParseSignature(string input, SignatureFormat signatureFormat, string methodName = null) { Tokenizer tokenizer = new Tokenizer(input); tokenizer.Eat(TokenType.WhiteSpace); if (signatureFormat.Has(SignatureFormat.AtPrefix)) { tokenizer.Expect(TokenType.Identifier); // "at" or "à" or similar, depending on language tokenizer.Expect(TokenType.WhiteSpace); } if (signatureFormat.Has(SignatureFormat.ReturnType)) { ParseType(tokenizer, signatureFormat); // Ignore return type. } if (signatureFormat.Has(SignatureFormat.MethodName)) { if (methodName != null) { throw new ArgumentException("Don't pass method name"); } methodName = ParseQualifiedMethodName(tokenizer, signatureFormat); } tokenizer.Expect(TokenType.LeftParen); var args = ParseArgumentList(tokenizer, TokenType.RightParen, signatureFormat); tokenizer.Expect(TokenType.RightParen); return(new Signature(methodName, args)); }
private static bool NextArgType(Tokenizer tokenizer, SignatureFormat signatureFormat, TokenType endBracket, out string argType) { var next = tokenizer.Peek(); argType = null; if (next.HasValue && next.Value.Kind == endBracket) { return(false); } tokenizer.Eat(TokenType.WhiteSpace); argType = ParseType(tokenizer, signatureFormat); int lastDot = Math.Max(argType.LastIndexOf('.'), argType.LastIndexOf('/')); if (lastDot > 0) { argType = argType.Substring(lastDot + 1); } if (signatureFormat.Has(SignatureFormat.ParameterNames)) { tokenizer.Expect(TokenType.WhiteSpace); tokenizer.Expect(TokenType.Identifier); } return(true); }
private static string ParseType(Tokenizer tokenizer, SignatureFormat signatureFormat, bool allowArray = true) { var t = tokenizer.Expect(TokenType.Identifier); string typeName = t.ToString(tokenizer.Input);//.Replace("/", ".").Replace("+", "."); if (typeName == "native") { throw new NotSupportedException("Native int"); } if (typeName == "unsigned") { tokenizer.Expect(TokenType.WhiteSpace); typeName = tokenizer.Expect(TokenType.Identifier).ToString(tokenizer.Input); typeName = ResolveUnsignedPrimitive(typeName); } else { typeName = ResolvePrimitive(typeName); } var arrayOrGenericInfo = tokenizer.Peek(); if (arrayOrGenericInfo.HasValue && signatureFormat.Has(SignatureFormat.GenericArity) && arrayOrGenericInfo.Value.Kind == TokenType.BackTick) { tokenizer.Next(); string arity = tokenizer.Expect(TokenType.Number).ToString(tokenizer.Input); typeName = string.Format("{0}`{1}", typeName, arity); arrayOrGenericInfo = tokenizer.Peek(); } if (arrayOrGenericInfo.HasValue && signatureFormat.Has(SignatureFormat.GenericTypes) && arrayOrGenericInfo.Value.Kind == TokenType.LeftAngleBracket) { tokenizer.Next(); // Comma separated list of types. var genericArgs = ParseArgumentList(tokenizer, TokenType.RightAngleBracket, signatureFormat); tokenizer.Expect(TokenType.RightAngleBracket); if (!signatureFormat.Has(SignatureFormat.GenericArity)) { typeName = string.Format("{0}`{1}", typeName, genericArgs.Count); } } if (arrayOrGenericInfo.HasValue && arrayOrGenericInfo.Value.Kind == TokenType.Slash) { // Nested type tokenizer.Next(); string nestedType = ParseType(tokenizer, signatureFormat); typeName = string.Format("{0}+{1}", typeName, nestedType); } if (allowArray) { typeName = typeName + ParseArraySuffix(tokenizer); } if (tokenizer.Eat(TokenType.Ampersand)) { typeName += "&"; } return(typeName); }