private SyntaxToken ParseEndOfDirective(bool ignoreErrors, bool afterPragma = false, bool afterLineNumber = false, bool afterReference = false) { var skippedTokens = new SyntaxListBuilder <SyntaxToken>(); // Consume all extranous tokens as leading SkippedTokens trivia. if (this.CurrentToken.Kind != SyntaxKind.EndOfDirectiveToken && this.CurrentToken.Kind != SyntaxKind.EndOfFileToken) { skippedTokens = new SyntaxListBuilder <SyntaxToken>(10); if (!ignoreErrors) { ErrorCode errorCode = ErrorCode.ERR_EndOfPPLineExpected; if (afterPragma) { errorCode = ErrorCode.WRN_EndOfPPLineExpected; } else if (afterLineNumber) { errorCode = ErrorCode.ERR_MissingPPFile; } else if (afterReference) { errorCode = ErrorCode.ERR_ExpectedPPFile; } 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); }
private SkippedTokensTriviaSyntax FileAsTrivia(SourceText text) { var builder = new SyntaxListBuilder(1); builder.Add(SyntaxFactory.BadToken(null, text.ToString(), null)); var fileAsTrivia = _syntaxFactory.SkippedTokensTrivia(builder.ToList <SyntaxToken>()); ForceEndOfFile(); // force the scanner to report that it is at the end of the input. return(fileAsTrivia); }
private void ParseDeclarationModifiers(SyntaxListBuilder list) { SyntaxKind k; while (IsDeclarationModifier(k = this.CurrentToken.Kind)) { var mod = this.EatToken(); if (k == SyntaxKind.StaticKeyword || k == SyntaxKind.VolatileKeyword || k == SyntaxKind.ConstKeyword) { mod = this.AddError(mod, ErrorCode.ERR_BadMemberFlag, mod.Text); } list.Add(mod); } }
private void ParseAnnotationDeclarations(SyntaxListBuilder list, bool allowAttributes = true) { var saveTerm = this._termState; this._termState |= TerminatorState.IsAttributeDeclarationTerminator; while (this.IsPossibleAnnotationSyntax()) { var section = this.ParseAnnotationDeclaration(); if (!allowAttributes) { section = this.AddError(section, ErrorCode.ERR_AttributesNotAllowed); } list.Add(section); } this._termState = saveTerm; }
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); } }
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); } } }
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; }
/// <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); }
public SyntaxListBuilder <TNode> Add(TNode node) { _builder.Add(node); return(this); }
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; } } } }
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 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 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 SyntaxList <SyntaxToken> decodeXppMemberModifiers(int visibility, bool isStatic, IList <IToken> tokens = null) { SyntaxListBuilder modifiers = _pool.Allocate(); if (isStatic) { modifiers.Add(SyntaxFactory.MakeToken(SyntaxKind.StaticKeyword, "CLASS")); } else { modifiers.Add(DecodeVisibility(visibility)); } if (tokens != null) { foreach (var token in tokens) { SyntaxToken kw = null; switch (token.Type) { // Member Modifiers from XppMemberModifiers rule case XP.CLASS: kw = SyntaxFactory.MakeToken(SyntaxKind.StaticKeyword, token.Text); break; case XP.STATIC: // remove visibility modifiers // STATIC CLASS (Visibility only in the scope of the prg). // class becomes Internal and is added to the static globals class kw = SyntaxFactory.MakeToken(SyntaxKind.InternalKeyword, token.Text); var tmp = modifiers.ToList(); modifiers.Clear(); foreach (SyntaxToken mod in tmp) { // remove all existing visibility keywords switch (mod.Kind) { case SyntaxKind.ProtectedKeyword: case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.InternalKeyword: break; default: modifiers.Add(mod); break; } } break; } if (kw != null) { modifiers.AddCheckUnique(kw); } } } var result = modifiers.ToList <SyntaxToken>(); _pool.Free(modifiers); return(result); }