From 556cb70c1d0de4d450baadf48279b7f0ca3d954e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 18 Jun 2015 14:00:36 -0700 Subject: [PATCH] Utilities + types setup for JSX and As --- src/compiler/core.ts | 4 +- src/compiler/types.ts | 91 +++++++++++++++++++++++++++++++++++++++ src/compiler/utilities.ts | 16 ++++--- 3 files changed, 104 insertions(+), 7 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ced477eeeec..7b35c5e0d65 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -702,9 +702,9 @@ namespace ts { /** * List of supported extensions in order of file resolution precedence. */ - export const supportedExtensions = [".ts", ".d.ts"]; + export const supportedExtensions = [".tsx", ".ts", ".d.ts"]; - const extensionsToRemove = [".d.ts", ".ts", ".js"]; + const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"]; export function removeFileExtension(path: string): string { for (let ext of extensionsToRemove) { if (fileExtensionIs(path, ext)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f9a2fa3b7b4..d78d38d5ba7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -48,6 +48,7 @@ namespace ts { SemicolonToken, CommaToken, LessThanToken, + LessThanSlashToken, GreaterThanToken, LessThanEqualsToken, GreaterThanEqualsToken, @@ -217,6 +218,8 @@ namespace ts { ClassExpression, OmittedExpression, ExpressionWithTypeArguments, + AsExpression, + // Misc TemplateSpan, SemicolonClassElement, @@ -265,6 +268,16 @@ namespace ts { // Module references ExternalModuleReference, + //JSX + JsxElement, + JsxSelfClosingElement, + JsxOpeningElement, + JsxText, + JsxClosingElement, + JsxAttribute, + JsxSpreadAttribute, + JsxExpression, + // Clauses CaseClause, DefaultClause, @@ -396,6 +409,17 @@ namespace ts { HasAggregatedChildData = 1 << 8 } + export const enum JsxFlags { + None = 0, + IntrinsicNamedElement = 1 << 0, + IntrinsicIndexedElement = 1 << 1, + ClassElement = 1 << 2, + UnknownElement = 1 << 3, + + IntrinsicElement = IntrinsicNamedElement | IntrinsicIndexedElement + } + + /* @internal */ export const enum RelationComparisonResult { Succeeded = 1, // Should be truthy @@ -799,11 +823,66 @@ namespace ts { export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression; + export interface AsExpression extends Expression { + expression: Expression; + type: TypeNode; + } + export interface TypeAssertion extends UnaryExpression { type: TypeNode; expression: UnaryExpression; } + export type AssertionExpression = TypeAssertion | AsExpression; + + /// A JSX expression of the form ... + export interface JsxElement extends PrimaryExpression { + openingElement: JsxOpeningElement; + children: NodeArray; + closingElement: JsxClosingElement; + } + + /// The opening element of a ... JsxElement + export interface JsxOpeningElement extends Expression { + _openingElementBrand?: any; + tagName: EntityName; + attributes: NodeArray; + } + + /// A JSX expression of the form + export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement { + _selfClosingElementBrand?: any; + } + + /// Either the opening tag in a ... pair, or the lone in a self-closing form + export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; + + export interface JsxAttribute extends Node { + name: Identifier; + /// JSX attribute initializers are optional; is sugar for + initializer?: Expression; + } + + export interface JsxSpreadAttribute extends Node { + expression: Expression; + } + + export interface JsxClosingElement extends Node { + tagName: EntityName; + } + + export interface JsxExpression extends Expression { + expression?: Expression; + } + + export interface JsxText extends Node { + _jsxTextExpressionBrand: any; + /// Used by the emitter to avoid recomputation + formattedReactText?: string; + } + + export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement; + export interface Statement extends Node { _statementBrand: any; } @@ -1144,6 +1223,7 @@ namespace ts { amdDependencies: {path: string; name: string}[]; moduleName: string; referencedFiles: FileReference[]; + isTSXFile: boolean; /** * lib.d.ts should have a reference comment like @@ -1323,6 +1403,9 @@ namespace ts { getAliasedSymbol(symbol: Symbol): Symbol; getExportsOfModule(moduleSymbol: Symbol): Symbol[]; + getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type; + getJsxIntrinsicTagNames(): Symbol[]; + // Should not be called directly. Should only be accessed through the Program instance. /* @internal */ getDiagnostics(sourceFile?: SourceFile): Diagnostic[]; /* @internal */ getGlobalDiagnostics(): Diagnostic[]; @@ -1603,6 +1686,7 @@ namespace ts { assignmentChecks?: Map; // Cache of assignment checks hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context importOnRightSide?: Symbol; // for import declarations - import that appear on the right side + jsxFlags?: JsxFlags; // flags for knowning what kind of element/attributes we're dealing with } export const enum TypeFlags { @@ -1834,6 +1918,7 @@ namespace ts { help?: boolean; inlineSourceMap?: boolean; inlineSources?: boolean; + jsx?: JsxEmit; listFiles?: boolean; locale?: string; mapRoot?: string; @@ -1877,6 +1962,12 @@ namespace ts { System = 4, } + export const enum JsxEmit { + None = 0, + Preserve = 1, + React = 2 + } + export const enum NewLineKind { CarriageReturnLineFeed = 0, LineFeed = 1, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ee75454ad93..7ec599babbc 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -169,13 +169,13 @@ namespace ts { return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end); } - export function getSourceTextOfNodeFromSourceFile(sourceFile: SourceFile, node: Node): string { + export function getSourceTextOfNodeFromSourceFile(sourceFile: SourceFile, node: Node, includeTrivia = false): string { if (nodeIsMissing(node)) { return ""; } let text = sourceFile.text; - return text.substring(skipTrivia(text, node.pos), node.end); + return text.substring(includeTrivia ? node.pos : skipTrivia(text, node.pos), node.end); } export function getTextOfNodeFromSourceText(sourceText: string, node: Node): string { @@ -186,8 +186,8 @@ namespace ts { return sourceText.substring(skipTrivia(sourceText, node.pos), node.end); } - export function getTextOfNode(node: Node): string { - return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node); + export function getTextOfNode(node: Node, includeTrivia = false): string { + return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia); } // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' @@ -850,6 +850,7 @@ namespace ts { case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: case SyntaxKind.TaggedTemplateExpression: + case SyntaxKind.AsExpression: case SyntaxKind.TypeAssertionExpression: case SyntaxKind.ParenthesizedExpression: case SyntaxKind.FunctionExpression: @@ -866,6 +867,8 @@ namespace ts { case SyntaxKind.TemplateExpression: case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.OmittedExpression: + case SyntaxKind.JsxElement: + case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.YieldExpression: return true; case SyntaxKind.QualifiedName: @@ -912,7 +915,8 @@ namespace ts { return (forInStatement.initializer === node && forInStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) || forInStatement.expression === node; case SyntaxKind.TypeAssertionExpression: - return node === (parent).expression; + case SyntaxKind.AsExpression: + return node === (parent).expression; case SyntaxKind.TemplateSpan: return node === (parent).expression; case SyntaxKind.ComputedPropertyName: @@ -1886,6 +1890,8 @@ namespace ts { case SyntaxKind.ElementAccessExpression: case SyntaxKind.NewExpression: case SyntaxKind.CallExpression: + case SyntaxKind.JsxElement: + case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.TaggedTemplateExpression: case SyntaxKind.ArrayLiteralExpression: case SyntaxKind.ParenthesizedExpression: