mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Adding support in fidelity for parsing union and parenthesized types
This commit is contained in:
@@ -46,6 +46,14 @@ module TypeScript {
|
||||
return this.defaultVisit(node);
|
||||
}
|
||||
|
||||
public visitUnionType(node: UnionTypeSyntax): any {
|
||||
return this.defaultVisit(node);
|
||||
}
|
||||
|
||||
public visitParenthesizedType(node: ParenthesizedTypeSyntax): any {
|
||||
return this.defaultVisit(node);
|
||||
}
|
||||
|
||||
public visitInterfaceDeclaration(node: InterfaceDeclarationSyntax): any {
|
||||
return this.defaultVisit(node);
|
||||
}
|
||||
|
||||
+100
-13
@@ -3532,6 +3532,38 @@ module TypeScript.Parser {
|
||||
}
|
||||
|
||||
function tryParseType(): ITypeSyntax {
|
||||
if (isFunctionType()) {
|
||||
return parseFunctionType();
|
||||
}
|
||||
|
||||
if (currentToken().kind() === SyntaxKind.NewKeyword) {
|
||||
return parseConstructorType();
|
||||
}
|
||||
|
||||
return tryParseUnionTypeOrHigher();
|
||||
}
|
||||
|
||||
function tryParseUnionTypeOrHigher(): ITypeSyntax {
|
||||
var type = tryParsePrimaryType();
|
||||
|
||||
if (type) {
|
||||
var barToken: ISyntaxToken;
|
||||
while ((barToken = currentToken()).kind() === SyntaxKind.BarToken) {
|
||||
consumeToken(barToken);
|
||||
var right = parsePrimaryType();
|
||||
|
||||
type = new syntaxFactory.UnionTypeSyntax(parseNodeData, type, barToken, right);
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
function parsePrimaryType(): ITypeSyntax {
|
||||
return tryParsePrimaryType() || eatIdentifierToken(DiagnosticCode.Type_expected);
|
||||
}
|
||||
|
||||
function tryParsePrimaryType(): ITypeSyntax {
|
||||
// First consume any underlying element type.
|
||||
var type = tryParseNonArrayType();
|
||||
|
||||
@@ -3572,11 +3604,9 @@ module TypeScript.Parser {
|
||||
}
|
||||
|
||||
return consumeToken(_currentToken);
|
||||
case SyntaxKind.OpenParenToken:
|
||||
case SyntaxKind.LessThanToken: return tryParseFunctionType();
|
||||
case SyntaxKind.VoidKeyword: return consumeToken(_currentToken);
|
||||
case SyntaxKind.OpenParenToken: return parseParenthesizedType(_currentToken);
|
||||
case SyntaxKind.OpenBraceToken: return parseObjectType();
|
||||
case SyntaxKind.NewKeyword: return parseConstructorType();
|
||||
case SyntaxKind.TypeOfKeyword: return parseTypeQuery(_currentToken);
|
||||
case SyntaxKind.OpenBracketToken: return parseTupleType(_currentToken);
|
||||
}
|
||||
@@ -3584,6 +3614,10 @@ module TypeScript.Parser {
|
||||
return tryParseNameOrGenericType();
|
||||
}
|
||||
|
||||
function parseParenthesizedType(openParenToken: ISyntaxToken): ParenthesizedTypeSyntax {
|
||||
return new syntaxFactory.ParenthesizedTypeSyntax(parseNodeData, consumeToken(openParenToken), parseType(), eatToken(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
|
||||
function tryParseNameOrGenericType(): ITypeSyntax {
|
||||
var name = tryParseName(/*allowIdentifierNames*/ false);
|
||||
if (name === null) {
|
||||
@@ -3604,18 +3638,71 @@ module TypeScript.Parser {
|
||||
: new syntaxFactory.GenericTypeSyntax(parseNodeData, name, typeArgumentList);
|
||||
}
|
||||
|
||||
function tryParseFunctionType(): FunctionTypeSyntax {
|
||||
var typeParameterList = tryParseTypeParameterList(/*requireCompleteTypeParameterList:*/ false);
|
||||
var parameterList: ParameterListSyntax = null;
|
||||
if (typeParameterList === null) {
|
||||
parameterList = tryParseParameterList();
|
||||
if (parameterList === null) {
|
||||
return null;
|
||||
function isFunctionType(): boolean {
|
||||
var token0 = currentToken();
|
||||
var token0Kind = token0.kind();
|
||||
|
||||
// If we see a < then we consider ourselves to be definitely in a (generic) function type.
|
||||
if (token0Kind === SyntaxKind.LessThanToken) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we don't see a < then we have to see an open paren for this to be a function
|
||||
// type. However, an open paren may also start a parenthesized type. So we need to
|
||||
// do some lookahead to see what we've actually got. If we don't see enough to be
|
||||
// sure that it's a function type, then we go ahead with the assumption that it's a
|
||||
// parenthesized type.
|
||||
if (token0Kind === SyntaxKind.OpenParenToken) {
|
||||
var token1 = peekToken(1);
|
||||
var token1Kind = token1.kind();
|
||||
|
||||
if (token1Kind === SyntaxKind.CloseParenToken || token1Kind === SyntaxKind.DotDotDotToken) {
|
||||
// ()
|
||||
// (...
|
||||
//
|
||||
// Both are definitely function types, and could not be paren types.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isModifierKind(token1Kind) || isIdentifier(token1)) {
|
||||
// (id
|
||||
// could be a function type or a parenthesized type.
|
||||
|
||||
var token2 = peekToken(2);
|
||||
var token2Kind = token2.kind();
|
||||
|
||||
if (token2Kind === SyntaxKind.ColonToken ||
|
||||
token2Kind === SyntaxKind.CommaToken ||
|
||||
token2Kind === SyntaxKind.QuestionToken ||
|
||||
token2Kind === SyntaxKind.EqualsToken ||
|
||||
isIdentifier(token2) ||
|
||||
isModifierKind(token2Kind)) {
|
||||
// ( id :
|
||||
// ( id ,
|
||||
// ( id ?
|
||||
// ( id =
|
||||
// ( modifier id
|
||||
//
|
||||
// All of these are definitely a function type and not a parenthesized type.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (token2Kind === SyntaxKind.CloseParenToken) {
|
||||
// ( id )
|
||||
//
|
||||
// Only a function type if we see an arrow following it.
|
||||
return peekToken(3).kind() === SyntaxKind.EqualsGreaterThanToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
parameterList = parseParameterList();
|
||||
}
|
||||
|
||||
// Anything else is a parenthesized type.
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseFunctionType(): FunctionTypeSyntax {
|
||||
var typeParameterList = tryParseTypeParameterList(/*requireCompleteTypeParameterList:*/ false);
|
||||
var parameterList = parseParameterList();
|
||||
|
||||
return new syntaxFactory.FunctionTypeSyntax(parseNodeData,
|
||||
typeParameterList, parameterList, eatToken(SyntaxKind.EqualsGreaterThanToken), parseType());
|
||||
|
||||
@@ -427,6 +427,20 @@ module TypeScript.PrettyPrinter {
|
||||
this.appendToken(node.closeBracketToken);
|
||||
}
|
||||
|
||||
public visitParenthesizedType(node: ParenthesizedTypeSyntax): void {
|
||||
this.appendToken(node.openParenToken);
|
||||
this.appendElement(node.type);
|
||||
this.appendToken(node.closeParenToken);
|
||||
}
|
||||
|
||||
public visitUnionType(node: UnionTypeSyntax): void {
|
||||
this.appendElement(node.left);
|
||||
this.ensureSpace();
|
||||
this.appendToken(node.barToken);
|
||||
this.ensureSpace();
|
||||
this.appendElement(node.right);
|
||||
}
|
||||
|
||||
public visitConstructorType(node: ConstructorTypeSyntax): void {
|
||||
this.appendToken(node.newKeyword);
|
||||
this.ensureSpace();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
///<reference path='..\core\environment.ts' />
|
||||
///<reference path='syntaxFacts.ts' />
|
||||
///<reference path='syntaxKind.ts' />
|
||||
///<reference path='..\..\..\tests\fidelity\es5compat.ts' />
|
||||
|
||||
// Adds argument checking to the generated nodes. Argument checking appears to slow things down
|
||||
// parsing about 7%. If we want to get that perf back, we can always remove this.
|
||||
@@ -365,6 +366,28 @@ var definitions:ITypeDefinition[] = [
|
||||
],
|
||||
isTypeScriptSpecific: true
|
||||
},
|
||||
<any> {
|
||||
name: 'UnionTypeSyntax',
|
||||
baseType: 'ISyntaxNode',
|
||||
interfaces: ['ITypeSyntax'],
|
||||
children: [
|
||||
<any>{ name: 'left', type: 'ITypeSyntax' },
|
||||
<any>{ name: 'barToken', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'right', type: 'ITypeSyntax' }
|
||||
],
|
||||
isTypeScriptSpecific: true
|
||||
},
|
||||
<any> {
|
||||
name: 'ParenthesizedTypeSyntax',
|
||||
baseType: 'ISyntaxNode',
|
||||
interfaces: ['ITypeSyntax'],
|
||||
children: [
|
||||
<any>{ name: 'openParenToken', isToken: true, excludeFromAST: true },
|
||||
<any>{ name: 'type', type: 'ITypeSyntax' },
|
||||
<any>{ name: 'closeParenToken', isToken: true, excludeFromAST: true }
|
||||
],
|
||||
isTypeScriptSpecific: true
|
||||
},
|
||||
<any>{
|
||||
name: 'TypeAnnotationSyntax',
|
||||
baseType: 'ISyntaxNode',
|
||||
|
||||
@@ -159,6 +159,8 @@ module TypeScript {
|
||||
GenericType,
|
||||
TypeQuery,
|
||||
TupleType,
|
||||
UnionType,
|
||||
ParenthesizedType,
|
||||
|
||||
// Module elements.
|
||||
InterfaceDeclaration,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -14,6 +14,8 @@ module TypeScript {
|
||||
case SyntaxKind.GenericType: return visitor.visitGenericType(<GenericTypeSyntax>element);
|
||||
case SyntaxKind.TypeQuery: return visitor.visitTypeQuery(<TypeQuerySyntax>element);
|
||||
case SyntaxKind.TupleType: return visitor.visitTupleType(<TupleTypeSyntax>element);
|
||||
case SyntaxKind.UnionType: return visitor.visitUnionType(<UnionTypeSyntax>element);
|
||||
case SyntaxKind.ParenthesizedType: return visitor.visitParenthesizedType(<ParenthesizedTypeSyntax>element);
|
||||
case SyntaxKind.InterfaceDeclaration: return visitor.visitInterfaceDeclaration(<InterfaceDeclarationSyntax>element);
|
||||
case SyntaxKind.FunctionDeclaration: return visitor.visitFunctionDeclaration(<FunctionDeclarationSyntax>element);
|
||||
case SyntaxKind.ModuleDeclaration: return visitor.visitModuleDeclaration(<ModuleDeclarationSyntax>element);
|
||||
@@ -111,6 +113,8 @@ module TypeScript {
|
||||
visitGenericType(node: GenericTypeSyntax): any;
|
||||
visitTypeQuery(node: TypeQuerySyntax): any;
|
||||
visitTupleType(node: TupleTypeSyntax): any;
|
||||
visitUnionType(node: UnionTypeSyntax): any;
|
||||
visitParenthesizedType(node: ParenthesizedTypeSyntax): any;
|
||||
visitInterfaceDeclaration(node: InterfaceDeclarationSyntax): any;
|
||||
visitFunctionDeclaration(node: FunctionDeclarationSyntax): any;
|
||||
visitModuleDeclaration(node: ModuleDeclarationSyntax): any;
|
||||
|
||||
@@ -109,6 +109,18 @@ module TypeScript {
|
||||
this.visitToken(node.closeBracketToken);
|
||||
}
|
||||
|
||||
public visitUnionType(node: UnionTypeSyntax): void {
|
||||
this.visitNodeOrToken(node.left);
|
||||
this.visitToken(node.barToken);
|
||||
this.visitNodeOrToken(node.right);
|
||||
}
|
||||
|
||||
public visitParenthesizedType(node: ParenthesizedTypeSyntax): void {
|
||||
this.visitToken(node.openParenToken);
|
||||
this.visitNodeOrToken(node.type);
|
||||
this.visitToken(node.closeParenToken);
|
||||
}
|
||||
|
||||
public visitInterfaceDeclaration(node: InterfaceDeclarationSyntax): void {
|
||||
this.visitList(node.modifiers);
|
||||
this.visitToken(node.interfaceKeyword);
|
||||
|
||||
Reference in New Issue
Block a user