private Expression ParseNamespaceOrTypeName(bool allowEmptyArguments, TokenSet followers) //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; //^ ensures result is SimpleName || result is AliasQualifiedName || result is QualifiedName || result is GenericTypeInstanceExpression; { SimpleName rootName = this.ParseSimpleName(followers|Token.Dot|Token.DoubleColon|Token.LessThan); Expression expression = rootName; if (rootName.Name.UniqueKey == this.nameTable.global.UniqueKey && this.currentToken == Token.DoubleColon) expression = new RootNamespaceExpression(rootName.SourceLocation); SourceLocationBuilder sctx = new SourceLocationBuilder(expression.SourceLocation); if (this.currentToken == Token.DoubleColon) { this.GetNextToken(); SimpleName simpleName = this.ParseSimpleName(followers|Token.Dot|Token.LessThan); sctx.UpdateToSpan(simpleName.SourceLocation); expression = new AliasQualifiedName(expression, simpleName, sctx.GetSourceLocation()); } //^ assume expression is SimpleName || expression is AliasQualifiedName; //RootNamespace will always disappear into AliasQualifiedName moreDots: while (this.currentToken == Token.Dot) //^ invariant expression is SimpleName || expression is AliasQualifiedName || expression is QualifiedName || expression is GenericTypeInstanceExpression; { this.GetNextToken(); SimpleName simpleName = this.ParseSimpleName(followers|Token.Dot|Token.LessThan); sctx.UpdateToSpan(simpleName.SourceLocation); expression = new QualifiedName(expression, simpleName, sctx.GetSourceLocation()); } if (this.currentToken == Token.LessThan) { //^ assume expression is SimpleName || expression is AliasQualifiedName || expression is QualifiedName; //Can only get back here if generic instance was followed by dot. TypeExpression genericType = new NamedTypeExpression(expression); while (this.currentToken == Token.LessThan) //^ invariant expression is SimpleName || expression is AliasQualifiedName || expression is QualifiedName || expression is GenericTypeInstanceExpression; { List<TypeExpression> arguments = this.ParseTypeArguments(sctx, allowEmptyArguments, followers|Token.Dot); expression = new GenericTypeInstanceExpression(genericType, arguments.AsReadOnly(), sctx.GetSourceLocation()); } if (this.currentToken == Token.Dot) goto moreDots; } if (this.insideType && !this.insideBlock && !followers[this.currentToken]) this.SkipTo(followers, Error.InvalidMemberDecl, this.scanner.GetTokenSource()); else this.SkipTo(followers); return expression; }
private Expression ParseImplementedInterfacePlusName(ref NameDeclaration name, bool allowThis, TokenSet followers) //^ ensures result is SimpleName || result is QualifiedName; //^ ensures result is QualifiedName ==> (((QualifiedName)result).Qualifier is SimpleName || //^ ((QualifiedName)result).Qualifier is QualifiedName || ((QualifiedName)result).Qualifier is GenericTypeInstanceExpression); { Expression implementedInterface = new SimpleName(name, name.SourceLocation, false); while (this.currentToken == Token.Dot || this.currentToken == Token.LessThan) //^ invariant implementedInterface is SimpleName || implementedInterface is QualifiedName; //The following invariant does not hold, it seems. Fix it. //^ invariant implementedInterface is QualifiedName ==> (((QualifiedName)implementedInterface).Qualifier is SimpleName || //^ ((QualifiedName)implementedInterface).Qualifier is QualifiedName || ((QualifiedName)implementedInterface).Qualifier is GenericTypeInstanceExpression); { if (this.currentToken == Token.LessThan) { //^ assume implementedInterface is SimpleName || implementedInterface is QualifiedName; TypeExpression genericType = new NamedTypeExpression(implementedInterface); SourceLocationBuilder ctx = new SourceLocationBuilder(implementedInterface.SourceLocation); List<TypeExpression> typeArguments = this.ParseTypeArguments(ctx, false, followers|Token.Dot|Token.LeftBrace); implementedInterface = new GenericTypeInstanceExpression(genericType, typeArguments, ctx); } this.Skip(Token.Dot); if (this.currentToken == Token.This && allowThis) { name = this.GetNameDeclarationFor("Item", this.scanner.SourceLocationOfLastScannedToken); } else { if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken]) this.SkipTo(followers|Parser.IdentifierOrNonReservedKeyword|Token.LeftBrace, Error.ExpectedIdentifier); name = this.ParseNameDeclaration(); } SourceLocationBuilder ctx1 = new SourceLocationBuilder(implementedInterface.SourceLocation); ctx1.UpdateToSpan(name.SourceLocation); implementedInterface = new QualifiedName(implementedInterface, new SimpleName(name, name.SourceLocation, false), ctx1); } return implementedInterface; }