private SyntaxToken ParseEndOfDirective(bool ignoreErrors, bool afterPragma = false, bool afterLineNumber = false) { var skippedTokens = new SyntaxListBuilder <SyntaxToken>(); // Consume all extraneous tokens as leading SkippedTokens trivia. if (this.CurrentToken.Kind != SyntaxKind.EndOfDirectiveToken && this.CurrentToken.Kind != SyntaxKind.EndOfFileToken) { skippedTokens = new SyntaxListBuilder <SyntaxToken>(10); if (!ignoreErrors) { var errorCode = ErrorCode.ERR_EndOfPPLineExpected; if (afterPragma) { errorCode = ErrorCode.WRN_EndOfPPLineExpected; } else if (afterLineNumber) { errorCode = ErrorCode.ERR_MissingPPFile; } skippedTokens.Add(this.AddError(this.EatToken().WithoutDiagnosticsGreen(), errorCode)); } while (this.CurrentToken.Kind != SyntaxKind.EndOfDirectiveToken && this.CurrentToken.Kind != SyntaxKind.EndOfFileToken) { skippedTokens.Add(this.EatToken().WithoutDiagnosticsGreen()); } } // attach text from extraneous tokens as trivia to EndOfDirective token SyntaxToken endOfDirective = this.CurrentToken.Kind == SyntaxKind.EndOfDirectiveToken ? this.EatToken() : SyntaxFactory.Token(SyntaxKind.EndOfDirectiveToken); if (!skippedTokens.IsNull) { endOfDirective = endOfDirective.WithLeadingTrivia(SyntaxFactory.SkippedTokensTrivia(skippedTokens.ToList())); } return(endOfDirective); }
// Is this statement list non-empty, and large enough to make using weak children beneficial? private static bool IsLargeEnoughNonEmptyStatementList(SyntaxListBuilder <StatementSyntax> statements) { if (statements.Count == 0) { return(false); } else if (statements.Count == 1) { // If we have a single statement, it might be small, like "return null", or large, // like a loop or if or switch with many statements inside. Use the width as a proxy for // how big it is. If it's small, its better to forgoe a many children list anyway, since the // weak reference would consume as much memory as is saved. return(statements[0].Width > 60); } else { // For 2 or more statements, go ahead and create a many-children lists. return(true); } }
private JavaClassBodySyntax ParseJavaClassBody(SyntaxToken name) { // Parse class body bool parseMembers = true; SyntaxListBuilder <MemberDeclarationSyntax> members = default(SyntaxListBuilder <MemberDeclarationSyntax>); try { var openBrace = this.EatToken(SyntaxKind.OpenBraceToken); // ignore members if missing type name or missing open curly if (name.IsMissing || openBrace.IsMissing) { parseMembers = false; } // even if we saw a { or think we should parse members bail out early since // we know namespaces can't be nested inside types if (parseMembers) { members = this._pool.Allocate <MemberDeclarationSyntax>(); this.ParseJavaNormalClassMembers(ref members, ref openBrace, name); } var closeBrace = this.EatToken(SyntaxKind.CloseBraceToken); SyntaxToken semicolon = null; if (this.CurrentToken.Kind == SyntaxKind.SemicolonToken) { semicolon = this.EatToken(); } return(_syntaxFactory.JavaClassBody(openBrace, members.ToList(), closeBrace, semicolon)); } finally { if (!members.IsNull) { this._pool.Free(members); } } }
private void ParseModifiers(SyntaxListBuilder tokens) { SyntaxModifier mods = 0; bool seenNoDuplicates = true; bool seenNoAccessibilityDuplicates = true; while (true) { var newMod = GetModifier(this.CurrentToken); if (newMod == SyntaxModifier.None) { break; } SyntaxToken modTok = this.EatToken(); ReportDuplicateModifiers(ref modTok, newMod, mods, ref seenNoDuplicates, ref seenNoAccessibilityDuplicates); mods |= newMod; tokens.Add(modTok); } }
internal SyntaxListBuilder Allocate() { SyntaxListBuilder item; if (freeIndex > 0) { freeIndex--; item = freeList[freeIndex].Value; freeList[freeIndex].Value = null; } else { item = new SyntaxListBuilder(10); } #if DEBUG Debug.Assert(!allocated.Contains(item)); allocated.Add(item); #endif return(item); }
private MemberDeclarationSyntax ParseTypeDeclaration(SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers) { CancellationToken.ThrowIfCancellationRequested(); switch (this.CurrentToken.Kind) { case SyntaxKind.ClassKeyword: return(this.ParseJavaNormalClassDeclaration(attributes, modifiers)); case SyntaxKind.EnumKeyword: return(this.ParseJavaEnumDeclaration(attributes, modifiers)); case SyntaxKind.InterfaceKeyword: return(this.ParseJavaNormalInterfaceDeclaration(attributes, modifiers)); case SyntaxKind.AtToken: return(this.ParseJavaAnnotationTypeDeclaration(attributes, modifiers)); default: throw ExceptionUtilities.UnexpectedValue(this.CurrentToken.Kind); } }
public void ParseJavaNormalClassMembers(ref SyntaxListBuilder <MemberDeclarationSyntax> members, ref SyntaxToken openBrace, SyntaxToken name) { while (true) { SyntaxKind kind = this.CurrentToken.Kind; if (CanStartMember(kind)) { // This token can start a member -- go parse it var saveTerm2 = this._termState; this._termState |= TerminatorState.IsPossibleMemberStartOrStop; var memberOrStatement = this.ParseMemberDeclaration(kind, name == null ? null : name.ValueText); if (memberOrStatement != null) { // statements are accepted here, a semantic error will be reported later members.Add(memberOrStatement); } else { // we get here if we couldn't parse the lookahead as a statement or a declaration (we haven't consumed any tokens): this.SkipBadMemberListTokens(ref openBrace, members); } this._termState = saveTerm2; } else if (kind == SyntaxKind.CloseBraceToken || kind == SyntaxKind.EndOfFileToken || this.IsTerminator()) { // This marks the end of members of this class break; } else { // Error -- try to sync up with intended reality this.SkipBadMemberListTokens(ref openBrace, members); } } }
private PostSkipAction SkipBadListTokensWithErrorCodeHelper <TNode>( SyntaxListBuilder <TNode> list, Func <LanguageParser, bool> isNotExpectedFunction, Func <LanguageParser, bool> abortFunction, ErrorCode error, out CSharpSyntaxNode trailingTrivia) where TNode : CSharpSyntaxNode { if (list.Count == 0) { return(SkipBadTokensWithErrorCode(isNotExpectedFunction, abortFunction, error, out trailingTrivia)); } else { CSharpSyntaxNode lastItemTrailingTrivia; var action = SkipBadTokensWithErrorCode(isNotExpectedFunction, abortFunction, error, out lastItemTrailingTrivia); if (lastItemTrailingTrivia != null) { list[list.Count - 1] = AddTrailingSkippedSyntax(list[list.Count - 1], lastItemTrailingTrivia); } trailingTrivia = null; return(action); } }
/// <remarks> /// WARNING: it is possible that "list" is really the underlying builder of a SeparateSyntaxListBuilder, /// so it is important that we not add anything to the list. /// </remarks> private PostSkipAction SkipBadListTokensWithExpectedKindHelper( SyntaxListBuilder list, Func <LanguageParser, bool> isNotExpectedFunction, Func <LanguageParser, bool> abortFunction, SyntaxKind expected, out CSharpSyntaxNode trailingTrivia) { if (list.Count == 0) { return(SkipBadTokensWithExpectedKind(isNotExpectedFunction, abortFunction, expected, out trailingTrivia)); } else { CSharpSyntaxNode lastItemTrailingTrivia; var action = SkipBadTokensWithExpectedKind(isNotExpectedFunction, abortFunction, expected, out lastItemTrailingTrivia); if (lastItemTrailingTrivia != null) { list[list.Count - 1] = AddTrailingSkippedSyntax(list[list.Count - 1], lastItemTrailingTrivia); } trailingTrivia = null; return(action); } }
internal CompilationUnitSyntax ParseCompilationUnit() { SyntaxListBuilder initialBadNodes = null; var body = new CompilationUnitBodyBuilder(this._pool); try { this.ParseCompilationUnitBody(ref body, ref initialBadNodes, SyntaxKind.CompilationUnit); var eof = this.EatToken(SyntaxKind.EndOfFileToken); var result = _syntaxFactory.CompilationUnit(body.Package, body.Imports, body.Members, eof); if (initialBadNodes != null) { // attach initial bad nodes as leading trivia on first token result = AddLeadingSkippedSyntax(result, initialBadNodes.ToListNode()); this._pool.Free(initialBadNodes); } return(result); } finally { body.Free(this._pool); } }
internal TNode ConsumeUnexpectedTokens <TNode>(TNode node) where TNode : CSharpSyntaxNode { if (this.CurrentToken.Kind == SyntaxKind.EndOfFileToken) { return(node); } SyntaxListBuilder <SyntaxToken> b = this._pool.Allocate <SyntaxToken>(); while (this.CurrentToken.Kind != SyntaxKind.EndOfFileToken) { b.Add(this.EatToken()); } var trailingTrash = b.ToList(); this._pool.Free(b); node = this.AddError(node, ErrorCode.ERR_UnexpectedCharacter, trailingTrash[0].ToString()); // TODO: better diagnostic? node = this.AddTrailingSkippedSyntax(node, trailingTrash.Node); return(node); }
private void ParseStatements(ref CSharpSyntaxNode previousNode, SyntaxListBuilder <StatementSyntax> statements, bool stopOnSwitchSections) { var saveTerm = this._termState; this._termState |= TerminatorState.IsPossibleStatementStartOrStop; // partial statements can abort if a new statement starts if (stopOnSwitchSections) { this._termState |= TerminatorState.IsSwitchSectionStart; } while (this.CurrentToken.Kind != SyntaxKind.CloseBraceToken && this.CurrentToken.Kind != SyntaxKind.EndOfFileToken && !(stopOnSwitchSections && this.IsPossibleSwitchSection())) { if (this.IsPossibleStatement()) { var statement = this.ParseStatement(); statements.Add(statement); } else { CSharpSyntaxNode trailingTrivia; var action = this.SkipBadStatementListTokens(statements, SyntaxKind.CloseBraceToken, out trailingTrivia); if (trailingTrivia != null) { previousNode = AddTrailingSkippedSyntax(previousNode, trailingTrivia); } if (action == PostSkipAction.Abort) { break; } } } this._termState = saveTerm; }
private ParameterSyntax ParseParameter( SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers, bool allowThisKeyword, bool allowDefaults, bool allowAttributes, bool allowFieldModifiers) { if (this.IsIncrementalAndFactoryContextMatches && CanReuseParameter(this.CurrentNode as CSharp.Syntax.ParameterSyntax, attributes, modifiers)) { return((ParameterSyntax)this.EatNode()); } this.ParseAnnotationDeclarations(attributes, allowAttributes); this.ParseParameterModifiers(modifiers, allowThisKeyword, allowFieldModifiers); TypeSyntax type = null; type = this.ParseType(true); var hasArgList = this.CurrentToken.Kind == SyntaxKind.DotDotDotToken; SyntaxToken dotdotdotTk = default(SyntaxToken); if (hasArgList) { dotdotdotTk = this.EatToken(SyntaxKind.DotDotDotToken); } SyntaxToken name = null; //if (!hasArgList) { name = this.ParseIdentifierToken(); // When the user type "int foo[]", give them a useful error if (this.CurrentToken.Kind == SyntaxKind.OpenBracketToken && this.PeekToken(1).Kind == SyntaxKind.CloseBracketToken) { var open = this.EatToken(); var close = this.EatToken(); open = this.AddError(open, ErrorCode.ERR_BadArraySyntax); name = AddTrailingSkippedSyntax(name, SyntaxList.List(open, close)); } } //else if (this.IsPossibleName()) //{ // // Current token is an identifier token, we expected a CloseParenToken. // // Get the expected token error for the missing token with correct diagnostic // // span and then parse the identifier token. // SyntaxDiagnosticInfo diag = this.GetExpectedTokenError(SyntaxKind.CloseParenToken, SyntaxKind.IdentifierToken); // name = this.ParseIdentifierToken(); // name = WithAdditionalDiagnostics(name, diag); //} //else //{ // // name is not optional on ParameterSyntax // name = this.EatToken(SyntaxKind.ArgListKeyword); //} EqualsValueClauseSyntax def = null; if (this.CurrentToken.Kind == SyntaxKind.EqualsToken) { var equals = this.EatToken(SyntaxKind.EqualsToken); var expr = this.ParseExpression(); def = _syntaxFactory.EqualsValueClause(equals, expr); if (!allowDefaults) { def = this.AddError(def, equals, ErrorCode.ERR_DefaultValueNotAllowed); } else { def = CheckFeatureAvailability(def, MessageID.IDS_FeatureOptionalParameter); } } return(_syntaxFactory.Parameter(attributes, modifiers.ToTokenList(), type, dotdotdotTk, name, def)); }
internal SeparatedSyntaxListBuilder(SyntaxListBuilder builder) { _builder = builder; }
private List <MemberDeclarationSyntax> GeneratePartialProperties(List <PartialPropertyElement> classes, SyntaxListBuilder <UsingDirectiveSyntax> usingslist, XSharpTreeTransformationCore trans) { // Create a list of member declarations for all partial types // that do not have a constructor (when /vo16 is selected) // or where access and assign were not found in the same source file // the usingList will contain an unique list of using statements combined from the various // source files where the types were found. var dict = new Dictionary <string, List <XP.IMethodContext> >(XSharpString.Comparer); var tmpUsings = new List <Syntax.UsingDirectiveSyntax>(); foreach (var clsctx in classes) { if (clsctx.Type.PartialProperties != null) { foreach (var m in clsctx.Type.PartialProperties) { var idName = m.Id.Get <SyntaxToken>(); var name = idName.Text; if (dict.ContainsKey(name)) { dict[name].Add(m); } else { var list = new List <XP.IMethodContext>() { m }; dict.Add(name, list); } } // Collect quickly now. Deduplicate later. tmpUsings.AddRange(clsctx.Usings); } } // now we have a list of PropertyNames and methods var result = new List <MemberDeclarationSyntax>(); // add the usings when they are not in the list yet foreach (var u in tmpUsings) { var green = u.Green as UsingDirectiveSyntax; trans.AddUsingWhenMissing(usingslist, green.Name, green.StaticKeyword != null, green.Alias); } // For each unique name add a property foreach (var element in dict) { var prop = new XSharpTreeTransformationCore.SyntaxClassEntities.VoPropertyInfo(); prop.idName = SyntaxFactory.Identifier(element.Key); foreach (var m in element.Value) { if (m.RealType == XSharpLexer.ACCESS) { if (prop.AccessMethodCtx == null) { prop.AccessMethodCtx = m; } else { prop.DupAccess = m; } } else { if (prop.AssignMethodCtx == null) { prop.AssignMethodCtx = m; } else { prop.DupAssign = m; } } } var propdecl = trans.GenerateVoProperty(prop, null); result.Add(propdecl); } return(result); }
private SyntaxTree processTrees(SyntaxTree[] trees, CSharpParseOptions parseoptions) { // this method gives us the ability to check all the generated syntax trees, // add generated constructors to partial classes when none of the parts has a constructor // merge accesses and assigns from different source files into one property etc. // we pass the usings from the compilation units along because the new compilation unit will // have to the same (combined) list of usings // When compiling in VO/Vulcan dialect we also collect the literal symbols from the compilation unit. // When we have one or more of these then we create a symbol table in the class "Xs$SymbolTable" var partialClasses = new Dictionary <string, List <PartialPropertyElement> >(XSharpString.Comparer); var symbolTable = new Dictionary <string, FieldDeclarationSyntax>(); var pszTable = new Dictionary <string, Tuple <string, FieldDeclarationSyntax> >(); foreach (var tree in trees) { var compilationunit = tree.GetRoot() as Syntax.CompilationUnitSyntax; if (compilationunit.NeedsProcessing) { foreach (var member in compilationunit.Members) { if (member is Syntax.NamespaceDeclarationSyntax) { processNameSpace(member as Syntax.NamespaceDeclarationSyntax, partialClasses, compilationunit.Usings); } else { var node = member.Green as CSharpSyntaxNode; if (node.XNode is XP.EntityContext) { processType(node.XNode as XP.EntityContext, partialClasses, compilationunit.Usings); } } } } if (_options.HasRuntime) { if (compilationunit.LiteralSymbols.Count > 0) { foreach (var pair in compilationunit.LiteralSymbols) { if (!symbolTable.ContainsKey(pair.Key)) { symbolTable.Add(pair.Key, pair.Value); } } compilationunit.LiteralSymbols.Clear(); } if (compilationunit.LiteralPSZs.Count > 0) { foreach (var pair in compilationunit.LiteralPSZs) { if (!pszTable.ContainsKey(pair.Key)) { pszTable.Add(pair.Key, pair.Value); } } compilationunit.LiteralSymbols.Clear(); } } } if (partialClasses.Count > 0 || symbolTable.Count > 0 || pszTable.Count > 0) { // Create a new tree which shall have the generated constructors and properties // and return this tree to the caller. // we copy the attributes, modifiers etc from one of the class instances to make sure that // do not specify a conflicting modifier. var trans = CreateTransform(null, _options, _pool, _syntaxFactory, _fileName); SyntaxListBuilder <UsingDirectiveSyntax> usingslist = _pool.Allocate <UsingDirectiveSyntax>(); var members = _pool.Allocate <MemberDeclarationSyntax>(); var clsmembers = _pool.Allocate <MemberDeclarationSyntax>(); foreach (var element in partialClasses) { var name = element.Key; bool hasctor = false; bool haspartialprop = false; XP.IPartialPropertyContext ctxt = null; XP.Namespace_Context xns; foreach (var val in element.Value) { var xnode = val.Type; ctxt = xnode; if (xnode.Data.HasInstanceCtor) { hasctor = true; } if (xnode.Data.PartialProps) { haspartialprop = true; } } if (ctxt.CsNode is InterfaceDeclarationSyntax) { var ifdecl = ctxt.Get <InterfaceDeclarationSyntax>(); // ctxt.Parent is XP.EntityContext // ctxt.Parent.Parent may be XP.Namespace_Context xns = ctxt.Parent.Parent as XP.Namespace_Context; if (haspartialprop) { clsmembers.Clear(); var props = GeneratePartialProperties(element.Value, usingslist, trans); if (props != null) { foreach (var prop in props) { clsmembers.Add(prop); } } if (clsmembers.Count > 0) { var decl = _syntaxFactory.InterfaceDeclaration( default(SyntaxList <AttributeListSyntax>), ifdecl.Modifiers, ifdecl.Keyword, ifdecl.Identifier, ifdecl.TypeParameterList, ifdecl.BaseList, ifdecl.ConstraintClauses, ifdecl.OpenBraceToken, clsmembers, ifdecl.CloseBraceToken, null); ifdecl.XGenerated = true; members.Add(WrapInNamespace(trans, decl, xns, _options.DefaultNamespace)); } } } else if (ctxt.CsNode is StructDeclarationSyntax) { var strucdecl = ctxt.Get <StructDeclarationSyntax>(); // ctxt.Parent is XP.EntityContext // ctxt.Parent.Parent may be XP.Namespace_Context xns = ctxt.Parent.Parent as XP.Namespace_Context; if (haspartialprop) { clsmembers.Clear(); var props = GeneratePartialProperties(element.Value, usingslist, trans); if (props != null) { foreach (var prop in props) { clsmembers.Add(prop); } } if (clsmembers.Count > 0) { var decl = _syntaxFactory.StructDeclaration( default(SyntaxList <AttributeListSyntax>), strucdecl.Modifiers, strucdecl.Keyword, strucdecl.Identifier, strucdecl.TypeParameterList, strucdecl.BaseList, strucdecl.ConstraintClauses, strucdecl.OpenBraceToken, clsmembers, strucdecl.CloseBraceToken, null); strucdecl.XGenerated = true; members.Add(WrapInNamespace(trans, decl, xns, _options.DefaultNamespace)); } } } else if (ctxt.CsNode is ClassDeclarationSyntax) { // ctxt.Parent is XP.EntityContext // ctxt.Parent.Parent may be XP.Namespace_Context xns = ctxt.Parent.Parent as XP.Namespace_Context; if (!hasctor || haspartialprop) { clsmembers.Clear(); var classdecl = ctxt.Get <ClassDeclarationSyntax>(); if (!hasctor && !classdecl.IsStatic() && _options.VOClipperConstructors && trans != null) { var ctor = trans.GenerateDefaultCtor(classdecl.Identifier, ctxt as XP.Class_Context); if (ctor != null) { clsmembers.Add(ctor); } } if (haspartialprop) { var props = GeneratePartialProperties(element.Value, usingslist, trans); if (props != null) { foreach (var prop in props) { clsmembers.Add(prop); } } } if (clsmembers.Count > 0) { var decl = _syntaxFactory.ClassDeclaration( default(SyntaxList <AttributeListSyntax>), classdecl.Modifiers, classdecl.Keyword, classdecl.Identifier, classdecl.TypeParameterList, classdecl.BaseList, classdecl.ConstraintClauses, classdecl.OpenBraceToken, clsmembers, classdecl.CloseBraceToken, null); decl.XGenerated = true; members.Add(WrapInNamespace(trans, decl, xns, _options.DefaultNamespace)); } } } } if (symbolTable.Count > 0) { // build internal static symbol table class members.Add(_generateSymbolsClass(symbolTable, trans)); } if (pszTable.Count > 0) { // build internal static psz table class members.Add(_generatePszClass(pszTable, trans)); } var eof = SyntaxFactory.Token(SyntaxKind.EndOfFileToken); var result = _syntaxFactory.CompilationUnit( default(SyntaxList <ExternAliasDirectiveSyntax>), usingslist, default(SyntaxList <AttributeListSyntax>), members, eof); result.XGenerated = true; var tree = (CSharpSyntaxTree)CSharpSyntaxTree.Create((Syntax.CompilationUnitSyntax)result.CreateRed(), parseoptions); tree.Generated = true; _pool.Free(members); _pool.Free(usingslist); _pool.Free(clsmembers); return(tree); } return(null); }
private SkippedTokensTriviaSyntax ParserErrorsAsTrivia(List <ParseErrorData> parseErrors, IDictionary <string, SourceText> includes) { // create one syntax token per error // and one syntax token for the main file // these tokens will get as many errors as needed. // We are only includin 1 syntax error per file (1003) and one parse error (9002) var textNode = SyntaxFactory.BadToken(null, _text.ToString(), null); var builder = new SyntaxListBuilder(parseErrors.Count + 1); if (!parseErrors.IsEmpty()) { bool hasSyntaxError = false; bool hasParserError = false; foreach (var e in parseErrors) { bool add = true; if (e.Code == ErrorCode.ERR_SyntaxError) { add = !hasSyntaxError; hasSyntaxError = true; } else if (e.Code == ErrorCode.ERR_ParserError) { add = !hasParserError; hasParserError = true; } if (!add) { continue; } if (e.Node != null) { var node = e.Node; var key = node.SourceFileName; int pos = node.Position; int len = node.FullWidth; if (node.SourceSymbol != null) { var sym = node.SourceSymbol as XSharpToken; key = sym.SourceName; pos = sym.Position; len = sym.FullWidth; } if (len <= 0 || pos < 0) { if (e.Node.Parent != null) { var xNode = e.Node as IXParseTree; pos = xNode.Position; len = xNode.FullWidth; } if (pos < 0) { pos = 0; } if (len <= 0) { len = 1; } } SourceText inc = null; if (key != null && includes.ContainsKey(key)) { inc = includes[key]; if (pos - 1 + len > inc.Length) { len = inc.Length - pos + 1; } } var diag = new SyntaxDiagnosticInfo(pos, len, e.Code, e.Args); if (inc != null) { var incNode = SyntaxFactory.BadToken(null, inc.ToString(), null); incNode = incNode.WithAdditionalDiagnostics(diag); incNode.XNode = e.Node; builder.Add(incNode); } else { textNode = textNode.WithAdditionalDiagnostics(diag); } } else { textNode = textNode.WithAdditionalDiagnostics(new SyntaxDiagnosticInfo(e.Code, e.Args)); } } } else { if (_options.ParseLevel == ParseLevel.Complete) { textNode = textNode.WithAdditionalDiagnostics(new SyntaxDiagnosticInfo(ErrorCode.ERR_ParserError, "Unknown error")); } } builder.Add(textNode); return(_syntaxFactory.SkippedTokensTrivia(builder.ToList <SyntaxToken>())); }
private JavaInitializerMethodDeclarationSyntax ParseJavaInitializerMethodDeclaration(SyntaxListBuilder modifiers) { //InstanceInitializer: // Block //StaticInitializer: // static Block SyntaxToken staticKeyword = default(SyntaxToken); var modifiersTokens = modifiers.ToTokenList(); //if (modifiersTokens.Count > 0) //{ // var token = modifiersTokens[0]; // if (token.Kind != SyntaxKind.StaticKeyword) // { // token = this.AddError(token, ErrorCode.ERR_BadModifierLocation); // //token = this.ConvertToMissingWithTrailingTrivia(token, SyntaxKind.StaticKeyword); // } // staticKeyword = token; //} bool haveStatic = modifiersTokens.Any(SyntaxKind.StaticKeyword); //ÓÐstatic ÇÒ ÐÞÊηû¾ÍÒ»¸ö if (haveStatic && modifiersTokens.Count == 1) { staticKeyword = modifiersTokens[0]; } else if (haveStatic && modifiersTokens.Count != 1) { int staticIndex = -1; for (int i = 0; i < modifiersTokens.Count; i++) { if (modifiersTokens[i].Kind == SyntaxKind.StaticKeyword) { staticIndex = i; break; } } staticKeyword = modifiersTokens[staticIndex]; for (int i = 0; i < modifiersTokens.Count; i++) { if (i != staticIndex) { if (i < staticIndex) { staticKeyword = this.AddLeadingSkippedSyntax(staticKeyword, this.AddErrorToFirstToken(modifiersTokens[i], ErrorCode.ERR_BadModifierLocation)); } else if (i > staticIndex) { staticKeyword = this.AddTrailingSkippedSyntax(staticKeyword, this.AddErrorToFirstToken(modifiersTokens[i], ErrorCode.ERR_BadModifierLocation)); } } } } else if (!haveStatic && modifiersTokens.Count != 0) { staticKeyword = Syntax.InternalSyntax.SyntaxFactory.MissingToken(SyntaxKind.StaticKeyword); foreach (SyntaxToken t in modifiersTokens) { staticKeyword = this.AddLeadingSkippedSyntax(staticKeyword, this.AddErrorToFirstToken(t, ErrorCode.ERR_BadModifierLocation)); } } var saveTerm = this._termState; this._termState |= TerminatorState.IsEndOfMethodSignature; try { if (this.CurrentToken.Kind == SyntaxKind.OpenBraceToken) { BlockSyntax body = this.ParseBlock(isMethodBody: true); return(_syntaxFactory.JavaInitializerMethodDeclaration(staticKeyword, body)); } } finally { this._termState = saveTerm; } return(null); }
/// <summary> /// Converts skippedSyntax node into tokens and adds these as trivia on the target token. /// Also adds the first error (in depth-first preorder) found in the skipped syntax tree to the target token. /// </summary> internal SyntaxToken AddSkippedSyntax(SyntaxToken target, CSharpSyntaxNode skippedSyntax, bool trailing) { var builder = new SyntaxListBuilder(4); // the error in we'll attach to the node SyntaxDiagnosticInfo diagnostic = null; // the position of the error within the skipedSyntax node full tree int diagnosticOffset = 0; int currentOffset = 0; foreach (var node in skippedSyntax.EnumerateNodes()) { SyntaxToken token = node as SyntaxToken; if (token != null) { builder.Add(token.GetLeadingTrivia()); if (token.Width > 0) { // separate trivia from the tokens SyntaxToken tk = token.WithLeadingTrivia(null).WithTrailingTrivia(null); // adjust relative offsets of diagnostics attached to the token: int leadingWidth = token.GetLeadingTriviaWidth(); if (leadingWidth > 0) { var tokenDiagnostics = tk.GetDiagnostics(); for (int i = 0; i < tokenDiagnostics.Length; i++) { var d = (SyntaxDiagnosticInfo)tokenDiagnostics[i]; tokenDiagnostics[i] = new SyntaxDiagnosticInfo(d.Offset - leadingWidth, d.Width, (ErrorCode)d.Code, d.Arguments); } } builder.Add(SyntaxFactory.SkippedTokensTrivia(tk)); } else { // do not create zero-width structured trivia, GetStructure doesn't work well for them var existing = (SyntaxDiagnosticInfo)token.GetDiagnostics().FirstOrDefault(); if (existing != null) { diagnostic = existing; diagnosticOffset = currentOffset; } } builder.Add(token.GetTrailingTrivia()); currentOffset += token.FullWidth; } else if (node.ContainsDiagnostics && diagnostic == null) { // only propagate the first error to reduce noise: var existing = (SyntaxDiagnosticInfo)node.GetDiagnostics().FirstOrDefault(); if (existing != null) { diagnostic = existing; diagnosticOffset = currentOffset; } } } int triviaWidth = currentOffset; var trivia = builder.ToListNode(); // total width of everything preceding the added trivia int triviaOffset; if (trailing) { var trailingTrivia = target.GetTrailingTrivia(); triviaOffset = target.FullWidth; //added trivia is full width (before addition) target = target.WithTrailingTrivia(SyntaxList.Concat(trailingTrivia, trivia)); } else { // Since we're adding triviaWidth before the token, we have to add that much to // the offset of each of its diagnostics. if (triviaWidth > 0) { var targetDiagnostics = target.GetDiagnostics(); for (int i = 0; i < targetDiagnostics.Length; i++) { var d = (SyntaxDiagnosticInfo)targetDiagnostics[i]; targetDiagnostics[i] = new SyntaxDiagnosticInfo(d.Offset + triviaWidth, d.Width, (ErrorCode)d.Code, d.Arguments); } } var leadingTrivia = target.GetLeadingTrivia(); target = target.WithLeadingTrivia(SyntaxList.Concat(trivia, leadingTrivia)); triviaOffset = 0; //added trivia is first, so offset is zero } if (diagnostic != null) { int newOffset = triviaOffset + diagnosticOffset + diagnostic.Offset; target = WithAdditionalDiagnostics(target, new SyntaxDiagnosticInfo(newOffset, diagnostic.Width, (ErrorCode)diagnostic.Code, diagnostic.Arguments) ); } return(target); }
private ConstructorDeclarationSyntax createConstructor(XP.FoxclassContext context, SyntaxListBuilder <MemberDeclarationSyntax> members, List <String> fieldNames, ConstructorDeclarationSyntax existingctor) { var stmts = new List <StatementSyntax>(); bool hasinit = false; var attributeLists = _pool.Allocate <AttributeListSyntax>(); ParameterListSyntax initparams = EmptyParameterList(); ConstructorDeclarationSyntax ctor = null; foreach (var member in context._Members) { if (member is XP.FoxclsmethodContext fm) { // fetch parameters from procedure/function init var method = fm.Member as XP.FoxmethodContext; if (method.Id.GetText().ToLower() == "init") { var syntax = method.Get <MethodDeclarationSyntax>(); initparams = syntax.ParameterList; attributeLists.AddRange(syntax.AttributeLists); hasinit = true; } } else if (member is XP.FoxclsvarinitContext cvi) { // Generate code to initialize properties var fldinit = cvi.Member; var assign = fldinit.F.Get <ExpressionSyntax>(); var stmt = GenerateExpressionStatement(assign); stmt.XNode = fldinit.F; stmts.Add(stmt); } else if (member is XP.FoxaddobjectContext fac) { // generate object creation and addobject call // Property:= ClassName{}{.......} var addobject = fac.Member; var create = createAddObject(addobject); var name = addobject.Id.GetText(); var prop = MakeSimpleMemberAccess(GenerateSelf(), GenerateSimpleName(name)); var assign = MakeSimpleAssignment(prop, create); var stmt = GenerateExpressionStatement(assign); stmt.XNode = addobject; stmts.Add(stmt); // AddObject(SELF:Property) var arg1 = MakeArgument(GenerateLiteral(name)); var arg2 = MakeArgument(prop); var mcall = GenerateMethodCall(XSharpSpecialNames.AddObject, MakeArgumentList(arg1, arg2)); stmt = GenerateExpressionStatement(mcall); stmt.XNode = addobject; stmts.Add(stmt); } } if (_options.fox1) { if (stmts.Count > 0) { // Generate Virtual Protected _InitProperties // SUPER:_InitProperties() // All Statements var mac = MakeSimpleMemberAccess(GenerateSuper(), GenerateSimpleName(XSharpSpecialNames.InitProperties)); var superCall = _syntaxFactory.InvocationExpression(mac, EmptyArgumentList()); var stmt = GenerateExpressionStatement(superCall, true); stmts.Insert(0, stmt); var body = MakeBlock(stmts); body.XGenerated = true; var mods = TokenList(SyntaxKind.ProtectedKeyword, SyntaxKind.OverrideKeyword); var id = SyntaxFactory.MakeIdentifier(XSharpSpecialNames.InitProperties); var mem = _syntaxFactory.MethodDeclaration(MakeCompilerGeneratedAttribute(), mods, _voidType, null, id, null, EmptyParameterList(), null, body, null, SyntaxFactory.MakeToken(SyntaxKind.SemicolonToken)); members.Add(mem); stmts.Clear(); } } if (stmts.Count > 0 || hasinit || existingctor != null) { var argList = new List <ArgumentSyntax>(); for (int i = 0; i < initparams.Parameters.Count; i++) { var par = initparams.Parameters[i]; argList.Add(MakeArgument(GenerateSimpleName(par.Identifier.Text))); } ArgumentListSyntax args = MakeArgumentList(argList.ToArray()); if (existingctor != null) { stmts.AddRange(existingctor.Body.Statements.Nodes); var body = MakeBlock(stmts); ctor = existingctor.Update(existingctor.AttributeLists, existingctor.Modifiers, existingctor.Identifier, existingctor.ParameterList, existingctor.Initializer, body, existingctor.ExpressionBody, existingctor.SemicolonToken); } else { var chain = _syntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, SyntaxFactory.MakeToken(SyntaxKind.ColonToken), SyntaxFactory.MakeToken(SyntaxKind.BaseKeyword), args ); var mods = TokenList(SyntaxKind.PublicKeyword); var id = context.Id.Get <SyntaxToken>(); GenerateAttributeList(attributeLists, SystemQualifiedNames.CompilerGenerated); var body = MakeBlock(stmts); ctor = _syntaxFactory.ConstructorDeclaration(attributeLists, mods, id, initparams, chain, body, null, null); } } _pool.Free(attributeLists); return(ctor); }
private static bool CanReuseParameter(CSharp.Syntax.ParameterSyntax parameter, SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers) { if (parameter == null) { return(false); } // cannot reuse parameter if it had attributes. // // TODO(cyrusn): Why? We can reuse other constructs if they have attributes. if (attributes.Count != 0 || parameter.AttributeLists.Count != 0) { return(false); } // cannot reuse parameter if it had modifiers. if ((modifiers != null && modifiers.Count != 0) || parameter.Modifiers.Count != 0) { return(false); } return(CanReuseParameter(parameter)); }
private void ReduceIncompleteMembers(ref SyntaxListBuilder <MemberDeclarationSyntax> incompleteMembers, ref CompilationUnitBodyBuilder body, ref SyntaxListBuilder initialBadNodes) { for (int i = 0; i < incompleteMembers.Count; i++) { this.AddSkippedNamespaceText(ref body, ref initialBadNodes, incompleteMembers[i]); } incompleteMembers.Clear(); }
private JavaNormalClassDeclarationSyntax ParseJavaNormalClassDeclaration(SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers) { Debug.Assert(this.CurrentToken.Kind == SyntaxKind.ClassKeyword); var classKeyword = this.EatToken(SyntaxKind.ClassKeyword); var saveTerm = this._termState; this._termState |= TerminatorState.IsPossibleAggregateClauseStartOrStop; var name = this.ParseIdentifierToken(); var typeParameters = this.ParseTypeParameterList(); this._termState = saveTerm; var extendsClause = this.ParseExtendsClause(); var implementsClauseList = this.ParseImplementsListClause(false); var body = this.ParseJavaClassBody(name); return(_syntaxFactory.JavaNormalClassDeclaration( this.CreateJavaMemberModifierSyntax(attributes, modifiers), classKeyword, name, typeParameters, extendsClause, implementsClauseList, body)); }
private JavaAnnotationTypeDeclarationSyntax ParseJavaAnnotationTypeDeclaration(SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers) { Debug.Assert(this.CurrentToken.Kind == SyntaxKind.AtToken); var atToken = this.EatToken(SyntaxKind.AtToken); var interfaceKeyword = this.EatToken(SyntaxKind.InterfaceKeyword); var saveTerm = this._termState; this._termState |= TerminatorState.IsPossibleAggregateClauseStartOrStop; var name = this.ParseIdentifierToken(); this._termState = saveTerm; // Parse class body bool parseMembers = true; SyntaxListBuilder <MemberDeclarationSyntax> members = default(SyntaxListBuilder <MemberDeclarationSyntax>); try { var openBrace = this.EatToken(SyntaxKind.OpenBraceToken); // ignore members if missing type name or missing open curly if (name.IsMissing || openBrace.IsMissing) { parseMembers = false; } // even if we saw a { or think we should parse members bail out early since // we know namespaces can't be nested inside types if (parseMembers) { members = this._pool.Allocate <MemberDeclarationSyntax>(); while (true) { SyntaxKind kind = this.CurrentToken.Kind; if (CanStartMember(kind)) { // This token can start a member -- go parse it var saveTerm2 = this._termState; this._termState |= TerminatorState.IsPossibleMemberStartOrStop; var memberOrStatement = this.ParseMemberDeclaration(kind, name.ValueText); if (memberOrStatement != null) { if (memberOrStatement is BaseMethodDeclarationSyntax) { var method = memberOrStatement as BaseMethodDeclarationSyntax; } // statements are accepted here, a semantic error will be reported later members.Add(memberOrStatement); } else { // we get here if we couldn't parse the lookahead as a statement or a declaration (we haven't consumed any tokens): this.SkipBadMemberListTokens(ref openBrace, members); } this._termState = saveTerm2; } else if (kind == SyntaxKind.CloseBraceToken || kind == SyntaxKind.EndOfFileToken || this.IsTerminator()) { // This marks the end of members of this class break; } else { // Error -- try to sync up with intended reality this.SkipBadMemberListTokens(ref openBrace, members); } } } var closeBrace = this.EatToken(SyntaxKind.CloseBraceToken); SyntaxToken semicolon = null; if (this.CurrentToken.Kind == SyntaxKind.SemicolonToken) { semicolon = this.EatToken(); } var aaa = _syntaxFactory.JavaAnnotationTypeDeclaration( this.CreateJavaMemberModifierSyntax(attributes, modifiers), atToken, interfaceKeyword, name, openBrace, members, closeBrace, semicolon); return(aaa); } finally { if (!members.IsNull) { this._pool.Free(members); } } }
private ConstructorDeclarationSyntax ParseConstructorDeclaration(string typeName, SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers, TypeParameterListSyntax typeParameterList) { var name = this.ParseIdentifierToken(); Debug.Assert(name.ValueText == typeName); var saveTerm = this._termState; this._termState |= TerminatorState.IsEndOfMethodSignature; try { var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true, allowAttributes: true, allowFieldModifiers: false); JavaThrowsListClauseSyntax throws = this.ParseJavaThrowsListClause(true); ConstructorInitializerSyntax initializer = null; if (this.CurrentToken.Kind == SyntaxKind.ColonToken) { bool isStatic = modifiers != null && modifiers.Any(SyntaxKind.StaticKeyword); initializer = this.ParseConstructorInitializer(name.ValueText, isStatic); } BlockSyntax body; SyntaxToken semicolon; this.ParseBodyOrSemicolon(out body, out semicolon); return(_syntaxFactory.ConstructorDeclaration(attributes, modifiers.ToTokenList(), typeParameterList, name, paramList, throws, initializer, body, semicolon)); } finally { this._termState = saveTerm; } }
private void ParseParameterModifiers(SyntaxListBuilder modifiers, bool allowThisKeyword, bool allowFieldModifiers) { var flags = ParamFlags.None; SyntaxModifier fieldMods = 0; bool seenNoDuplicates = true; bool seenNoAccessibilityDuplicates = true; while (true) { if (IsParameterModifier(this.CurrentToken.Kind, allowThisKeyword)) { var mod = this.EatToken(); if (mod.Kind == SyntaxKind.ThisKeyword) { if (mod.Kind == SyntaxKind.ThisKeyword) { mod = CheckFeatureAvailability(mod, MessageID.IDS_FeatureExtensionMethod); if ((flags & ParamFlags.This) != 0) { mod = this.AddError(mod, ErrorCode.ERR_DupParamMod, SyntaxKindFacts.GetText(SyntaxKind.ThisKeyword)); } else if ((flags & ParamFlags.Params) != 0) { mod = this.AddError(mod, ErrorCode.ERR_BadParamModThis); } else { flags |= ParamFlags.This; } } if (mod.Kind == SyntaxKind.FinalKeyword) { flags |= ParamFlags.Final; } //else if (mod.Kind == SyntaxKind.ParamsKeyword) //{ // if ((flags & ParamFlags.Params) != 0) // { // mod = this.AddError(mod, ErrorCode.ERR_DupParamMod, SyntaxKindFacts.GetText(SyntaxKind.ParamsKeyword)); // } // else if ((flags & ParamFlags.This) != 0) // { // mod = this.AddError(mod, ErrorCode.ERR_BadParamModThis); // } // else if ((flags & (ParamFlags.Ref | ParamFlags.Out | ParamFlags.This)) != 0) // { // mod = this.AddError(mod, ErrorCode.ERR_MultiParamMod); // } // else // { // flags |= ParamFlags.Params; // } //} } modifiers.Add(mod); continue; } if (allowFieldModifiers) { var newFieldMod = GetFieldModifier(this.CurrentToken); if (newFieldMod != SyntaxModifier.None) { var modTok = this.EatToken(); if (newFieldMod == SyntaxModifier.Static) { if ((fieldMods & SyntaxModifier.Static) == 0) { modTok = this.AddError(modTok, ErrorCode.ERR_StaticParamMod); } } else { ReportDuplicateModifiers(ref modTok, newFieldMod, fieldMods, ref seenNoDuplicates, ref seenNoAccessibilityDuplicates); } fieldMods |= newFieldMod; modifiers.Add(modTok); continue; } } break; } if (fieldMods != 0 && fieldMods != SyntaxModifier.Static && ((fieldMods & AccessModifiers) == 0)) { for (int i = 0; i < modifiers.Count; i++) { var mod = GetFieldModifier((SyntaxToken)modifiers[i]); if (mod != SyntaxModifier.None && mod != SyntaxModifier.Static) { Debug.Assert((fieldMods & AccessModifiers) == 0); if ((fieldMods & AccessModifiers) == 0) { modifiers[i] = this.AddError(modifiers[i], ErrorCode.ERR_ParamMissingAccessMod); } break; } } } }
internal SyntaxListBuilder(SyntaxListBuilder builder) { _builder = builder; }
public static SyntaxList <CSharpSyntaxNode> ToList(this SyntaxListBuilder builder) { return(ToList <CSharpSyntaxNode>(builder)); }
private static bool IsSingleSpaceTrivia(SyntaxListBuilder syntax) { return(syntax.Count == 1 && SyntaxFactory.Space.IsEquivalentTo(syntax[0])); }
internal SyntaxListBuilder(SyntaxListBuilder builder) { this.builder = builder; }