void TrackCurrentFrameAndExpression (Token token) { while (frame.bracketType == '<' && !Tokens.ValidInsideTypeName[token.Kind]) { frame.type = FrameType.Popped; frame = frame.parent; } switch (token.Kind) { case Tokens.OpenCurlyBrace: frame.lastExpressionStart = Location.Empty; frame = new Frame (frame, '{'); frame.parent.ResetCurlyChildType (); break; case Tokens.CloseCurlyBrace: while (frame.parent != null) { if (frame.bracketType == '{') { frame.type = FrameType.Popped; frame = frame.parent; break; } else { frame.type = FrameType.Popped; frame = frame.parent; } } break; case Tokens.OpenParenthesis: if (frame.lastExpressionStart.IsEmpty) frame.lastExpressionStart = token.Location; frame = new Frame (frame, '('); frame.parent.ResetParenthesisChildType (); break; case Tokens.OpenSquareBracket: frame = new Frame (frame, '['); frame.parent.ResetSquareBracketChildType (); break; case Tokens.CloseParenthesis: case Tokens.CloseSquareBracket: if (frame.parent != null && (frame.bracketType == '(' || frame.bracketType == '[')) { frame.type = FrameType.Popped; frame = frame.parent; } break; case Tokens.From: frame.SetContext (new ExpressionContext.LinqContext (token.Location.Line, token.Location.Column)); break; case Tokens.LessThan: if (Tokens.ValidInsideTypeName[lastToken]) { frame = new Frame (frame, '<'); if (frame.parent.InExpressionMode) { frame.SetContext (ExpressionContext.Default); } else if ((frame.parent.state == FrameState.TypeDecl || frame.parent.state == FrameState.MethodDecl || frame.parent.state == FrameState.FieldDeclAfterIdentifier) && frame.parent.context == ExpressionContext.IdentifierExpected) { frame.type = FrameType.TypeParameterDecl; frame.SetContext (ExpressionContext.TypeName); frame.parent.SetContext (ExpressionContext.ConstraintsStart); } else { frame.SetContext (ExpressionContext.TypeName); } } break; case Tokens.GreaterThan: if (frame.parent != null && frame.bracketType == '<') { frame.type = FrameType.Popped; frame = frame.parent; } else { frame.lastExpressionStart = Location.Empty; frame.SetDefaultContext (); } break; case Tokens.Question: // do not reset context - TrackCurrentContext will take care of this frame.lastExpressionStart = Location.Empty; break; case Tokens.Dot: case Tokens.DoubleColon: // let the current expression continue break; default: if (Tokens.IdentifierTokens[token.Kind]) { if (lastToken != Tokens.Dot && lastToken != Tokens.DoubleColon) { if (Tokens.ValidInsideTypeName[lastToken]) { frame.SetDefaultContext (); } frame.lastExpressionStart = token.Location; } } else if (Tokens.SimpleTypeName[token.Kind] || Tokens.ExpressionStart[token.Kind] || token.Kind == Tokens.Literal) { frame.lastExpressionStart = token.Location; } else { frame.lastExpressionStart = Location.Empty; frame.SetDefaultContext (); } break; } }
void TrackCurrentContext (Token token) { if (frame.state == FrameState.ObjectCreation) { if (token.Kind == Tokens.CloseSquareBracket) { // handle collection initalizers new string[] { "foo" }. lexer.StartPeek (); if (!(lastToken == Tokens.OpenSquareBracket && lexer.Peek ().Kind == Tokens.OpenCurlyBrace) && frame.context.IsObjectCreation) { frame.SetContext (ExpressionContext.Default); frame.lastExpressionStart = frame.lastNewTokenStart; } // keep frame.state } else if (token.Kind == Tokens.CloseParenthesis || token.Kind == Tokens.CloseCurlyBrace) { if (frame.context.IsObjectCreation) { frame.SetContext (ExpressionContext.Default); frame.lastExpressionStart = frame.lastNewTokenStart; } // keep frame.state } else if (token.Kind == Tokens.GreaterThan || token.Kind == Tokens.DoubleColon || token.Kind == Tokens.Dot || Tokens.SimpleTypeName[token.Kind]) { // keep frame.state == FrameState.ObjectCreationInType } else { frame.state = FrameState.Normal; frame.ResetCurlyChildType (); } } switch (token.Kind) { case Tokens.Using: if (frame.type == FrameType.Global) { frame.SetContext (ExpressionContext.NamespaceNameExcepted); break; } else { goto case Tokens.For; } case Tokens.For: case Tokens.Foreach: case Tokens.Fixed: case Tokens.Catch: if (frame.type == FrameType.Statements) { frame.parenthesisChildType = FrameType.Statements; } break; case Tokens.Throw: frame.SetExpectedType (DomReturnType.Exception); break; case Tokens.New: if (frame.InExpressionMode) { frame.SetContext (ExpressionContext.TypeDerivingFrom (frame.expectedType, frame.expectedType, true)); frame.state = FrameState.ObjectCreation; frame.curlyChildType = FrameType.ObjectInitializer; frame.lastNewTokenStart = token.Location; } break; case Tokens.Namespace: frame.SetContext (ExpressionContext.NamespaceNameExcepted); break; case Tokens.Assign: if (frame.type == FrameType.Global) { frame.SetContext (ExpressionContext.FullyQualifiedType); break; } else if (frame.type == FrameType.Enum) { frame.SetContext (ExpressionContext.Default); break; } else if (frame.type == FrameType.TypeDecl) { frame.SetContext (ExpressionContext.Default); frame.state = FrameState.Initializer; frame.ResetParenthesisChildType (); frame.ResetSquareBracketChildType (); frame.ResetCurlyChildType (); break; } else if (frame.type == FrameType.ObjectInitializer) { frame.state = FrameState.ObjectInitializerValue; frame.SetDefaultContext (); break; } else { goto default; } case Tokens.Colon: if (frame.context == ExpressionContext.NamespaceNameExcepted) break; if (frame.state == FrameState.MethodDecl && lastToken == Tokens.CloseParenthesis) { frame.SetContext (ExpressionContext.BaseConstructorCall); frame.parenthesisChildType = FrameType.Expression; } else { if (frame.curlyChildType == FrameType.TypeDecl || frame.curlyChildType == FrameType.Interface || frame.curlyChildType == FrameType.Enum) { if (frame.state != FrameState.Constraints) { frame.state = FrameState.InheritanceList; frame.SetDefaultContext (); } } } break; case Tokens.Class: case Tokens.Struct: if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) { if (frame.state != FrameState.Constraints) { frame.state = FrameState.TypeDecl; frame.curlyChildType = FrameType.TypeDecl; frame.SetContext (ExpressionContext.IdentifierExpected); } } break; case Tokens.Interface: if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) { frame.state = FrameState.TypeDecl; frame.curlyChildType = FrameType.Interface; frame.SetContext (ExpressionContext.IdentifierExpected); } break; case Tokens.Enum: if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) { frame.state = FrameState.TypeDecl; frame.curlyChildType = FrameType.Enum; frame.SetContext (ExpressionContext.IdentifierExpected); } break; case Tokens.Delegate: if (frame.InExpressionMode) { frame.parenthesisChildType = FrameType.ParameterList; frame.curlyChildType = FrameType.Statements; } else if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) { frame.parenthesisChildType = FrameType.ParameterList; frame.state = FrameState.MethodDecl; frame.SetContext (ExpressionContext.TypeName); } break; case Tokens.LambdaArrow: frame.curlyChildType = FrameType.Statements; break; case Tokens.Event: frame.SetContext (ExpressionContext.DelegateType); frame.curlyChildType = FrameType.Event; frame.state = FrameState.EventDecl; break; case Tokens.Comma: if (frame.bracketType == '<') { frame.state = FrameState.Normal; frame.SetDefaultContext (); } else if (frame.state == FrameState.FieldDecl || frame.state == FrameState.FieldDeclAfterIdentifier || frame.state == FrameState.Initializer) { frame.state = FrameState.FieldDecl; frame.SetContext (ExpressionContext.IdentifierExpected); } else if (frame.state == FrameState.ObjectInitializerValue) { frame.state = FrameState.Normal; frame.SetDefaultContext (); } else if (frame.type == FrameType.Statements) { frame.SetContext (ExpressionContext.IdentifierExpected); } break; case Tokens.Where: if (!frame.InExpressionMode && (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl)) { frame.state = FrameState.Constraints; frame.SetDefaultContext (); } break; case Tokens.CloseCurlyBrace: case Tokens.Semicolon: frame.state = FrameState.Normal; frame.SetDefaultContext (); break; case Tokens.OpenParenthesis: if (frame.parent != null && (frame.parent.state == FrameState.FieldDeclAfterIdentifier || frame.parent.state == FrameState.FieldDecl)) { frame.type = FrameType.ParameterList; frame.SetContext (ExpressionContext.FirstParameterType); frame.parent.state = FrameState.MethodDecl; frame.parent.curlyChildType = FrameType.Statements; } break; case Tokens.Question: // IdentifierExpected = this is after a type name = the ? was a nullable marker if (frame.context != ExpressionContext.IdentifierExpected) { frame.SetDefaultContext (); } break; case Tokens.This: if (frame.state == FrameState.FieldDecl) { // this is an indexer declaration frame.squareBracketChildType = FrameType.ParameterList; frame.state = FrameState.FieldDeclAfterIdentifier; } break; case Tokens.Goto: frame.SetContext (ExpressionContext.IdentifierExpected); break; case Tokens.As: case Tokens.Is: frame.SetContext (ExpressionContext.TypeName); break; case Tokens.Typeof: frame.parenthesisChildType = FrameType.TypeReference; break; case Tokens.Default: frame.parenthesisChildType = FrameType.TypeReference; break; default: if (frame.context == ExpressionContext.NamespaceNameExcepted) break; if (Tokens.SimpleTypeName[token.Kind]) { if (frame.type == FrameType.Interface || frame.type == FrameType.TypeDecl) { if (frame.state == FrameState.Normal) { frame.state = FrameState.FieldDecl; frame.curlyChildType = FrameType.Property; } else if (frame.state == FrameState.FieldDecl && Tokens.IdentifierTokens[token.Kind]) { frame.state = FrameState.FieldDeclAfterIdentifier; } if (frame.state != FrameState.ObjectCreation) { frame.SetContext (ExpressionContext.IdentifierExpected); } } else if (frame.type == FrameType.ParameterList || frame.type == FrameType.Statements || frame.type == FrameType.Global) { if (!frame.context.IsObjectCreation) { frame.SetContext (ExpressionContext.IdentifierExpected); } } } break; } }
void ApplyToken (Token token) { TrackCurrentFrameAndExpression (token); TrackCurrentContext (token); }