Merge pull request #3564 from RyanCavanaugh/jsxAndAs

JSX and `as` operator
This commit is contained in:
Ryan Cavanaugh 2015-06-29 10:54:28 -07:00
commit e1c9d28cb0
244 changed files with 9570 additions and 170 deletions

View file

@ -74,6 +74,9 @@ namespace ts {
getAliasedSymbol: resolveAlias,
getEmitResolver,
getExportsOfModule: getExportsOfModuleAsArray,
getJsxElementAttributesType,
getJsxIntrinsicTagNames
};
let unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown");
@ -113,11 +116,18 @@ namespace ts {
let globalRegExpType: ObjectType;
let globalTemplateStringsArrayType: ObjectType;
let globalESSymbolType: ObjectType;
let jsxElementType: ObjectType;
/** Lazily loaded, use getJsxIntrinsicElementType() */
let jsxIntrinsicElementsType: ObjectType;
let globalIterableType: GenericType;
let globalIteratorType: GenericType;
let globalIterableIteratorType: GenericType;
let anyArrayType: Type;
let getGlobalClassDecoratorType: () => ObjectType;
let getGlobalParameterDecoratorType: () => ObjectType;
let getGlobalPropertyDecoratorType: () => ObjectType;
let getGlobalMethodDecoratorType: () => ObjectType;
let getGlobalTypedPropertyDescriptorType: () => ObjectType;
let tupleTypes: Map<TupleType> = {};
@ -156,6 +166,14 @@ namespace ts {
}
};
const JsxNames = {
JSX: "JSX",
IntrinsicElements: "IntrinsicElements",
ElementClass: "ElementClass",
ElementAttributesPropertyNameContainer: "ElementAttributesProperty",
Element: "Element"
};
let subtypeRelation: Map<RelationComparisonResult> = {};
let assignableRelation: Map<RelationComparisonResult> = {};
let identityRelation: Map<RelationComparisonResult> = {};
@ -2009,7 +2027,7 @@ namespace ts {
// If the binding pattern is empty, this variable declaration is not visible
return false;
}
// Otherwise fall through
// Otherwise fall through
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
@ -3785,6 +3803,16 @@ namespace ts {
return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), arity);
}
/**
* Returns a type that is inside a namespace at the global scope, e.g.
* getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type
*/
function getExportedTypeFromNamespace(namespace: string, name: string): Type {
var namespaceSymbol = getGlobalSymbol(namespace, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);
var typeSymbol = namespaceSymbol && getSymbol(namespaceSymbol.exports, name, SymbolFlags.Type);
return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol);
}
function getGlobalESSymbolConstructorSymbol() {
return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol"));
}
@ -5538,6 +5566,7 @@ namespace ts {
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.PrefixUnaryExpression:
case SyntaxKind.DeleteExpression:
@ -5564,6 +5593,12 @@ namespace ts {
case SyntaxKind.ThrowStatement:
case SyntaxKind.TryStatement:
case SyntaxKind.CatchClause:
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxAttribute:
case SyntaxKind.JsxSpreadAttribute:
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.JsxExpression:
return forEachChild(node, isAssignedIn);
}
return false;
@ -6330,6 +6365,26 @@ namespace ts {
return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined;
}
function getContextualTypeForJsxExpression(expr: JsxExpression|JsxSpreadAttribute): Type {
// Contextual type only applies to JSX expressions that are in attribute assignments (not in 'Children' positions)
if (expr.parent.kind === SyntaxKind.JsxAttribute) {
let attrib = <JsxAttribute>expr.parent;
let attrsType = getJsxElementAttributesType(<JsxOpeningLikeElement>attrib.parent);
if (!attrsType || isTypeAny(attrsType)) {
return undefined;
}
else {
return getTypeOfPropertyOfType(attrsType, attrib.name.text);
}
}
if (expr.kind === SyntaxKind.JsxSpreadAttribute) {
return getJsxElementAttributesType(<JsxOpeningLikeElement>expr.parent);
}
return undefined;
}
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
function getContextualType(node: Expression): Type {
@ -6357,7 +6412,8 @@ namespace ts {
case SyntaxKind.NewExpression:
return getContextualTypeForArgument(<CallExpression>parent, node);
case SyntaxKind.TypeAssertionExpression:
return getTypeFromTypeNode((<TypeAssertion>parent).type);
case SyntaxKind.AsExpression:
return getTypeFromTypeNode((<AssertionExpression>parent).type);
case SyntaxKind.BinaryExpression:
return getContextualTypeForBinaryOperand(node);
case SyntaxKind.PropertyAssignment:
@ -6371,6 +6427,9 @@ namespace ts {
return getContextualTypeForSubstitutionExpression(<TemplateExpression>parent.parent, node);
case SyntaxKind.ParenthesizedExpression:
return getContextualType(<ParenthesizedExpression>parent);
case SyntaxKind.JsxExpression:
case SyntaxKind.JsxSpreadAttribute:
return getContextualTypeForJsxExpression(<JsxExpression>parent);
}
return undefined;
}
@ -6511,7 +6570,6 @@ namespace ts {
let restArrayType = checkExpression((<SpreadElementExpression>e).expression, contextualMapper);
let restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
(languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined);
if (restElementType) {
elementTypes.push(restElementType);
}
@ -6671,6 +6729,435 @@ namespace ts {
}
}
function checkJsxSelfClosingElement(node: JsxSelfClosingElement) {
checkJsxOpeningLikeElement(node);
return jsxElementType || anyType;
}
function tagNamesAreEquivalent(lhs: EntityName, rhs: EntityName): boolean {
if (lhs.kind !== rhs.kind) {
return false;
}
if (lhs.kind === SyntaxKind.Identifier) {
return (<Identifier>lhs).text === (<Identifier>rhs).text;
}
return (<QualifiedName>lhs).right.text === (<QualifiedName>rhs).right.text &&
tagNamesAreEquivalent((<QualifiedName>lhs).left, (<QualifiedName>rhs).left);
}
function checkJsxElement(node: JsxElement) {
// Check that the closing tag matches
if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
error(node.closingElement, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNode(node.openingElement.tagName));
}
// Check attributes
checkJsxOpeningLikeElement(node.openingElement);
// Check children
for(let child of node.children) {
switch (child.kind) {
case SyntaxKind.JsxExpression:
checkJsxExpression(<JsxExpression>child);
break;
case SyntaxKind.JsxElement:
checkJsxElement(<JsxElement>child);
break;
case SyntaxKind.JsxSelfClosingElement:
checkJsxSelfClosingElement(<JsxSelfClosingElement>child);
break;
default:
// No checks for JSX Text
Debug.assert(child.kind === SyntaxKind.JsxText);
}
}
return jsxElementType || anyType;
}
/**
* Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
*/
function isUnhyphenatedJsxName(name: string) {
// - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers
return name.indexOf("-") < 0;
}
/**
* Returns true iff React would emit this tag name as a string rather than an identifier or qualified name
*/
function isJsxIntrinsicIdentifier(tagName: Identifier|QualifiedName) {
if (tagName.kind === SyntaxKind.QualifiedName) {
return false;
}
else {
return isIntrinsicJsxName((<Identifier>tagName).text);
}
}
function checkJsxAttribute(node: JsxAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
let correspondingPropType: Type = undefined;
// Look up the corresponding property for this attribute
if (elementAttributesType === emptyObjectType && isUnhyphenatedJsxName(node.name.text)) {
// If there is no 'props' property, you may not have non-"data-" attributes
error(node.parent, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName());
}
else if (elementAttributesType && !isTypeAny(elementAttributesType)) {
let correspondingPropSymbol = getPropertyOfType(elementAttributesType, node.name.text);
correspondingPropType = correspondingPropSymbol && getTypeOfSymbol(correspondingPropSymbol);
// If there's no corresponding property with this name, error
if (!correspondingPropType && isUnhyphenatedJsxName(node.name.text)) {
error(node.name, Diagnostics.Property_0_does_not_exist_on_type_1, node.name.text, typeToString(elementAttributesType));
return unknownType;
}
}
let exprType: Type;
if (node.initializer) {
exprType = checkExpression(node.initializer);
}
else {
// <Elem attr /> is sugar for <Elem attr={true} />
exprType = booleanType;
}
if (correspondingPropType) {
checkTypeAssignableTo(exprType, correspondingPropType, node);
}
nameTable[node.name.text] = true;
return exprType;
}
function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
let type = checkExpression(node.expression);
let props = getPropertiesOfType(type);
for(let prop of props) {
// Is there a corresponding property in the element attributes type? Skip checking of properties
// that have already been assigned to, as these are not actually pushed into the resulting type
if (!nameTable[prop.name]) {
let targetPropSym = getPropertyOfType(elementAttributesType, prop.name);
if (targetPropSym) {
let msg = chainDiagnosticMessages(undefined, Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property, prop.name);
checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(targetPropSym), node, undefined, msg);
}
nameTable[prop.name] = true;
}
}
return type;
}
/// Returns the type JSX.IntrinsicElements. May return `unknownType` if that type is not present.
function getJsxIntrinsicElementsType() {
if (!jsxIntrinsicElementsType) {
jsxIntrinsicElementsType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.IntrinsicElements) || unknownType;
}
return jsxIntrinsicElementsType;
}
/// Given a JSX opening element or self-closing element, return the symbol of the property that the tag name points to if
/// this is an intrinsic tag. This might be a named
/// property of the IntrinsicElements interface, or its string indexer.
/// If this is a class-based tag (otherwise returns undefined), returns the symbol of the class
/// type or factory function.
/// Otherwise, returns unknownSymbol.
function getJsxElementTagSymbol(node: JsxOpeningLikeElement): Symbol {
let flags: JsxFlags = JsxFlags.UnknownElement;
let links = getNodeLinks(node);
if (!links.resolvedSymbol) {
if (isJsxIntrinsicIdentifier(node.tagName)) {
links.resolvedSymbol = lookupIntrinsicTag(node);
} else {
links.resolvedSymbol = lookupClassTag(node);
}
}
return links.resolvedSymbol;
function lookupIntrinsicTag(node: JsxOpeningLikeElement): Symbol {
let intrinsicElementsType = getJsxIntrinsicElementsType();
if (intrinsicElementsType !== unknownType) {
// Property case
let intrinsicProp = getPropertyOfType(intrinsicElementsType, (<Identifier>node.tagName).text);
if (intrinsicProp) {
links.jsxFlags |= JsxFlags.IntrinsicNamedElement;
return intrinsicProp;
}
// Intrinsic string indexer case
let indexSignatureType = getIndexTypeOfType(intrinsicElementsType, IndexKind.String);
if (indexSignatureType) {
links.jsxFlags |= JsxFlags.IntrinsicIndexedElement;
return intrinsicElementsType.symbol;
}
// Wasn't found
error(node, Diagnostics.Property_0_does_not_exist_on_type_1, (<Identifier>node.tagName).text, 'JSX.' + JsxNames.IntrinsicElements);
return unknownSymbol;
}
else {
if (compilerOptions.noImplicitAny) {
error(node, Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, JsxNames.IntrinsicElements);
}
}
}
function lookupClassTag(node: JsxOpeningLikeElement): Symbol {
let valueSymbol: Symbol;
// Look up the value in the current scope
if (node.tagName.kind === SyntaxKind.Identifier) {
valueSymbol = getResolvedSymbol(<Identifier>node.tagName);
}
else {
valueSymbol = checkQualifiedName(<QualifiedName>node.tagName).symbol;
}
if (valueSymbol !== unknownSymbol) {
links.jsxFlags |= JsxFlags.ClassElement;
}
return valueSymbol || unknownSymbol;
}
}
/**
* Given a JSX element that is a class element, finds the Element Instance Type. If the
* element is not a class element, or the class element type cannot be determined, returns 'undefined'.
* For example, in the element <MyClass>, the element instance type is `MyClass` (not `typeof MyClass`).
*/
function getJsxElementInstanceType(node: JsxOpeningLikeElement) {
if (!(getNodeLinks(node).jsxFlags & JsxFlags.ClassElement)) {
// There is no such thing as an instance type for a non-class element
return undefined;
}
let classSymbol = getJsxElementTagSymbol(node);
if (classSymbol === unknownSymbol) {
// Couldn't find the class instance type. Error has already been issued
return anyType;
}
let valueType = getTypeOfSymbol(classSymbol);
if (isTypeAny(valueType)) {
// Short-circuit if the class tag is using an element type 'any'
return anyType;
}
// Resolve the signatures, preferring constructors
let signatures = getSignaturesOfType(valueType, SignatureKind.Construct);
if (signatures.length === 0) {
// No construct signatures, try call signatures
signatures = getSignaturesOfType(valueType, SignatureKind.Call);
if (signatures.length === 0) {
// We found no signatures at all, which is an error
error(node.tagName, Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, getTextOfNode(node.tagName));
return undefined;
}
}
// Check that the constructor/factory returns an object type
let returnType = getUnionType(signatures.map(s => getReturnTypeOfSignature(s)));
if (!isTypeAny(returnType) && !(returnType.flags & TypeFlags.ObjectType)) {
error(node.tagName, Diagnostics.The_return_type_of_a_JSX_element_constructor_must_return_an_object_type);
return undefined;
}
// Issue an error if this return type isn't assignable to JSX.ElementClass
let elemClassType = getJsxGlobalElementClassType();
if (elemClassType) {
checkTypeRelatedTo(returnType, elemClassType, assignableRelation, node, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
}
return returnType;
}
/// e.g. "props" for React.d.ts,
/// or 'undefined' if ElementAttributesPropery doesn't exist (which means all
/// non-intrinsic elements' attributes type is 'any'),
/// or '' if it has 0 properties (which means every
/// non-instrinsic elements' attributes type is the element instance type)
function getJsxElementPropertiesName() {
// JSX
let jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/undefined);
// JSX.ElementAttributesProperty [symbol]
let attribsPropTypeSym = jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.ElementAttributesPropertyNameContainer, SymbolFlags.Type);
// JSX.ElementAttributesProperty [type]
let attribPropType = attribsPropTypeSym && getDeclaredTypeOfSymbol(attribsPropTypeSym);
// The properites of JSX.ElementAttributesProperty
let attribProperties = attribPropType && getPropertiesOfType(attribPropType);
if (attribProperties) {
// Element Attributes has zero properties, so the element attributes type will be the class instance type
if (attribProperties.length === 0) {
return "";
}
// Element Attributes has one property, so the element attributes type will be the type of the corresponding
// property of the class instance type
else if (attribProperties.length === 1) {
return attribProperties[0].name;
}
// More than one property on ElementAttributesProperty is an error
else {
error(attribsPropTypeSym.declarations[0], Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, JsxNames.ElementAttributesPropertyNameContainer);
return undefined;
}
}
else {
// No interface exists, so the element attributes type will be an implicit any
return undefined;
}
}
/**
* Given an opening/self-closing element, get the 'element attributes type', i.e. the type that tells
* us which attributes are valid on a given element.
*/
function getJsxElementAttributesType(node: JsxOpeningLikeElement): Type {
let links = getNodeLinks(node);
if (!links.resolvedJsxType) {
let sym = getJsxElementTagSymbol(node);
if (links.jsxFlags & JsxFlags.ClassElement) {
let elemInstanceType = getJsxElementInstanceType(node);
if (isTypeAny(elemInstanceType)) {
return links.resolvedJsxType = anyType;
}
var propsName = getJsxElementPropertiesName();
if (propsName === undefined) {
// There is no type ElementAttributesProperty, return 'any'
return links.resolvedJsxType = anyType;
}
else if (propsName === "") {
// If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead
return links.resolvedJsxType = elemInstanceType;
}
else {
var attributesType = getTypeOfPropertyOfType(elemInstanceType, propsName);
if (!attributesType) {
// There is no property named 'props' on this instance type
return links.resolvedJsxType = emptyObjectType;
}
else if (isTypeAny(attributesType) || (attributesType === unknownType)) {
return links.resolvedJsxType = attributesType;
}
else if (!(attributesType.flags & TypeFlags.ObjectType)) {
error(node.tagName, Diagnostics.JSX_element_attributes_type_0_must_be_an_object_type, typeToString(attributesType));
return links.resolvedJsxType = anyType;
}
else {
return links.resolvedJsxType = attributesType;
}
}
}
else if (links.jsxFlags & JsxFlags.IntrinsicNamedElement) {
return links.resolvedJsxType = getTypeOfSymbol(sym);
}
else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) {
return links.resolvedJsxType = getIndexTypeOfSymbol(sym, IndexKind.String);
}
else {
// Resolution failed, so we don't know
return links.resolvedJsxType = anyType;
}
}
return links.resolvedJsxType;
}
/**
* Given a JSX attribute, returns the symbol for the corresponds property
* of the element attributes type. Will return unknownSymbol for attributes
* that have no matching element attributes type property.
*/
function getJsxAttributePropertySymbol(attrib: JsxAttribute): Symbol {
let attributesType = getJsxElementAttributesType(<JsxOpeningElement>attrib.parent);
let prop = getPropertyOfType(attributesType, attrib.name.text);
return prop || unknownSymbol;
}
let jsxElementClassType: Type = undefined;
function getJsxGlobalElementClassType(): Type {
if(!jsxElementClassType) {
jsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
}
return jsxElementClassType;
}
/// Returns all the properties of the Jsx.IntrinsicElements interface
function getJsxIntrinsicTagNames(): Symbol[] {
let intrinsics = getJsxIntrinsicElementsType();
return intrinsics ? getPropertiesOfType(intrinsics) : emptyArray;
}
function checkJsxPreconditions(errorNode: Node) {
// Preconditions for using JSX
if ((compilerOptions.jsx || JsxEmit.None) === JsxEmit.None) {
error(errorNode, Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
}
if (jsxElementType === undefined) {
if(compilerOptions.noImplicitAny) {
error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
}
}
}
function checkJsxOpeningLikeElement(node: JsxOpeningLikeElement) {
checkGrammarJsxElement(node);
checkJsxPreconditions(node);
let targetAttributesType = getJsxElementAttributesType(node);
let nameTable: Map<boolean> = {};
// Process this array in right-to-left order so we know which
// attributes (mostly from spreads) are being overwritten and
// thus should have their types ignored
let sawSpreadedAny = false;
for (let i = node.attributes.length - 1; i >= 0; i--) {
if (node.attributes[i].kind === SyntaxKind.JsxAttribute) {
checkJsxAttribute(<JsxAttribute>(node.attributes[i]), targetAttributesType, nameTable);
}
else {
Debug.assert(node.attributes[i].kind === SyntaxKind.JsxSpreadAttribute);
let spreadType = checkJsxSpreadAttribute(<JsxSpreadAttribute>(node.attributes[i]), targetAttributesType, nameTable);
if(isTypeAny(spreadType)) {
sawSpreadedAny = true;
}
}
}
// Check that all required properties have been provided. If an 'any'
// was spreaded in, though, assume that it provided all required properties
if (targetAttributesType && !sawSpreadedAny) {
let targetProperties = getPropertiesOfType(targetAttributesType);
for (let i = 0; i < targetProperties.length; i++) {
if (!(targetProperties[i].flags & SymbolFlags.Optional) &&
nameTable[targetProperties[i].name] === undefined) {
error(node, Diagnostics.Property_0_is_missing_in_type_1, targetProperties[i].name, typeToString(targetAttributesType));
}
}
}
}
function checkJsxExpression(node: JsxExpression) {
if (node.expression) {
return checkExpression(node.expression);
}
else {
return unknownType;
}
}
// If a symbol is a synthesized symbol with no value declaration, we assume it is a property. Example of this are the synthesized
// '.prototype' property as well as synthesized tuple index properties.
function getDeclarationKindFromSymbol(s: Symbol) {
@ -7725,7 +8212,7 @@ namespace ts {
if (!hasCorrectArity(node, args, originalCandidate)) {
continue;
}
let candidate: Signature;
let typeArgumentsAreValid: boolean;
let inferenceContext = originalCandidate.typeParameters
@ -8034,7 +8521,7 @@ namespace ts {
return getReturnTypeOfSignature(getResolvedSignature(node));
}
function checkTypeAssertion(node: TypeAssertion): Type {
function checkAssertion(node: AssertionExpression) {
let exprType = checkExpression(node.expression);
let targetType = getTypeFromTypeNode(node.type);
if (produceDiagnostics && targetType !== unknownType) {
@ -8207,7 +8694,6 @@ namespace ts {
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, contextualMapper?: TypeMapper): Type {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
// Grammar checking
let hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
if (!hasGrammarError && node.kind === SyntaxKind.FunctionExpression) {
@ -8691,7 +9177,7 @@ namespace ts {
if (!checkForDisallowedESSymbolOperand(operator)) {
return booleanType;
}
// Fall through
// Fall through
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
@ -8719,8 +9205,8 @@ namespace ts {
function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
let offendingSymbolOperand =
someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? node.left :
someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? node.right :
undefined;
someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? node.right :
undefined;
if (offendingSymbolOperand) {
error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(operator));
return false;
@ -8975,8 +9461,6 @@ namespace ts {
return checkCallExpression(<CallExpression>node);
case SyntaxKind.TaggedTemplateExpression:
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.TypeAssertionExpression:
return checkTypeAssertion(<TypeAssertion>node);
case SyntaxKind.ParenthesizedExpression:
return checkExpression((<ParenthesizedExpression>node).expression, contextualMapper);
case SyntaxKind.ClassExpression:
@ -8986,6 +9470,9 @@ namespace ts {
return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression>node, contextualMapper);
case SyntaxKind.TypeOfExpression:
return checkTypeOfExpression(<TypeOfExpression>node);
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.AsExpression:
return checkAssertion(<AssertionExpression>node);
case SyntaxKind.DeleteExpression:
return checkDeleteExpression(<DeleteExpression>node);
case SyntaxKind.VoidExpression:
@ -9004,6 +9491,14 @@ namespace ts {
return undefinedType;
case SyntaxKind.YieldExpression:
return checkYieldExpression(<YieldExpression>node);
case SyntaxKind.JsxExpression:
return checkJsxExpression(<JsxExpression>node);
case SyntaxKind.JsxElement:
return checkJsxElement(<JsxElement>node);
case SyntaxKind.JsxSelfClosingElement:
return checkJsxSelfClosingElement(<JsxSelfClosingElement>node);
case SyntaxKind.JsxOpeningElement:
Debug.fail("Shouldn't ever directly check a JsxOpeningElement");
}
return unknownType;
}
@ -9918,7 +10413,7 @@ namespace ts {
case SyntaxKind.MethodDeclaration:
checkParameterTypeAnnotationsAsExpressions(<FunctionLikeDeclaration>node);
// fall-through
// fall-through
case SyntaxKind.SetAccessor:
case SyntaxKind.GetAccessor:
@ -10495,7 +10990,7 @@ namespace ts {
if (allowStringInput) {
return checkElementTypeOfArrayOrString(inputType, errorNode);
}
if (isArrayLikeType(inputType)) {
let indexType = getIndexTypeOfType(inputType, IndexKind.Number);
if (indexType) {
@ -11581,7 +12076,7 @@ namespace ts {
// if the module merges with a class declaration in the same lexical scope,
// we need to track this to ensure the correct emit.
let mergedClass = getDeclarationOfKind(symbol, SyntaxKind.ClassDeclaration);
let mergedClass = getDeclarationOfKind(symbol, SyntaxKind.ClassDeclaration);
if (mergedClass &&
inSameLexicalScope(node, mergedClass)) {
getNodeLinks(node).flags |= NodeCheckFlags.LexicalModuleMergesWithClass;
@ -12008,6 +12503,7 @@ namespace ts {
case SyntaxKind.TemplateExpression:
case SyntaxKind.TemplateSpan:
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.TypeOfExpression:
case SyntaxKind.VoidExpression:
@ -12045,6 +12541,12 @@ namespace ts {
case SyntaxKind.EnumMember:
case SyntaxKind.ExportAssignment:
case SyntaxKind.SourceFile:
case SyntaxKind.JsxExpression:
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxAttribute:
case SyntaxKind.JsxSpreadAttribute:
case SyntaxKind.JsxOpeningElement:
forEachChild(node, checkFunctionAndClassExpressionBodies);
break;
}
@ -12298,6 +12800,9 @@ namespace ts {
meaning |= SymbolFlags.Alias;
return resolveEntityName(<EntityName>entityName, meaning);
}
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) || (entityName.parent.kind === SyntaxKind.JsxSelfClosingElement)) {
return getJsxElementTagSymbol(<JsxOpeningLikeElement>entityName.parent);
}
else if (isExpression(entityName)) {
if (nodeIsMissing(entityName)) {
// Missing entity name.
@ -12332,6 +12837,9 @@ namespace ts {
meaning |= SymbolFlags.Alias;
return resolveEntityName(<EntityName>entityName, meaning);
}
else if (entityName.parent.kind === SyntaxKind.JsxAttribute) {
return getJsxAttributePropertySymbol(<JsxAttribute>entityName.parent);
}
if (entityName.parent.kind === SyntaxKind.TypePredicate) {
return resolveEntityName(<Identifier>entityName, /*meaning*/ SymbolFlags.FunctionScopedVariable);
@ -12466,6 +12974,7 @@ namespace ts {
return unknownType;
}
function getTypeOfExpression(expr: Expression): Type {
if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
expr = <Expression>expr.parent;
@ -12807,7 +13316,7 @@ namespace ts {
break;
}
}
return "Object";
}
@ -12933,7 +13442,7 @@ namespace ts {
let isVariableDeclarationOrBindingElement =
n.parent.kind === SyntaxKind.BindingElement || (n.parent.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>n.parent).name === n);
let symbol =
let symbol =
(isVariableDeclarationOrBindingElement ? getSymbolOfNode(n.parent) : undefined) ||
getNodeLinks(n).resolvedSymbol ||
resolveName(n, n.text, SymbolFlags.Value | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined);
@ -12961,7 +13470,7 @@ namespace ts {
if (!signature) {
return unknownType;
}
let instantiatedSignature = getSignatureInstantiation(signature, typeArguments);
return getOrCreateTypeFromSignature(instantiatedSignature);
}
@ -13020,6 +13529,11 @@ namespace ts {
globalNumberType = getGlobalType("Number");
globalBooleanType = getGlobalType("Boolean");
globalRegExpType = getGlobalType("RegExp");
jsxElementType = getExportedTypeFromNamespace("JSX", JsxNames.Element);
getGlobalClassDecoratorType = memoize(() => getGlobalType("ClassDecorator"));
getGlobalPropertyDecoratorType = memoize(() => getGlobalType("PropertyDecorator"));
getGlobalMethodDecoratorType = memoize(() => getGlobalType("MethodDecorator"));
getGlobalParameterDecoratorType = memoize(() => getGlobalType("ParameterDecorator"));
getGlobalTypedPropertyDescriptorType = memoize(() => getGlobalType("TypedPropertyDescriptor", /*arity*/ 1));
// If we're in ES6 mode, load the TemplateStringsArray.
@ -13049,7 +13563,6 @@ namespace ts {
}
// GRAMMAR CHECKING
function checkGrammarDecorators(node: Node): boolean {
if (!node.decorators) {
return false;
@ -13501,13 +14014,13 @@ namespace ts {
let currentKind: number;
if (prop.kind === SyntaxKind.PropertyAssignment || prop.kind === SyntaxKind.ShorthandPropertyAssignment) {
// Grammar checking for computedPropertName and shorthandPropertyAssignment
checkGrammarForInvalidQuestionMark(prop,(<PropertyAssignment>prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional);
checkGrammarForInvalidQuestionMark(prop, (<PropertyAssignment>prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional);
if (name.kind === SyntaxKind.NumericLiteral) {
checkGrammarNumericLiteral(<Identifier>name);
}
currentKind = Property;
}
else if ( prop.kind === SyntaxKind.MethodDeclaration) {
else if (prop.kind === SyntaxKind.MethodDeclaration) {
currentKind = Property;
}
else if (prop.kind === SyntaxKind.GetAccessor) {
@ -13543,6 +14056,29 @@ namespace ts {
}
}
function checkGrammarJsxElement(node: JsxOpeningElement|JsxSelfClosingElement) {
const seen: Map<boolean> = {};
for (let attr of node.attributes) {
if (attr.kind === SyntaxKind.JsxSpreadAttribute) {
continue;
}
let jsxAttr = (<JsxAttribute>attr);
let name = jsxAttr.name;
if (!hasProperty(seen, name.text)) {
seen[name.text] = true;
}
else {
return grammarErrorOnNode(name, Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
}
let initializer = jsxAttr.initializer;
if (initializer && initializer.kind === SyntaxKind.JsxExpression && !(<JsxExpression>initializer).expression) {
return grammarErrorOnNode(jsxAttr.initializer, Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression);
}
}
}
function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInStatement | ForOfStatement): boolean {
if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
return true;
@ -13771,7 +14307,7 @@ namespace ts {
}
}
let checkLetConstNames = languageVersion >= ScriptTarget.ES6 && (isLet(node) || isConst(node));
let checkLetConstNames = languageVersion >= ScriptTarget.ES6 && (isLet(node) || isConst(node));
// 1. LexicalDeclaration : LetOrConst BindingList ;
// It is a Syntax Error if the BoundNames of BindingList contains "let".
@ -13919,6 +14455,11 @@ namespace ts {
}
}
function isEvalOrArgumentsIdentifier(node: Node): boolean {
return node.kind === SyntaxKind.Identifier &&
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
}
function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) {
if (node.typeParameters) {
return grammarErrorAtPos(getSourceFileOfNode(node), node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);

View file

@ -38,6 +38,16 @@ namespace ts {
name: "inlineSources",
type: "boolean",
},
{
name: "jsx",
type: {
"preserve": JsxEmit.Preserve,
"react": JsxEmit.React
},
paramType: Diagnostics.KIND,
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
error: Diagnostics.Argument_for_jsx_must_be_preserve_or_react
},
{
name: "listFiles",
type: "boolean",
@ -401,18 +411,29 @@ namespace ts {
}
function getFileNames(): string[] {
var fileNames: string[] = [];
let fileNames: string[] = [];
if (hasProperty(json, "files")) {
if (json["files"] instanceof Array) {
fileNames = map(<string[]>json["files"], s => combinePaths(basePath, s));
}
}
else {
var exclude = json["exclude"] instanceof Array ? map(<string[]>json["exclude"], normalizeSlashes) : undefined;
var sysFiles = host.readDirectory(basePath, ".ts", exclude);
for (var i = 0; i < sysFiles.length; i++) {
var name = sysFiles[i];
if (!fileExtensionIs(name, ".d.ts") || !contains(sysFiles, name.substr(0, name.length - 5) + ".ts")) {
let exclude = json["exclude"] instanceof Array ? map(<string[]>json["exclude"], normalizeSlashes) : undefined;
let sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
for (let i = 0; i < sysFiles.length; i++) {
let name = sysFiles[i];
if (fileExtensionIs(name, ".d.ts")) {
let baseName = name.substr(0, name.length - ".d.ts".length);
if (!contains(sysFiles, baseName + ".tsx") && !contains(sysFiles, baseName + ".ts")) {
fileNames.push(name);
}
}
else if (fileExtensionIs(name, ".ts")) {
if (!contains(sysFiles, name + "x")) {
fileNames.push(name)
}
}
else {
fileNames.push(name);
}
}

View file

@ -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)) {

View file

@ -382,6 +382,16 @@ namespace ts {
No_base_constructor_has_the_specified_number_of_type_arguments: { code: 2508, category: DiagnosticCategory.Error, key: "No base constructor has the specified number of type arguments." },
Base_constructor_return_type_0_is_not_a_class_or_interface_type: { code: 2509, category: DiagnosticCategory.Error, key: "Base constructor return type '{0}' is not a class or interface type." },
Base_constructors_must_all_have_the_same_return_type: { code: 2510, category: DiagnosticCategory.Error, key: "Base constructors must all have the same return type." },
JSX_element_attributes_type_0_must_be_an_object_type: { code: 2600, category: DiagnosticCategory.Error, key: "JSX element attributes type '{0}' must be an object type." },
The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: { code: 2601, category: DiagnosticCategory.Error, key: "The return type of a JSX element constructor must return an object type." },
JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: { code: 2602, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist." },
Property_0_in_type_1_is_not_assignable_to_type_2: { code: 2603, category: DiagnosticCategory.Error, key: "Property '{0}' in type '{1}' is not assignable to type '{2}'" },
JSX_element_type_0_does_not_have_any_construct_or_call_signatures: { code: 2604, category: DiagnosticCategory.Error, key: "JSX element type '{0}' does not have any construct or call signatures." },
JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: { code: 2605, category: DiagnosticCategory.Error, key: "JSX element type '{0}' is not a constructor function for JSX elements." },
Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: { code: 2606, category: DiagnosticCategory.Error, key: "Property '{0}' of JSX spread attribute is not assignable to target property." },
JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" },
The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" },
Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
@ -523,6 +533,8 @@ namespace ts {
Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: { code: 6060, category: DiagnosticCategory.Message, key: "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." },
NEWLINE: { code: 6061, category: DiagnosticCategory.Message, key: "NEWLINE" },
Argument_for_newLine_option_must_be_CRLF_or_LF: { code: 6062, category: DiagnosticCategory.Error, key: "Argument for '--newLine' option must be 'CRLF' or 'LF'." },
Specify_JSX_code_generation_Colon_preserve_or_react: { code: 6080, category: DiagnosticCategory.Message, key: "Specify JSX code generation: 'preserve' or 'react'" },
Argument_for_jsx_must_be_preserve_or_react: { code: 6081, category: DiagnosticCategory.Message, key: "Argument for '--jsx' must be 'preserve' or 'react'." },
Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." },
Enables_experimental_support_for_ES7_decorators: { code: 6065, category: DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." },
Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." },
@ -542,6 +554,7 @@ namespace ts {
_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." },
JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: { code: 7026, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists" },
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." },
import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." },
@ -559,5 +572,12 @@ namespace ts {
enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." },
type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." },
decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." },
Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." },
class_expressions_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'class' expressions are not currently supported." },
JSX_attributes_must_only_be_assigned_a_non_empty_expression: { code: 17000, category: DiagnosticCategory.Error, key: "JSX attributes must only be assigned a non-empty 'expression'." },
JSX_elements_cannot_have_multiple_attributes_with_the_same_name: { code: 17001, category: DiagnosticCategory.Error, key: "JSX elements cannot have multiple attributes with the same name." },
Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: DiagnosticCategory.Error, key: "Expected corresponding JSX closing tag for '{0}'." },
JSX_attribute_expected: { code: 17003, category: DiagnosticCategory.Error, key: "JSX attribute expected." },
Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: DiagnosticCategory.Error, key: "Cannot use JSX unless the '--jsx' flag is provided." },
};
}

View file

@ -638,7 +638,7 @@
"Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning.": {
"category": "Error",
"code": 1219
},
},
"Generators are only available when targeting ECMAScript 6 or higher.": {
"category": "Error",
"code": 1220
@ -1519,6 +1519,47 @@
"code": 2510
},
"JSX element attributes type '{0}' must be an object type.": {
"category": "Error",
"code": 2600
},
"The return type of a JSX element constructor must return an object type.": {
"category": "Error",
"code": 2601
},
"JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.": {
"category": "Error",
"code": 2602
},
"Property '{0}' in type '{1}' is not assignable to type '{2}'": {
"category": "Error",
"code": 2603
},
"JSX element type '{0}' does not have any construct or call signatures.": {
"category": "Error",
"code": 2604
},
"JSX element type '{0}' is not a constructor function for JSX elements.": {
"category": "Error",
"code": 2605
},
"Property '{0}' of JSX spread attribute is not assignable to target property.": {
"category": "Error",
"code": 2606
},
"JSX element class does not support attributes because it does not have a '{0}' property": {
"category": "Error",
"code": 2607
},
"The global type 'JSX.{0}' may not have more than one property": {
"category": "Error",
"code": 2608
},
"Cannot emit namespaced JSX elements in React": {
"category": "Error",
"code": 2650
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000
@ -1887,7 +1928,7 @@
"category": "Error",
"code": 5050
},
"Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided.": {
"Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided.": {
"category": "Error",
"code": 5051
},
@ -2076,14 +2117,22 @@
"category": "Message",
"code": 6060
},
"NEWLINE": {
"category": "Message",
"NEWLINE": {
"category": "Message",
"code": 6061
},
"Argument for '--newLine' option must be 'CRLF' or 'LF'.": {
"category": "Error",
"category": "Error",
"code": 6062
},
"Specify JSX code generation: 'preserve' or 'react'": {
"category": "Message",
"code": 6080
},
"Argument for '--jsx' must be 'preserve' or 'react'.": {
"category": "Message",
"code": 6081
},
"Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified.": {
"category": "Error",
"code": 6064
@ -2161,6 +2210,12 @@
"category": "Error",
"code": 7025
},
"JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists": {
"category": "Error",
"code": 7026
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
@ -2228,5 +2283,34 @@
"'decorators' can only be used in a .ts file.": {
"category": "Error",
"code": 8017
},
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": {
"category": "Error",
"code": 9002
},
"'class' expressions are not currently supported.": {
"category": "Error",
"code": 9003
},
"JSX attributes must only be assigned a non-empty 'expression'.": {
"category": "Error",
"code": 17000
},
"JSX elements cannot have multiple attributes with the same name.": {
"category": "Error",
"code": 17001
},
"Expected corresponding JSX closing tag for '{0}'.": {
"category": "Error",
"code": 17002
},
"JSX attribute expected.": {
"category": "Error",
"code": 17003
},
"Cannot use JSX unless the '--jsx' flag is provided.": {
"category": "Error",
"code": 17004
}
}

View file

@ -47,16 +47,19 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};`;
let compilerOptions = host.getCompilerOptions();
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
let sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
let diagnostics: Diagnostic[] = [];
let newLine = host.getNewLine();
let jsxDesugaring = host.getCompilerOptions().jsx !== JsxEmit.Preserve;
let shouldEmitJsx = (s: SourceFile) => (s.languageVariant === LanguageVariant.JSX && !jsxDesugaring);
if (targetSourceFile === undefined) {
forEach(host.getSourceFiles(), sourceFile => {
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
let jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, ".js");
let jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, shouldEmitJsx(sourceFile) ? ".jsx" : ".js");
emitFile(jsFilePath, sourceFile);
}
});
@ -68,7 +71,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
else {
// targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service)
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
let jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
let jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, host, forEach(host.getSourceFiles(), shouldEmitJsx) ? ".jsx" : ".js");
emitFile(jsFilePath, targetSourceFile);
}
else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) {
@ -1111,6 +1114,224 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emit(span.literal);
}
function jsxEmitReact(node: JsxElement|JsxSelfClosingElement) {
/// Emit a tag name, which is either '"div"' for lower-cased names, or
/// 'Div' for upper-cased or dotted names
function emitTagName(name: Identifier|QualifiedName) {
if (name.kind === SyntaxKind.Identifier && isIntrinsicJsxName((<Identifier>name).text)) {
write('"');
emit(name);
write('"');
}
else {
emit(name);
}
}
/// Emit an attribute name, which is quoted if it needs to be quoted. Because
/// these emit into an object literal property name, we don't need to be worried
/// about keywords, just non-identifier characters
function emitAttributeName(name: Identifier) {
if (/[A-Za-z_]+[\w*]/.test(name.text)) {
write('"');
emit(name);
write('"');
}
else {
emit(name);
}
}
/// Emit an name/value pair for an attribute (e.g. "x: 3")
function emitJsxAttribute(node: JsxAttribute) {
emitAttributeName(node.name);
write(": ");
if (node.initializer) {
emit(node.initializer);
}
else {
write("true");
}
}
function emitJsxElement(openingNode: JsxOpeningLikeElement, children?: JsxChild[]) {
// Call React.createElement(tag, ...
emitLeadingComments(openingNode);
write("React.createElement(");
emitTagName(openingNode.tagName);
write(", ");
// Attribute list
if (openingNode.attributes.length === 0) {
// When there are no attributes, React wants "null"
write("null");
}
else {
// Either emit one big object literal (no spread attribs), or
// a call to React.__spread
let attrs = openingNode.attributes;
if (forEach(attrs, attr => attr.kind === SyntaxKind.JsxSpreadAttribute)) {
write("React.__spread(");
let haveOpenedObjectLiteral = false;
for (let i = 0; i < attrs.length; i++) {
if (attrs[i].kind === SyntaxKind.JsxSpreadAttribute) {
// If this is the first argument, we need to emit a {} as the first argument
if (i === 0) {
write("{}, ");
}
if (haveOpenedObjectLiteral) {
write("}");
haveOpenedObjectLiteral = false;
}
if (i > 0) {
write(", ");
}
emit((<JsxSpreadAttribute>attrs[i]).expression);
}
else {
Debug.assert(attrs[i].kind === SyntaxKind.JsxAttribute);
if (haveOpenedObjectLiteral) {
write(", ");
}
else {
haveOpenedObjectLiteral = true;
if (i > 0) {
write(", ");
}
write("{");
}
emitJsxAttribute(<JsxAttribute>attrs[i]);
}
}
if (haveOpenedObjectLiteral) write("}");
write(")"); // closing paren to React.__spread(
}
else {
// One object literal with all the attributes in them
write("{");
for (var i = 0; i < attrs.length; i++) {
if (i > 0) {
write(", ");
}
emitJsxAttribute(<JsxAttribute>attrs[i]);
}
write("}");
}
}
// Children
if (children) {
for (var i = 0; i < children.length; i++) {
// Don't emit empty expressions
if (children[i].kind === SyntaxKind.JsxExpression && !((<JsxExpression>children[i]).expression)) {
continue;
}
// Don't emit empty strings
if (children[i].kind === SyntaxKind.JsxText) {
let text = getTextToEmit(<JsxText>children[i]);
if(text !== undefined) {
write(', "');
write(text);
write('"');
}
}
else {
write(", ");
emit(children[i]);
}
}
}
// Closing paren
write(")"); // closes "React.createElement("
emitTrailingComments(openingNode);
}
if (node.kind === SyntaxKind.JsxElement) {
emitJsxElement((<JsxElement>node).openingElement, (<JsxElement>node).children);
}
else {
Debug.assert(node.kind === SyntaxKind.JsxSelfClosingElement);
emitJsxElement(<JsxSelfClosingElement>node);
}
}
function jsxEmitPreserve(node: JsxElement|JsxSelfClosingElement) {
function emitJsxAttribute(node: JsxAttribute) {
emit(node.name);
write("=");
emit(node.initializer);
}
function emitJsxSpreadAttribute(node: JsxSpreadAttribute) {
write("{...");
emit(node.expression);
write("}");
}
function emitAttributes(attribs: NodeArray<JsxAttribute|JsxSpreadAttribute>) {
for (let i = 0, n = attribs.length; i < n; i++) {
if (i > 0) {
write(" ");
}
if (attribs[i].kind === SyntaxKind.JsxSpreadAttribute) {
emitJsxSpreadAttribute(<JsxSpreadAttribute>attribs[i]);
}
else {
Debug.assert(attribs[i].kind === SyntaxKind.JsxAttribute);
emitJsxAttribute(<JsxAttribute>attribs[i]);
}
}
}
function emitJsxOpeningOrSelfClosingElement(node: JsxOpeningElement|JsxSelfClosingElement) {
write("<");
emit(node.tagName);
if (node.attributes.length > 0 || (node.kind === SyntaxKind.JsxSelfClosingElement)) {
write(" ");
}
emitAttributes(node.attributes);
if (node.kind === SyntaxKind.JsxSelfClosingElement) {
write("/>");
}
else {
write(">");
}
}
function emitJsxClosingElement(node: JsxClosingElement) {
write("</");
emit(node.tagName);
write(">");
}
function emitJsxElement(node: JsxElement) {
emitJsxOpeningOrSelfClosingElement(node.openingElement);
for (var i = 0, n = node.children.length; i < n; i++) {
emit(node.children[i]);
}
emitJsxClosingElement(node.closingElement);
}
if (node.kind === SyntaxKind.JsxElement) {
emitJsxElement(<JsxElement>node);
}
else {
Debug.assert(node.kind === SyntaxKind.JsxSelfClosingElement);
emitJsxOpeningOrSelfClosingElement(<JsxSelfClosingElement>node);
}
}
// This function specifically handles numeric/string literals for enum and accessor 'identifiers'.
// In a sense, it does not actually emit identifiers as much as it declares a name for a specific property.
// For example, this is utilized when feeding in a result to Object.defineProperty.
@ -1187,6 +1408,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
case SyntaxKind.IfStatement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
case SyntaxKind.NewExpression:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.PostfixUnaryExpression:
@ -1663,8 +1886,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
function parenthesizeForAccess(expr: Expression): LeftHandSideExpression {
// When diagnosing whether the expression needs parentheses, the decision should be based
// on the innermost expression in a chain of nested type assertions.
while (expr.kind === SyntaxKind.TypeAssertionExpression) {
expr = (<TypeAssertion>expr).expression;
while (expr.kind === SyntaxKind.TypeAssertionExpression || expr.kind === SyntaxKind.AsExpression) {
expr = (<AssertionExpression>expr).expression;
}
// isLeftHandSideExpression is almost the correct criterion for when it is not necessary
@ -1824,8 +2047,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function skipParentheses(node: Expression): Expression {
while (node.kind === SyntaxKind.ParenthesizedExpression || node.kind === SyntaxKind.TypeAssertionExpression) {
node = (<ParenthesizedExpression | TypeAssertion>node).expression;
while (node.kind === SyntaxKind.ParenthesizedExpression || node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression) {
node = (<ParenthesizedExpression | AssertionExpression>node).expression;
}
return node;
}
@ -1975,12 +2198,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
// not the user. If we didn't want them, the emitter would not have put them
// there.
if (!nodeIsSynthesized(node) && node.parent.kind !== SyntaxKind.ArrowFunction) {
if (node.expression.kind === SyntaxKind.TypeAssertionExpression) {
if (node.expression.kind === SyntaxKind.TypeAssertionExpression || node.expression.kind === SyntaxKind.AsExpression) {
let operand = (<TypeAssertion>node.expression).expression;
// Make sure we consider all nested cast expressions, e.g.:
// (<any><number><any>-A).x;
while (operand.kind === SyntaxKind.TypeAssertionExpression) {
while (operand.kind === SyntaxKind.TypeAssertionExpression || operand.kind === SyntaxKind.AsExpression) {
operand = (<TypeAssertion>operand).expression;
}
@ -3842,7 +4065,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emitClassLikeDeclarationForES6AndHigher(node);
}
}
function emitClassLikeDeclarationForES6AndHigher(node: ClassLikeDeclaration) {
let thisNodeIsDecorated = nodeIsDecorated(node);
if (node.kind === SyntaxKind.ClassDeclaration) {
@ -4101,7 +4324,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write(".prototype");
}
}
function emitDecoratorsOfClass(node: ClassLikeDeclaration) {
emitDecoratorsOfMembers(node, /*staticFlag*/ 0);
emitDecoratorsOfMembers(node, NodeFlags.Static);
@ -5013,7 +5236,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
let started = false;
for (let importNode of externalImports) {
// do not create variable declaration for exports and imports that lack import clause
let skipNode =
let skipNode =
importNode.kind === SyntaxKind.ExportDeclaration ||
(importNode.kind === SyntaxKind.ImportDeclaration && !(<ImportDeclaration>importNode).importClause)
@ -5110,7 +5333,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
write("};");
return emitExportStarFunction(exportedNamesStorageRef);
function emitExportStarFunction(localNames: string): string {
const exportStarFunction = makeUniqueName("exportStar");
@ -5137,7 +5360,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return exportStarFunction;
}
function writeExportedName(node: Identifier | Declaration): void {
// do not record default exports
// they are local to module and never overwritten (explicitly skipped) by star export
@ -5433,7 +5656,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
if (importNode.kind === SyntaxKind.ImportDeclaration &&
(<ImportDeclaration>importNode).importClause.namedBindings) {
let namedBindings = (<ImportDeclaration>importNode).importClause.namedBindings;
if (namedBindings.kind === SyntaxKind.NamespaceImport) {
// emit re-export for namespace
@ -5692,6 +5915,99 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
}
function emitJsxElement(node: JsxElement | JsxSelfClosingElement) {
switch (compilerOptions.jsx) {
case JsxEmit.React:
jsxEmitReact(node);
break;
case JsxEmit.Preserve:
// Fall back to preserve if None was specified (we'll error earlier)
default:
jsxEmitPreserve(node);
break;
}
}
function trimReactWhitespace(node: JsxText): string {
let result: string = undefined;
let text = getTextOfNode(node);
let firstNonWhitespace = 0;
let lastNonWhitespace = -1;
// JSX trims whitespace at the end and beginning of lines, except that the
// start/end of a tag is considered a start/end of a line only if that line is
// on the same line as the closing tag. See examples in tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
for (let i = 0; i < text.length; i++) {
let c = text.charCodeAt(i);
if (isLineBreak(c)) {
if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) {
let part = text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1);
result = (result ? result + '" + \' \' + "' : '') + part;
}
firstNonWhitespace = -1;
}
else if (!isWhiteSpace(c)) {
lastNonWhitespace = i;
if (firstNonWhitespace === -1) {
firstNonWhitespace = i;
}
}
}
if (firstNonWhitespace !== -1) {
let part = text.substr(firstNonWhitespace);
result = (result ? result + '" + \' \' + "' : '') + part;
}
return result;
}
function getTextToEmit(node: JsxText) {
switch (compilerOptions.jsx) {
case JsxEmit.React:
let text = trimReactWhitespace(node);
if (text.length === 0) {
return undefined;
}
else {
return text;
}
case JsxEmit.Preserve:
default:
return getTextOfNode(node, true);
}
}
function emitJsxText(node: JsxText) {
switch (compilerOptions.jsx) {
case JsxEmit.React:
write('"');
write(trimReactWhitespace(node));
write('"');
break;
case JsxEmit.Preserve:
default: // Emit JSX-preserve as default when no --jsx flag is specified
write(getTextOfNode(node, true));
break;
}
}
function emitJsxExpression(node: JsxExpression) {
if (node.expression) {
switch (compilerOptions.jsx) {
case JsxEmit.Preserve:
default:
write('{');
emit(node.expression);
write('}');
break;
case JsxEmit.React:
emit(node.expression);
break;
}
}
}
function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean): number {
for (let i = 0; i < statements.length; ++i) {
if (isPrologueDirective(statements[i])) {
@ -5834,7 +6150,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
if (node.kind !== SyntaxKind.Block &&
node.parent &&
node.parent.kind === SyntaxKind.ArrowFunction &&
(<ArrowFunction>node.parent).body === node &&
(<ArrowFunction>node.parent).body === node &&
compilerOptions.target <= ScriptTarget.ES5) {
return false;
@ -5879,6 +6195,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return emitTemplateExpression(<TemplateExpression>node);
case SyntaxKind.TemplateSpan:
return emitTemplateSpan(<TemplateSpan>node);
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
return emitJsxElement(<JsxElement|JsxSelfClosingElement>node);
case SyntaxKind.JsxText:
return emitJsxText(<JsxText>node);
case SyntaxKind.JsxExpression:
return emitJsxExpression(<JsxExpression>node);
case SyntaxKind.QualifiedName:
return emitQualifiedName(<QualifiedName>node);
case SyntaxKind.ObjectBindingPattern:
@ -5909,6 +6232,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return emitTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.TypeAssertionExpression:
return emit((<TypeAssertion>node).expression);
case SyntaxKind.AsExpression:
return emit((<AsExpression>node).expression);
case SyntaxKind.ParenthesizedExpression:
return emitParenExpression(<ParenthesizedExpression>node);
case SyntaxKind.FunctionDeclaration:

View file

@ -162,6 +162,9 @@ namespace ts {
return visitNode(cbNode, (<BinaryExpression>node).left) ||
visitNode(cbNode, (<BinaryExpression>node).operatorToken) ||
visitNode(cbNode, (<BinaryExpression>node).right);
case SyntaxKind.AsExpression:
return visitNode(cbNode, (<AsExpression>node).expression) ||
visitNode(cbNode, (<AsExpression>node).type);
case SyntaxKind.ConditionalExpression:
return visitNode(cbNode, (<ConditionalExpression>node).condition) ||
visitNode(cbNode, (<ConditionalExpression>node).questionToken) ||
@ -319,6 +322,25 @@ namespace ts {
return visitNode(cbNode, (<ExternalModuleReference>node).expression);
case SyntaxKind.MissingDeclaration:
return visitNodes(cbNodes, node.decorators);
case SyntaxKind.JsxElement:
return visitNode(cbNode, (<JsxElement>node).openingElement) ||
visitNodes(cbNodes, (<JsxElement>node).children) ||
visitNode(cbNode, (<JsxElement>node).closingElement);
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.JsxOpeningElement:
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
visitNodes(cbNodes, (<JsxOpeningLikeElement>node).attributes);
case SyntaxKind.JsxAttribute:
return visitNode(cbNode, (<JsxAttribute>node).name) ||
visitNode(cbNode, (<JsxAttribute>node).initializer);
case SyntaxKind.JsxSpreadAttribute:
return visitNode(cbNode, (<JsxSpreadAttribute>node).expression);
case SyntaxKind.JsxExpression:
return visitNode(cbNode, (<JsxExpression>node).expression);
case SyntaxKind.JsxClosingElement:
return visitNode(cbNode, (<JsxClosingElement>node).tagName);
case SyntaxKind.JSDocTypeExpression:
return visitNode(cbNode, (<JSDocTypeExpression>node).type);
case SyntaxKind.JSDocUnionType:
@ -522,6 +544,7 @@ namespace ts {
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
scanner.setLanguageVariant(isTsx(fileName) ? LanguageVariant.JSX : LanguageVariant.Standard);
}
function clearState() {
@ -634,6 +657,7 @@ namespace ts {
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = normalizePath(fileName);
sourceFile.flags = fileExtensionIs(sourceFile.fileName, ".d.ts") ? NodeFlags.DeclarationFile : 0;
sourceFile.languageVariant = isTsx(sourceFile.fileName) ? LanguageVariant.JSX : LanguageVariant.Standard;
return sourceFile;
}
@ -804,6 +828,10 @@ namespace ts {
return token = scanner.reScanTemplateToken();
}
function scanJsxIdentifier(): SyntaxKind {
return token = scanner.scanJsxIdentifier();
}
function speculationHelper<T>(callback: () => T, isLookAhead: boolean): T {
// Keep track of the state we'll need to rollback to if lookahead fails (or if the
// caller asked us to always reset our state).
@ -1175,6 +1203,10 @@ namespace ts {
return isHeritageClause();
case ParsingContext.ImportOrExportSpecifiers:
return isIdentifierOrKeyword();
case ParsingContext.JsxAttributes:
return isIdentifierOrKeyword() || token === SyntaxKind.OpenBraceToken;
case ParsingContext.JsxChildren:
return true;
case ParsingContext.JSDocFunctionParameters:
case ParsingContext.JSDocTypeArguments:
case ParsingContext.JSDocTupleTypes:
@ -1265,6 +1297,10 @@ namespace ts {
return token === SyntaxKind.GreaterThanToken || token === SyntaxKind.OpenParenToken;
case ParsingContext.HeritageClauses:
return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.CloseBraceToken;
case ParsingContext.JsxAttributes:
return token === SyntaxKind.GreaterThanToken || token === SyntaxKind.SlashToken;
case ParsingContext.JsxChildren:
return token === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash);
case ParsingContext.JSDocFunctionParameters:
return token === SyntaxKind.CloseParenToken || token === SyntaxKind.ColonToken || token === SyntaxKind.CloseBraceToken;
case ParsingContext.JSDocTypeArguments:
@ -1481,6 +1517,12 @@ namespace ts {
// name list, and there can be left hand side expressions (which can have type
// arguments.)
case ParsingContext.HeritageClauseElement:
// Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
// on any given element. Same for children.
case ParsingContext.JsxAttributes:
case ParsingContext.JsxChildren:
}
return false;
@ -1647,6 +1689,8 @@ namespace ts {
case ParsingContext.TupleElementTypes: return Diagnostics.Type_expected;
case ParsingContext.HeritageClauses: return Diagnostics.Unexpected_token_expected;
case ParsingContext.ImportOrExportSpecifiers: return Diagnostics.Identifier_expected;
case ParsingContext.JsxAttributes: return Diagnostics.Identifier_expected;
case ParsingContext.JsxChildren: return Diagnostics.Identifier_expected;
case ParsingContext.JSDocFunctionParameters: return Diagnostics.Parameter_declaration_expected;
case ParsingContext.JSDocTypeArguments: return Diagnostics.Type_argument_expected;
case ParsingContext.JSDocTupleTypes: return Diagnostics.Type_expected;
@ -2802,6 +2846,33 @@ namespace ts {
return Tristate.False;
}
// JSX overrides
if (sourceFile.languageVariant === LanguageVariant.JSX) {
let isArrowFunctionInJsx = lookAhead(() => {
let third = nextToken();
if (third === SyntaxKind.ExtendsKeyword) {
let fourth = nextToken();
switch (fourth) {
case SyntaxKind.EqualsToken:
case SyntaxKind.GreaterThanToken:
return false;
default:
return true;
}
}
else if (third === SyntaxKind.CommaToken) {
return true;
}
return false;
});
if (isArrowFunctionInJsx) {
return Tristate.True;
}
return Tristate.False;
}
// This *could* be a parenthesized arrow function.
return Tristate.Unknown;
}
@ -2918,7 +2989,23 @@ namespace ts {
break;
}
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
if (token === SyntaxKind.AsKeyword) {
// Make sure we *do* perform ASI for constructs like this:
// var x = foo
// as (Bar)
// This should be parsed as an initialized variable, followed
// by a function call to 'as' with the argument 'Bar'
if (scanner.hasPrecedingLineBreak()) {
break;
}
else {
nextToken();
leftOperand = makeAsExpression(leftOperand, parseType());
}
}
else {
leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
}
}
return leftOperand;
@ -2955,6 +3042,7 @@ namespace ts {
case SyntaxKind.GreaterThanEqualsToken:
case SyntaxKind.InstanceOfKeyword:
case SyntaxKind.InKeyword:
case SyntaxKind.AsKeyword:
return 7;
case SyntaxKind.LessThanLessThanToken:
case SyntaxKind.GreaterThanGreaterThanToken:
@ -2982,6 +3070,13 @@ namespace ts {
return finishNode(node);
}
function makeAsExpression(left: Expression, right: TypeNode): AsExpression {
let node = <AsExpression>createNode(SyntaxKind.AsExpression, left.pos);
node.expression = left;
node.type = right;
return finishNode(node);
}
function parsePrefixUnaryExpression() {
let node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression);
node.operator = token;
@ -3027,7 +3122,13 @@ namespace ts {
case SyntaxKind.VoidKeyword:
return parseVoidExpression();
case SyntaxKind.LessThanToken:
return parseTypeAssertion();
if (sourceFile.languageVariant !== LanguageVariant.JSX) {
return parseTypeAssertion();
}
if(lookAhead(nextTokenIsIdentifier)) {
return parseJsxElementOrSelfClosingElement();
}
// Fall through
default:
return parsePostfixExpressionOrHigher();
}
@ -3154,6 +3255,154 @@ namespace ts {
node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true);
return finishNode(node);
}
function parseJsxElementOrSelfClosingElement(): JsxElement|JsxSelfClosingElement {
let opening = parseJsxOpeningOrSelfClosingElement();
if (opening.kind === SyntaxKind.JsxOpeningElement) {
let node = <JsxElement>createNode(SyntaxKind.JsxElement, opening.pos);
node.openingElement = opening;
node.children = parseJsxChildren(node.openingElement.tagName);
node.closingElement = parseJsxClosingElement();
return finishNode(node);
}
else {
Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement);
// Nothing else to do for self-closing elements
return <JsxSelfClosingElement>opening;
}
}
function parseJsxText(): JsxText {
let node = <JsxText>createNode(SyntaxKind.JsxText, scanner.getStartPos());
token = scanner.scanJsxToken();
return finishNode(node);
}
function parseJsxChild(): JsxChild {
switch (token) {
case SyntaxKind.JsxText:
return parseJsxText();
case SyntaxKind.OpenBraceToken:
return parseJsxExpression();
case SyntaxKind.LessThanToken:
return parseJsxElementOrSelfClosingElement();
}
Debug.fail('Unknown JSX child kind ' + token);
}
function parseJsxChildren(openingTagName: EntityName): NodeArray<JsxChild> {
let result = <NodeArray<JsxChild>>[];
result.pos = scanner.getStartPos();
let saveParsingContext = parsingContext;
parsingContext |= 1 << ParsingContext.JsxChildren;
while(true) {
token = scanner.reScanJsxToken();
if (token === SyntaxKind.LessThanSlashToken) {
break;
}
else if (token === SyntaxKind.EndOfFileToken) {
parseErrorAtCurrentToken(Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, openingTagName));
break;
}
result.push(parseJsxChild());
}
result.end = scanner.getTokenPos();
parsingContext = saveParsingContext;
return result;
}
function parseJsxOpeningOrSelfClosingElement(): JsxOpeningElement|JsxSelfClosingElement {
let fullStart = scanner.getStartPos();
parseExpected(SyntaxKind.LessThanToken);
let tagName = parseJsxElementName();
let attributes = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
let node: JsxOpeningLikeElement;
if (parseOptional(SyntaxKind.GreaterThanToken)) {
node = <JsxOpeningElement>createNode(SyntaxKind.JsxOpeningElement, fullStart);
}
else {
parseExpected(SyntaxKind.SlashToken);
parseExpected(SyntaxKind.GreaterThanToken);
node = <JsxSelfClosingElement>createNode(SyntaxKind.JsxSelfClosingElement, fullStart);
}
node.tagName = tagName;
node.attributes = attributes;
return finishNode(node);
}
function parseJsxElementName(): EntityName {
scanJsxIdentifier();
let elementName: EntityName = parseIdentifier();
while (parseOptional(SyntaxKind.DotToken)) {
scanJsxIdentifier();
let node = <QualifiedName>createNode(SyntaxKind.QualifiedName, elementName.pos);
node.left = elementName;
node.right = parseIdentifierName();
elementName = finishNode(node);
}
return elementName;
}
function parseJsxExpression(): JsxExpression {
let node = <JsxExpression>createNode(SyntaxKind.JsxExpression);
parseExpected(SyntaxKind.OpenBraceToken);
if (token !== SyntaxKind.CloseBraceToken) {
node.expression = parseExpression();
}
parseExpected(SyntaxKind.CloseBraceToken);
return finishNode(node);
}
function parseJsxAttribute(): JsxAttribute | JsxSpreadAttribute {
if (token === SyntaxKind.OpenBraceToken) {
return parseJsxSpreadAttribute();
}
scanJsxIdentifier();
let node = <JsxAttribute>createNode(SyntaxKind.JsxAttribute);
node.name = parseIdentifierName();
if (parseOptional(SyntaxKind.EqualsToken)) {
switch (token) {
case SyntaxKind.StringLiteral:
node.initializer = parseLiteralNode();
break;
default:
node.initializer = parseJsxExpression();
break;
}
}
return finishNode(node);
}
function parseJsxSpreadAttribute(): JsxSpreadAttribute {
let node = <JsxSpreadAttribute>createNode(SyntaxKind.JsxSpreadAttribute);
parseExpected(SyntaxKind.OpenBraceToken);
parseExpected(SyntaxKind.DotDotDotToken);
node.expression = parseExpression();
parseExpected(SyntaxKind.CloseBraceToken);
return finishNode(node);
}
function parseJsxClosingElement(): JsxClosingElement {
let node = <JsxClosingElement>createNode(SyntaxKind.JsxClosingElement);
parseExpected(SyntaxKind.LessThanSlashToken);
node.tagName = parseJsxElementName();
parseExpected(SyntaxKind.GreaterThanToken);
return finishNode(node);
}
function parseTypeAssertion(): TypeAssertion {
let node = <TypeAssertion>createNode(SyntaxKind.TypeAssertionExpression);
@ -4602,6 +4851,10 @@ namespace ts {
return nextToken() === SyntaxKind.OpenParenToken;
}
function nextTokenIsSlash() {
return nextToken() === SyntaxKind.SlashToken;
}
function nextTokenIsCommaOrFromKeyword() {
nextToken();
return token === SyntaxKind.CommaToken ||
@ -4802,7 +5055,7 @@ namespace ts {
}
function processReferenceComments(sourceFile: SourceFile): void {
let triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/false, sourceText);
let triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/false, LanguageVariant.Standard, sourceText);
let referencedFiles: FileReference[] = [];
let amdDependencies: { path: string; name: string }[] = [];
let amdModuleName: string;
@ -4889,6 +5142,8 @@ namespace ts {
ArrayBindingElements, // Binding elements in array binding list
ArgumentExpressions, // Expressions in argument list
ObjectLiteralMembers, // Members in object literal
JsxAttributes, // Attributes in jsx element
JsxChildren, // Things between opening and closing JSX tags
ArrayLiteralMembers, // Members in array literal
Parameters, // Parameters in parameter list
TypeParameters, // Type parameters in type parameter list

View file

@ -21,12 +21,16 @@ namespace ts {
reScanGreaterToken(): SyntaxKind;
reScanSlashToken(): SyntaxKind;
reScanTemplateToken(): SyntaxKind;
scanJsxIdentifier(): SyntaxKind;
reScanJsxToken(): SyntaxKind;
scanJsxToken(): SyntaxKind;
scan(): SyntaxKind;
// Sets the text for the scanner to scan. An optional subrange starting point and length
// can be provided to have the scanner only scan a portion of the text.
setText(text: string, start?: number, length?: number): void;
setOnError(onError: ErrorCallback): void;
setScriptTarget(scriptTarget: ScriptTarget): void;
setLanguageVariant(variant: LanguageVariant): void;
setTextPos(textPos: number): void;
// Invokes the provided callback then unconditionally restores the scanner to the state it
// was in immediately prior to invoking the callback. The result of invoking the callback
@ -130,6 +134,7 @@ namespace ts {
"++": SyntaxKind.PlusPlusToken,
"--": SyntaxKind.MinusMinusToken,
"<<": SyntaxKind.LessThanLessThanToken,
"</": SyntaxKind.LessThanSlashToken,
">>": SyntaxKind.GreaterThanGreaterThanToken,
">>>": SyntaxKind.GreaterThanGreaterThanGreaterThanToken,
"&": SyntaxKind.AmpersandToken,
@ -621,11 +626,12 @@ namespace ts {
ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ ||
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion);
}
/* @internal */
// Creates a scanner over a (possibly unspecified) range of a piece of text.
export function createScanner(languageVersion: ScriptTarget,
skipTrivia: boolean,
languageVariant = LanguageVariant.Standard,
text?: string,
onError?: ErrorCallback,
start?: number,
@ -665,9 +671,13 @@ namespace ts {
reScanGreaterToken,
reScanSlashToken,
reScanTemplateToken,
scanJsxIdentifier,
reScanJsxToken,
scanJsxToken,
scan,
setText,
setScriptTarget,
setLanguageVariant,
setOnError,
setTextPos,
tryScan,
@ -1302,6 +1312,9 @@ namespace ts {
if (text.charCodeAt(pos + 1) === CharacterCodes.equals) {
return pos += 2, token = SyntaxKind.LessThanEqualsToken;
}
if (text.charCodeAt(pos + 1) === CharacterCodes.slash && languageVariant === LanguageVariant.JSX) {
return pos += 2, token = SyntaxKind.LessThanSlashToken;
}
return pos++, token = SyntaxKind.LessThanToken;
case CharacterCodes.equals:
if (isConflictMarkerTrivia(text, pos)) {
@ -1481,6 +1494,62 @@ namespace ts {
return token = scanTemplateAndSetTokenValue();
}
function reScanJsxToken(): SyntaxKind {
pos = tokenPos = startPos;
return token = scanJsxToken();
}
function scanJsxToken(): SyntaxKind {
startPos = tokenPos = pos;
if (pos >= end) {
return token = SyntaxKind.EndOfFileToken;
}
let char = text.charCodeAt(pos);
if (char === CharacterCodes.lessThan) {
if (text.charCodeAt(pos + 1) === CharacterCodes.slash) {
pos += 2;
return token = SyntaxKind.LessThanSlashToken;
}
pos++;
return token = SyntaxKind.LessThanToken;
}
if (char === CharacterCodes.openBrace) {
pos++;
return token = SyntaxKind.OpenBraceToken;
}
while (pos < end) {
pos++;
char = text.charCodeAt(pos);
if ((char === CharacterCodes.openBrace) || (char === CharacterCodes.lessThan)) {
break;
}
}
return token = SyntaxKind.JsxText;
}
// Scans a JSX identifier; these differ from normal identifiers in that
// they allow dashes
function scanJsxIdentifier(): SyntaxKind {
if (token === SyntaxKind.Identifier) {
let firstCharPosition = pos;
while (pos < end) {
let ch = text.charCodeAt(pos);
if (ch === CharacterCodes.minus || ((firstCharPosition === pos) ? isIdentifierStart(ch) : isIdentifierPart(ch))) {
pos++;
}
else {
break;
}
}
tokenValue += text.substr(firstCharPosition, pos - firstCharPosition);
}
return token;
}
function speculationHelper<T>(callback: () => T, isLookahead: boolean): T {
let savePos = pos;
let saveStartPos = startPos;
@ -1525,6 +1594,10 @@ namespace ts {
languageVersion = scriptTarget;
}
function setLanguageVariant(variant: LanguageVariant) {
languageVariant = variant;
}
function setTextPos(textPos: number) {
Debug.assert(textPos >= 0);
pos = textPos;

View file

@ -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,64 @@ namespace ts {
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator;
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 <TagName attrs>...</TagName>
export interface JsxElement extends PrimaryExpression {
openingElement: JsxOpeningElement;
children: NodeArray<JsxChild>;
closingElement: JsxClosingElement;
}
/// The opening element of a <Tag>...</Tag> JsxElement
export interface JsxOpeningElement extends Expression {
_openingElementBrand?: any;
tagName: EntityName;
attributes: NodeArray<JsxAttribute | JsxSpreadAttribute>;
}
/// A JSX expression of the form <TagName attrs />
export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement {
_selfClosingElementBrand?: any;
}
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
export interface JsxAttribute extends Node {
name: Identifier;
/// JSX attribute initializers are optional; <X y /> is sugar for <X y={true} />
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;
}
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
export interface Statement extends Node {
_statementBrand: any;
}
@ -1144,6 +1221,7 @@ namespace ts {
amdDependencies: {path: string; name: string}[];
moduleName: string;
referencedFiles: FileReference[];
languageVariant: LanguageVariant;
/**
* lib.d.ts should have a reference comment like
@ -1323,6 +1401,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 +1684,8 @@ namespace ts {
assignmentChecks?: Map<boolean>; // 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
resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element
}
export const enum TypeFlags {
@ -1834,6 +1917,7 @@ namespace ts {
help?: boolean;
inlineSourceMap?: boolean;
inlineSources?: boolean;
jsx?: JsxEmit;
listFiles?: boolean;
locale?: string;
mapRoot?: string;
@ -1877,6 +1961,12 @@ namespace ts {
System = 4,
}
export const enum JsxEmit {
None = 0,
Preserve = 1,
React = 2
}
export const enum NewLineKind {
CarriageReturnLineFeed = 0,
LineFeed = 1,
@ -1897,6 +1987,11 @@ namespace ts {
Latest = ES6,
}
export const enum LanguageVariant {
Standard,
JSX
}
export interface ParsedCommandLine {
options: CompilerOptions;
fileNames: string[];

View file

@ -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__'
@ -274,7 +274,7 @@ namespace ts {
}
export function getSpanOfTokenAtPosition(sourceFile: SourceFile, pos: number): TextSpan {
let scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.text, /*onError:*/ undefined, pos);
let scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
scanner.scan();
let start = scanner.getTokenPos();
return createTextSpanFromBounds(start, scanner.getTextPos());
@ -848,6 +848,7 @@ namespace ts {
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
case SyntaxKind.TaggedTemplateExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.FunctionExpression:
@ -864,6 +865,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:
@ -910,7 +913,8 @@ namespace ts {
return (forInStatement.initializer === node && forInStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) ||
forInStatement.expression === node;
case SyntaxKind.TypeAssertionExpression:
return node === (<TypeAssertion>parent).expression;
case SyntaxKind.AsExpression:
return node === (<AssertionExpression>parent).expression;
case SyntaxKind.TemplateSpan:
return node === (<TemplateSpan>parent).expression;
case SyntaxKind.ComputedPropertyName:
@ -1530,6 +1534,11 @@ namespace ts {
}
}
export function isIntrinsicJsxName(name: string) {
let ch = name.substr(0, 1);
return ch.toLowerCase() === ch;
}
function get16BitUnicodeEscapeSequence(charCode: number): string {
let hexCharCode = charCode.toString(16).toUpperCase();
let paddedHexCode = ("0000" + hexCharCode).slice(-4);
@ -1885,6 +1894,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:
@ -1950,6 +1961,10 @@ namespace ts {
return fileExtensionIs(fileName, ".js");
}
export function isTsx(fileName: string) {
return fileExtensionIs(fileName, ".tsx");
}
/**
* Replace each instance of non-ascii characters by one, two, three, or four escape sequences
* representing the UTF-8 encoding of the character, and return the expanded char code list.

View file

@ -149,7 +149,7 @@ class CompilerBaselineRunner extends RunnerBase {
// check errors
it('Correct errors for ' + fileName, () => {
if (this.errors) {
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.ts$/, '.errors.txt'), (): string => {
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.tsx?$/, '.errors.txt'), (): string => {
if (result.errors.length === 0) return null;
return getErrorBaseline(toBeCompiled, otherFiles, result);
});
@ -159,7 +159,7 @@ class CompilerBaselineRunner extends RunnerBase {
// Source maps?
it('Correct sourcemap content for ' + fileName, () => {
if (options.sourceMap || options.inlineSourceMap) {
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.ts$/, '.sourcemap.txt'), () => {
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => {
var record = result.getSourceMapRecord();
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
@ -177,7 +177,7 @@ class CompilerBaselineRunner extends RunnerBase {
}
// check js output
Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.ts/, '.js'), () => {
Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.tsx?/, '.js'), () => {
var tsCode = '';
var tsSources = otherFiles.concat(toBeCompiled);
if (tsSources.length > 1) {
@ -235,7 +235,7 @@ class CompilerBaselineRunner extends RunnerBase {
throw new Error('Number of sourcemap files should be same as js files.');
}
Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.ts/, '.js.map'), () => {
Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.tsx?/, '.js.map'), () => {
if (options.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) {
// We need to return null here or the runBaseLine will actually create a empty file.
// Baselining isn't required here because there is no output.
@ -320,11 +320,11 @@ class CompilerBaselineRunner extends RunnerBase {
let pullExtension = isSymbolBaseLine ? '.symbols.pull' : '.types.pull';
if (fullBaseLine !== pullBaseLine) {
Harness.Baseline.runBaseline('Correct full information for ' + fileName, justName.replace(/\.ts/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline('Correct pull information for ' + fileName, justName.replace(/\.ts/, pullExtension), () => pullBaseLine);
Harness.Baseline.runBaseline('Correct full information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline('Correct pull information for ' + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine);
}
else {
Harness.Baseline.runBaseline('Correct information for ' + fileName, justName.replace(/\.ts/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline('Correct information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
}
}
@ -391,7 +391,7 @@ class CompilerBaselineRunner extends RunnerBase {
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
if (this.tests.length === 0) {
var testFiles = this.enumerateFiles(this.basePath, /\.ts$/, { recursive: true });
var testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true });
testFiles.forEach(fn => {
fn = fn.replace(/\\/g, "/");
this.checkTestCodeOutput(fn);

View file

@ -212,7 +212,7 @@ module Utils {
}
var result = "";
ts.forEach(Object.getOwnPropertyNames(flags),(v: any) => {
ts.forEach(Object.getOwnPropertyNames(flags), (v: any) => {
if (isFinite(v)) {
v = +v;
if (f === +v) {
@ -410,7 +410,7 @@ module Harness {
deleteFile(fileName: string): void;
listFiles(path: string, filter: RegExp, options?: { recursive?: boolean }): string[];
log(text: string): void;
getMemoryUsage? (): number;
getMemoryUsage?(): number;
}
module IOImpl {
@ -794,7 +794,7 @@ module Harness {
public reset() { this.fileCollection = {}; }
public toArray(): { fileName: string; file: WriterAggregator; }[]{
public toArray(): { fileName: string; file: WriterAggregator; }[] {
var result: { fileName: string; file: WriterAggregator; }[] = [];
for (var p in this.fileCollection) {
if (this.fileCollection.hasOwnProperty(p)) {
@ -1166,6 +1166,12 @@ module Harness {
options.inlineSources = setting.value === 'true';
break;
case 'jsx':
options.jsx = setting.value.toLowerCase() === 'react' ? ts.JsxEmit.React :
setting.value.toLowerCase() === 'preserve' ? ts.JsxEmit.Preserve :
ts.JsxEmit.None;
break;
default:
throw new Error('Unsupported compiler setting ' + setting.flag);
}
@ -1229,7 +1235,7 @@ module Harness {
}
var dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
@ -1428,6 +1434,10 @@ module Harness {
return stringEndsWith(fileName, '.ts');
}
export function isTSX(fileName: string) {
return stringEndsWith(fileName, '.tsx');
}
export function isDTS(fileName: string) {
return stringEndsWith(fileName, '.d.ts');
}
@ -1435,6 +1445,9 @@ module Harness {
export function isJS(fileName: string) {
return stringEndsWith(fileName, '.js');
}
export function isJSX(fileName: string) {
return stringEndsWith(fileName, '.jsx');
}
export function isJSMap(fileName: string) {
return stringEndsWith(fileName, '.js.map');
@ -1455,12 +1468,15 @@ module Harness {
if (isDTS(emittedFile.fileName)) {
// .d.ts file, add to declFiles emit
this.declFilesCode.push(emittedFile);
} else if (isJS(emittedFile.fileName)) {
}
else if (isJS(emittedFile.fileName) || isJSX(emittedFile.fileName)) {
// .js file, add to files
this.files.push(emittedFile);
} else if (isJSMap(emittedFile.fileName)) {
}
else if (isJSMap(emittedFile.fileName)) {
this.sourceMaps.push(emittedFile);
} else {
}
else {
throw new Error('Unrecognized file extension for file ' + emittedFile.fileName);
}
});
@ -1495,6 +1511,16 @@ module Harness {
// Regex for parsing options in the format "@Alpha: Value of any sort"
var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
// List of allowed metadata names
var fileMetadataNames = ["filename", "comments", "declaration", "module",
"nolib", "sourcemap", "target", "out", "outdir", "noemithelpers", "noemitonerror",
"noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom",
"errortruncation", "usecasesensitivefilenames", "preserveconstenums",
"includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal",
"isolatedmodules", "inlinesourcemap", "maproot", "sourceroot",
"inlinesources", "emitdecoratormetadata", "experimentaldecorators",
"skipdefaultlibcheck", "jsx"];
function extractCompilerSettings(content: string): CompilerSetting[] {
var opts: CompilerSetting[] = [];

View file

@ -27,7 +27,7 @@ class RunnerBase {
var fixedPath = path;
// full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point
var fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.ts/g;
var fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
var fullPathList = fixedPath.match(fullPath);
if (fullPathList) {
fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match)));

View file

@ -470,6 +470,7 @@ namespace ts.formatting {
switch (context.contextNode.kind) {
case SyntaxKind.BinaryExpression:
case SyntaxKind.ConditionalExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.TypePredicate:
return true;

View file

@ -112,7 +112,7 @@ namespace ts.formatting {
static AnyIncludingMultilineComments = TokenRange.FromTokens(TokenRange.Any.GetTokens().concat([SyntaxKind.MultiLineCommentTrivia]));
static Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword);
static BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator);
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.IsKeyword]);
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword]);
static UnaryPrefixOperators = TokenRange.FromTokens([SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]);
static UnaryPrefixExpressions = TokenRange.FromTokens([SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
static UnaryPreincrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);

View file

@ -197,8 +197,8 @@ namespace ts {
list._children = [];
let pos = nodes.pos;
for (let node of nodes) {
if (pos < node.pos) {
pos = this.addSyntheticNodes(list._children, pos, node.pos);
@ -750,6 +750,7 @@ namespace ts {
public symbolCount: number;
public version: string;
public languageVersion: ScriptTarget;
public languageVariant: LanguageVariant;
public identifiers: Map<string>;
public nameTable: Map<string>;
@ -874,7 +875,7 @@ namespace ts {
case SyntaxKind.SetAccessor:
case SyntaxKind.TypeLiteral:
addDeclaration(<Declaration>node);
// fall through
// fall through
case SyntaxKind.Constructor:
case SyntaxKind.VariableStatement:
case SyntaxKind.VariableDeclarationList:
@ -1094,7 +1095,7 @@ namespace ts {
export const definition = "definition";
export const reference = "reference";
export const writtenReference = "writtenReference";
}
}
export interface HighlightSpan {
textSpan: TextSpan;
@ -1609,6 +1610,7 @@ namespace ts {
return {
target: ScriptTarget.ES5,
module: ModuleKind.None,
jsx: JsxEmit.Preserve
};
}
@ -2894,21 +2896,33 @@ namespace ts {
return undefined;
}
let options = program.getCompilerOptions();
let jsx = options.jsx !== JsxEmit.None;
let target = options.target;
// Find the node where completion is requested on, in the case of a completion after
// a dot, it is the member access expression other wise, it is a request for all
// visible symbols in the scope, and the node is the current location.
let node = currentToken;
let isRightOfDot = false;
if (contextToken && contextToken.kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.PropertyAccessExpression) {
node = (<PropertyAccessExpression>contextToken.parent).expression;
isRightOfDot = true;
}
else if (contextToken && contextToken.kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.QualifiedName) {
node = (<QualifiedName>contextToken.parent).left;
isRightOfDot = true;
}
let isRightOfOpenTag = false;
let location = getTouchingPropertyName(sourceFile, position);
if(contextToken) {
let kind = contextToken.kind;
if (kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.PropertyAccessExpression) {
node = (<PropertyAccessExpression>contextToken.parent).expression;
isRightOfDot = true;
}
else if (kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.QualifiedName) {
node = (<QualifiedName>contextToken.parent).left;
isRightOfDot = true;
}
else if (kind === SyntaxKind.LessThanToken && sourceFile.languageVariant === LanguageVariant.JSX) {
isRightOfOpenTag = true;
location = contextToken;
}
}
let semanticStart = new Date().getTime();
let isMemberCompletion: boolean;
@ -2918,6 +2932,17 @@ namespace ts {
if (isRightOfDot) {
getTypeScriptMemberSymbols();
}
else if (isRightOfOpenTag) {
let tagSymbols = typeChecker.getJsxIntrinsicTagNames();
if (tryGetGlobalSymbols()) {
symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & SymbolFlags.Value)));
}
else {
symbols = tagSymbols;
}
isMemberCompletion = true;
isNewIdentifierLocation = false;
}
else {
// For JavaScript or TypeScript, if we're not after a dot, then just try to get the
// global symbols in scope. These results should be valid for either language as
@ -2929,7 +2954,7 @@ namespace ts {
log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart));
return { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot };
return { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag) };
function getTypeScriptMemberSymbols(): void {
// Right of dot member completion list
@ -3010,6 +3035,7 @@ namespace ts {
// Add filtered items to the completion list
symbols = filterObjectMembersList(typeMembers, existingMembers);
}
return true;
}
else if (getAncestor(contextToken, SyntaxKind.ImportClause)) {
// cursor is in import clause
@ -3031,51 +3057,77 @@ namespace ts {
//let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration);
symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray;
}
return true;
}
else {
// Get all entities in the current scope.
isMemberCompletion = false;
isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken);
else if (getAncestor(contextToken, SyntaxKind.JsxElement) || getAncestor(contextToken, SyntaxKind.JsxSelfClosingElement)) {
// Go up until we hit either the element or expression
let jsxNode = contextToken;
if (previousToken !== contextToken) {
Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'.");
while (jsxNode) {
if (jsxNode.kind === SyntaxKind.JsxExpression) {
// Defer to global completion if we're inside an {expression}
break;
} else if (jsxNode.kind === SyntaxKind.JsxSelfClosingElement || jsxNode.kind === SyntaxKind.JsxElement) {
let attrsType: Type;
if (jsxNode.kind === SyntaxKind.JsxSelfClosingElement) {
// Cursor is inside a JSX self-closing element
attrsType = typeChecker.getJsxElementAttributesType(<JsxSelfClosingElement>jsxNode);
}
else {
Debug.assert(jsxNode.kind === SyntaxKind.JsxElement);
// Cursor is inside a JSX element
attrsType = typeChecker.getJsxElementAttributesType((<JsxElement>jsxNode).openingElement);
}
symbols = typeChecker.getPropertiesOfType(attrsType);
isMemberCompletion = true;
return true;
}
jsxNode = jsxNode.parent;
}
// We need to find the node that will give us an appropriate scope to begin
// aggregating completion candidates. This is achieved in 'getScopeNode'
// by finding the first node that encompasses a position, accounting for whether a node
// is "complete" to decide whether a position belongs to the node.
//
// However, at the end of an identifier, we are interested in the scope of the identifier
// itself, but fall outside of the identifier. For instance:
//
// xyz => x$
//
// the cursor is outside of both the 'x' and the arrow function 'xyz => x',
// so 'xyz' is not returned in our results.
//
// We define 'adjustedPosition' so that we may appropriately account for
// being at the end of an identifier. The intention is that if requesting completion
// at the end of an identifier, it should be effectively equivalent to requesting completion
// anywhere inside/at the beginning of the identifier. So in the previous case, the
// 'adjustedPosition' will work as if requesting completion in the following:
//
// xyz => $x
//
// If previousToken !== contextToken, then
// - 'contextToken' was adjusted to the token prior to 'previousToken'
// because we were at the end of an identifier.
// - 'previousToken' is defined.
let adjustedPosition = previousToken !== contextToken ?
previousToken.getStart() :
position;
let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
/// TODO filter meaning based on the current context
let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
}
// Get all entities in the current scope.
isMemberCompletion = false;
isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken);
if (previousToken !== contextToken) {
Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'.");
}
// We need to find the node that will give us an appropriate scope to begin
// aggregating completion candidates. This is achieved in 'getScopeNode'
// by finding the first node that encompasses a position, accounting for whether a node
// is "complete" to decide whether a position belongs to the node.
//
// However, at the end of an identifier, we are interested in the scope of the identifier
// itself, but fall outside of the identifier. For instance:
//
// xyz => x$
//
// the cursor is outside of both the 'x' and the arrow function 'xyz => x',
// so 'xyz' is not returned in our results.
//
// We define 'adjustedPosition' so that we may appropriately account for
// being at the end of an identifier. The intention is that if requesting completion
// at the end of an identifier, it should be effectively equivalent to requesting completion
// anywhere inside/at the beginning of the identifier. So in the previous case, the
// 'adjustedPosition' will work as if requesting completion in the following:
//
// xyz => $x
//
// If previousToken !== contextToken, then
// - 'contextToken' was adjusted to the token prior to 'previousToken'
// because we were at the end of an identifier.
// - 'previousToken' is defined.
let adjustedPosition = previousToken !== contextToken ?
previousToken.getStart() :
position;
let scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile;
/// TODO filter meaning based on the current context
let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
return true;
}
@ -4221,7 +4273,7 @@ namespace ts {
function getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
let results = getOccurrencesAtPositionCore(fileName, position);
if (results) {
let sourceFile = getCanonicalFileName(normalizeSlashes(fileName));
@ -5793,7 +5845,7 @@ namespace ts {
}
function isTypeReference(node: Node): boolean {
if (isRightSideOfQualifiedNameOrPropertyAccess(node) ) {
if (isRightSideOfQualifiedNameOrPropertyAccess(node)) {
node = node.parent;
}
@ -5962,13 +6014,13 @@ namespace ts {
return BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position);
}
function getNavigationBarItems(fileName: string): NavigationBarItem[]{
function getNavigationBarItems(fileName: string): NavigationBarItem[] {
let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
return NavigationBar.getNavigationBarItems(sourceFile);
}
function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]{
function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
return convertClassifications(getEncodedSemanticClassifications(fileName, span));
}
@ -6097,7 +6149,7 @@ namespace ts {
return result;
}
function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]{
function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
return convertClassifications(getEncodedSyntacticClassifications(fileName, span));
}
@ -6108,8 +6160,8 @@ namespace ts {
let spanLength = span.length;
// Make a scanner we can get trivia from.
let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text);
let mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text);
let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text);
let mergeConflictScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.languageVariant, sourceFile.text);
let result: number[] = [];
processElement(sourceFile);
@ -6464,14 +6516,14 @@ namespace ts {
function getMatchingTokenKind(token: Node): ts.SyntaxKind {
switch (token.kind) {
case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken
case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken;
case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken;
case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken;
case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken
case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken;
case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken;
case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken;
case ts.SyntaxKind.OpenBraceToken: return ts.SyntaxKind.CloseBraceToken
case ts.SyntaxKind.OpenParenToken: return ts.SyntaxKind.CloseParenToken;
case ts.SyntaxKind.OpenBracketToken: return ts.SyntaxKind.CloseBracketToken;
case ts.SyntaxKind.LessThanToken: return ts.SyntaxKind.GreaterThanToken;
case ts.SyntaxKind.CloseBraceToken: return ts.SyntaxKind.OpenBraceToken
case ts.SyntaxKind.CloseParenToken: return ts.SyntaxKind.OpenParenToken;
case ts.SyntaxKind.CloseBracketToken: return ts.SyntaxKind.OpenBracketToken;
case ts.SyntaxKind.GreaterThanToken: return ts.SyntaxKind.LessThanToken;
}
return undefined;
@ -6686,6 +6738,7 @@ namespace ts {
if (defaultLibFileName) {
for (let current of declarations) {
let sourceFile = current.getSourceFile();
var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName));
if (sourceFile && getCanonicalFileName(ts.normalizePath(sourceFile.fileName)) === getCanonicalFileName(ts.normalizePath(defaultLibFileName))) {
return getRenameInfoError(getLocaleSpecificMessage(Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library.key));
}
@ -6915,7 +6968,7 @@ namespace ts {
case ClassificationType.stringLiteral: return TokenClass.StringLiteral;
case ClassificationType.whiteSpace: return TokenClass.Whitespace;
case ClassificationType.punctuation: return TokenClass.Punctuation;
case ClassificationType.identifier:
case ClassificationType.identifier:
case ClassificationType.className:
case ClassificationType.enumName:
case ClassificationType.interfaceName:
@ -6970,7 +7023,7 @@ namespace ts {
case EndOfLineState.InTemplateMiddleOrTail:
text = "}\n" + text;
offset = 2;
// fallthrough
// fallthrough
case EndOfLineState.InTemplateSubstitutionPosition:
templateStack.push(SyntaxKind.TemplateHead);
break;
@ -7009,9 +7062,9 @@ namespace ts {
if (!isTrivia(token)) {
if ((token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) && !noRegexTable[lastNonTriviaToken]) {
if (scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
token = SyntaxKind.RegularExpressionLiteral;
}
if (scanner.reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
token = SyntaxKind.RegularExpressionLiteral;
}
}
else if (lastNonTriviaToken === SyntaxKind.DotToken && isKeyword(token)) {
token = SyntaxKind.Identifier;
@ -7024,7 +7077,7 @@ namespace ts {
token = SyntaxKind.Identifier;
}
else if (lastNonTriviaToken === SyntaxKind.Identifier &&
token === SyntaxKind.LessThanToken) {
token === SyntaxKind.LessThanToken) {
// Could be the start of something generic. Keep track of that by bumping
// up the current count of generic contexts we may be in.
angleBracketStack++;
@ -7035,10 +7088,10 @@ namespace ts {
angleBracketStack--;
}
else if (token === SyntaxKind.AnyKeyword ||
token === SyntaxKind.StringKeyword ||
token === SyntaxKind.NumberKeyword ||
token === SyntaxKind.BooleanKeyword ||
token === SyntaxKind.SymbolKeyword) {
token === SyntaxKind.StringKeyword ||
token === SyntaxKind.NumberKeyword ||
token === SyntaxKind.BooleanKeyword ||
token === SyntaxKind.SymbolKeyword) {
if (angleBracketStack > 0 && !syntacticClassifierAbsent) {
// If it looks like we're could be in something generic, don't classify this
// as a keyword. We may just get overwritten by the syntactic classifier,
@ -7274,7 +7327,7 @@ namespace ts {
declare let __dirname: string;
/**
* Get the path of the default library file (lib.d.ts) as distributed with the typescript
* Get the path of the default library files (lib.d.ts) as distributed with the typescript
* node package.
* The functionality is not supported if the ts module is consumed outside of a node module.
*/

View file

@ -75,28 +75,28 @@ function delint(sourceFile) {
delintNode(sourceFile);
function delintNode(node) {
switch (node.kind) {
case 189 /* ForStatement */:
case 190 /* ForInStatement */:
case 188 /* WhileStatement */:
case 187 /* DoStatement */:
if (node.statement.kind !== 182 /* Block */) {
case 191 /* ForStatement */:
case 192 /* ForInStatement */:
case 190 /* WhileStatement */:
case 189 /* DoStatement */:
if (node.statement.kind !== 184 /* Block */) {
report(node, "A looping statement's contents should be wrapped in a block body.");
}
break;
case 186 /* IfStatement */:
case 188 /* IfStatement */:
var ifStatement = node;
if (ifStatement.thenStatement.kind !== 182 /* Block */) {
if (ifStatement.thenStatement.kind !== 184 /* Block */) {
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
}
if (ifStatement.elseStatement &&
ifStatement.elseStatement.kind !== 182 /* Block */ &&
ifStatement.elseStatement.kind !== 186 /* IfStatement */) {
ifStatement.elseStatement.kind !== 184 /* Block */ &&
ifStatement.elseStatement.kind !== 188 /* IfStatement */) {
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
}
break;
case 172 /* BinaryExpression */:
case 173 /* BinaryExpression */:
var op = node.operatorToken.kind;
if (op === 28 /* EqualsEqualsToken */ || op == 29 /* ExclamationEqualsToken */) {
if (op === 29 /* EqualsEqualsToken */ || op == 30 /* ExclamationEqualsToken */) {
report(node, "Use '===' and '!=='.");
}
break;

View file

@ -0,0 +1,19 @@
//// [asOperator1.ts]
var as = 43;
var x = undefined as number;
var y = (null as string).length;
var z = Date as any as string;
// Should parse as a union type, not a bitwise 'or' of (32 as number) and 'string'
var j = 32 as number|string;
j = '';
//// [asOperator1.js]
var as = 43;
var x = undefined;
var y = null.length;
var z = Date;
// Should parse as a union type, not a bitwise 'or' of (32 as number) and 'string'
var j = 32;
j = '';

View file

@ -0,0 +1,24 @@
=== tests/cases/conformance/expressions/asOperator/asOperator1.ts ===
var as = 43;
>as : Symbol(as, Decl(asOperator1.ts, 0, 3))
var x = undefined as number;
>x : Symbol(x, Decl(asOperator1.ts, 1, 3))
>undefined : Symbol(undefined)
var y = (null as string).length;
>y : Symbol(y, Decl(asOperator1.ts, 2, 3))
>(null as string).length : Symbol(String.length, Decl(lib.d.ts, 414, 19))
>length : Symbol(String.length, Decl(lib.d.ts, 414, 19))
var z = Date as any as string;
>z : Symbol(z, Decl(asOperator1.ts, 3, 3))
>Date : Symbol(Date, Decl(lib.d.ts, 633, 23), Decl(lib.d.ts, 815, 11))
// Should parse as a union type, not a bitwise 'or' of (32 as number) and 'string'
var j = 32 as number|string;
>j : Symbol(j, Decl(asOperator1.ts, 6, 3))
j = '';
>j : Symbol(j, Decl(asOperator1.ts, 6, 3))

View file

@ -0,0 +1,35 @@
=== tests/cases/conformance/expressions/asOperator/asOperator1.ts ===
var as = 43;
>as : number
>43 : number
var x = undefined as number;
>x : number
>undefined as number : number
>undefined : undefined
var y = (null as string).length;
>y : number
>(null as string).length : number
>(null as string) : string
>null as string : string
>null : null
>length : number
var z = Date as any as string;
>z : string
>Date as any as string : string
>Date as any : any
>Date : DateConstructor
// Should parse as a union type, not a bitwise 'or' of (32 as number) and 'string'
var j = 32 as number|string;
>j : string | number
>32 as number|string : string | number
>32 : number
j = '';
>j = '' : string
>j : string | number
>'' : string

View file

@ -0,0 +1,8 @@
tests/cases/conformance/expressions/asOperator/asOperator2.ts(1,9): error TS2352: Neither type 'number' nor type 'string' is assignable to the other.
==== tests/cases/conformance/expressions/asOperator/asOperator2.ts (1 errors) ====
var x = 23 as string;
~~~~~~~~~~~~
!!! error TS2352: Neither type 'number' nor type 'string' is assignable to the other.

View file

@ -0,0 +1,6 @@
//// [asOperator2.ts]
var x = 23 as string;
//// [asOperator2.js]
var x = 23;

View file

@ -0,0 +1,22 @@
//// [asOperator3.ts]
declare function tag(...x: any[]): any;
var a = `${123 + 456 as number}`;
var b = `leading ${123 + 456 as number}`;
var c = `${123 + 456 as number} trailing`;
var d = `Hello ${123} World` as string;
var e = `Hello` as string;
var f = 1 + `${1} end of string` as string;
var g = tag `Hello ${123} World` as string;
var h = tag `Hello` as string;
//// [asOperator3.js]
var a = "" + 123 + 456;
var b = "leading " + 123 + 456;
var c = 123 + 456 + " trailing";
var d = ("Hello " + 123 + " World");
var e = "Hello";
var f = 1 + (1 + " end of string");
var g = (_a = ["Hello ", " World"], _a.raw = ["Hello ", " World"], tag(_a, 123));
var h = (_b = ["Hello"], _b.raw = ["Hello"], tag(_b));
var _a, _b;

View file

@ -0,0 +1,31 @@
=== tests/cases/conformance/expressions/asOperator/asOperator3.ts ===
declare function tag(...x: any[]): any;
>tag : Symbol(tag, Decl(asOperator3.ts, 0, 0))
>x : Symbol(x, Decl(asOperator3.ts, 0, 21))
var a = `${123 + 456 as number}`;
>a : Symbol(a, Decl(asOperator3.ts, 2, 3))
var b = `leading ${123 + 456 as number}`;
>b : Symbol(b, Decl(asOperator3.ts, 3, 3))
var c = `${123 + 456 as number} trailing`;
>c : Symbol(c, Decl(asOperator3.ts, 4, 3))
var d = `Hello ${123} World` as string;
>d : Symbol(d, Decl(asOperator3.ts, 5, 3))
var e = `Hello` as string;
>e : Symbol(e, Decl(asOperator3.ts, 6, 3))
var f = 1 + `${1} end of string` as string;
>f : Symbol(f, Decl(asOperator3.ts, 7, 3))
var g = tag `Hello ${123} World` as string;
>g : Symbol(g, Decl(asOperator3.ts, 8, 3))
>tag : Symbol(tag, Decl(asOperator3.ts, 0, 0))
var h = tag `Hello` as string;
>h : Symbol(h, Decl(asOperator3.ts, 9, 3))
>tag : Symbol(tag, Decl(asOperator3.ts, 0, 0))

View file

@ -0,0 +1,63 @@
=== tests/cases/conformance/expressions/asOperator/asOperator3.ts ===
declare function tag(...x: any[]): any;
>tag : (...x: any[]) => any
>x : any[]
var a = `${123 + 456 as number}`;
>a : string
>`${123 + 456 as number}` : string
>123 + 456 as number : number
>123 + 456 : number
>123 : number
>456 : number
var b = `leading ${123 + 456 as number}`;
>b : string
>`leading ${123 + 456 as number}` : string
>123 + 456 as number : number
>123 + 456 : number
>123 : number
>456 : number
var c = `${123 + 456 as number} trailing`;
>c : string
>`${123 + 456 as number} trailing` : string
>123 + 456 as number : number
>123 + 456 : number
>123 : number
>456 : number
var d = `Hello ${123} World` as string;
>d : string
>`Hello ${123} World` as string : string
>`Hello ${123} World` : string
>123 : number
var e = `Hello` as string;
>e : string
>`Hello` as string : string
>`Hello` : string
var f = 1 + `${1} end of string` as string;
>f : string
>1 + `${1} end of string` as string : string
>1 + `${1} end of string` : string
>1 : number
>`${1} end of string` : string
>1 : number
var g = tag `Hello ${123} World` as string;
>g : string
>tag `Hello ${123} World` as string : string
>tag `Hello ${123} World` : any
>tag : (...x: any[]) => any
>`Hello ${123} World` : string
>123 : number
var h = tag `Hello` as string;
>h : string
>tag `Hello` as string : string
>tag `Hello` : any
>tag : (...x: any[]) => any
>`Hello` : string

View file

@ -0,0 +1,26 @@
//// [asOperatorASI.ts]
class Foo { }
declare function as(...args: any[]);
// Example 1
var x = 10
as `Hello world`; // should not error
// Example 2
var y = 20
as(Foo); // should emit
//// [asOperatorASI.js]
var Foo = (function () {
function Foo() {
}
return Foo;
})();
// Example 1
var x = 10;
(_a = ["Hello world"], _a.raw = ["Hello world"], as(_a)); // should not error
// Example 2
var y = 20;
as(Foo); // should emit
var _a;

View file

@ -0,0 +1,23 @@
=== tests/cases/conformance/expressions/asOperator/asOperatorASI.ts ===
class Foo { }
>Foo : Symbol(Foo, Decl(asOperatorASI.ts, 0, 0))
declare function as(...args: any[]);
>as : Symbol(as, Decl(asOperatorASI.ts, 0, 13))
>args : Symbol(args, Decl(asOperatorASI.ts, 1, 20))
// Example 1
var x = 10
>x : Symbol(x, Decl(asOperatorASI.ts, 4, 3))
as `Hello world`; // should not error
>as : Symbol(as, Decl(asOperatorASI.ts, 0, 13))
// Example 2
var y = 20
>y : Symbol(y, Decl(asOperatorASI.ts, 8, 3))
as(Foo); // should emit
>as : Symbol(as, Decl(asOperatorASI.ts, 0, 13))
>Foo : Symbol(Foo, Decl(asOperatorASI.ts, 0, 0))

View file

@ -0,0 +1,28 @@
=== tests/cases/conformance/expressions/asOperator/asOperatorASI.ts ===
class Foo { }
>Foo : Foo
declare function as(...args: any[]);
>as : (...args: any[]) => any
>args : any[]
// Example 1
var x = 10
>x : number
>10 : number
as `Hello world`; // should not error
>as `Hello world` : any
>as : (...args: any[]) => any
>`Hello world` : string
// Example 2
var y = 20
>y : number
>20 : number
as(Foo); // should emit
>as(Foo) : any
>as : (...args: any[]) => any
>Foo : typeof Foo

View file

@ -0,0 +1,15 @@
tests/cases/conformance/expressions/asOperator/asOperatorAmbiguity.ts(7,14): error TS2339: Property 'm' does not exist on type 'A<B>'.
==== tests/cases/conformance/expressions/asOperator/asOperatorAmbiguity.ts (1 errors) ====
interface A<T> { x: T; }
interface B { m: string; }
// Make sure this is a type assertion to an array type, and not nested comparison operators.
var x: any;
var y = x as A<B>[];
var z = y[0].m; // z should be string
~
!!! error TS2339: Property 'm' does not exist on type 'A<B>'.

View file

@ -0,0 +1,16 @@
//// [asOperatorAmbiguity.ts]
interface A<T> { x: T; }
interface B { m: string; }
// Make sure this is a type assertion to an array type, and not nested comparison operators.
var x: any;
var y = x as A<B>[];
var z = y[0].m; // z should be string
//// [asOperatorAmbiguity.js]
// Make sure this is a type assertion to an array type, and not nested comparison operators.
var x;
var y = x;
var z = y[0].m; // z should be string

View file

@ -0,0 +1,10 @@
tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts(2,9): error TS2352: Neither type '(v: number) => number' nor type '(x: number) => string' is assignable to the other.
Type 'number' is not assignable to type 'string'.
==== tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts (1 errors) ====
// should error
var x = (v => v) as (x: number) => string;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2352: Neither type '(v: number) => number' nor type '(x: number) => string' is assignable to the other.
!!! error TS2352: Type 'number' is not assignable to type 'string'.

View file

@ -0,0 +1,7 @@
//// [asOperatorContextualType.ts]
// should error
var x = (v => v) as (x: number) => string;
//// [asOperatorContextualType.js]
// should error
var x = (function (v) { return v; });

View file

@ -0,0 +1,11 @@
tests/cases/conformance/expressions/asOperator/asOperatorNames.ts(2,9): error TS2352: Neither type 'number' nor type 'string' is assignable to the other.
==== tests/cases/conformance/expressions/asOperator/asOperatorNames.ts (1 errors) ====
var a = 20;
var b = a as string;
~~~~~~~~~~~
!!! error TS2352: Neither type 'number' nor type 'string' is assignable to the other.
var as = "hello";
var as1 = as as string;

View file

@ -0,0 +1,12 @@
//// [asOperatorNames.ts]
var a = 20;
var b = a as string;
var as = "hello";
var as1 = as as string;
//// [asOperatorNames.js]
var a = 20;
var b = a;
var as = "hello";
var as1 = as;

View file

@ -0,0 +1,49 @@
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(7,13): error TS2304: Cannot find name 'test'.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(7,17): error TS1005: '}' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(11,32): error TS1005: '}' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(13,36): error TS1005: '}' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(15,45): error TS1005: '}' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(22,1): error TS1005: ':' expected.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(22,1): error TS17002: Expected corresponding JSX closing tag for 'any'.
tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx(22,1): error TS17002: Expected corresponding JSX closing tag for 'foo'.
==== tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx (8 errors) ====
declare var createElement: any;
class foo {}
var x: any;
x = <any> { test: <any></any> };
~~~~
!!! error TS2304: Cannot find name 'test'.
~
!!! error TS1005: '}' expected.
x = <any><any></any>;
x = <foo>hello {<foo>{}} </foo>;
~
!!! error TS1005: '}' expected.
x = <foo test={<foo>{}}>hello</foo>;
~
!!! error TS1005: '}' expected.
x = <foo test={<foo>{}}>hello{<foo>{}}</foo>;
~
!!! error TS1005: '}' expected.
x = <foo>x</foo>, x = <foo/>;
<foo>{<foo><foo>{/foo/.test(x) ? <foo><foo></foo> : <foo><foo></foo>}</foo>}</foo>
!!! error TS1005: ':' expected.
!!! error TS17002: Expected corresponding JSX closing tag for 'any'.
!!! error TS17002: Expected corresponding JSX closing tag for 'foo'.

View file

@ -0,0 +1,49 @@
//// [jsxAndTypeAssertion.tsx]
declare var createElement: any;
class foo {}
var x: any;
x = <any> { test: <any></any> };
x = <any><any></any>;
x = <foo>hello {<foo>{}} </foo>;
x = <foo test={<foo>{}}>hello</foo>;
x = <foo test={<foo>{}}>hello{<foo>{}}</foo>;
x = <foo>x</foo>, x = <foo/>;
<foo>{<foo><foo>{/foo/.test(x) ? <foo><foo></foo> : <foo><foo></foo>}</foo>}</foo>
//// [jsxAndTypeAssertion.jsx]
var foo = (function () {
function foo() {
}
return foo;
})();
var x;
x = <any> {test}: <any></any> };
x = <any><any></any>;
x = <foo>hello {<foo>} </foo>};
x = <foo test={<foo>}>hello</foo>}/>;
x = <foo test={<foo>}>hello{<foo>}</foo>};
x = <foo>x</foo>, x = <foo />;
<foo>{<foo><foo>{/foo/.test(x) ? <foo><foo></foo> : <foo><foo></foo>}</foo>}</foo>
:
}
</></>}</></>}/></></></>;

View file

@ -0,0 +1,81 @@
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,17): error TS1005: '{' expected.
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,23): error TS1005: '}' expected.
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,29): error TS1005: '{' expected.
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,57): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(39,58): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(41,1): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(41,6): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx(41,12): error TS1109: Expression expected.
==== tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx (8 errors) ====
declare var React: any;
declare var 日本語;
declare var AbC_def;
declare var LeftRight;
declare var x;
declare var a;
declare var props;
<a />;
//<n:a n:v />; Namespace unsuported
//<a n:foo="bar"> {value} <b><c /></b></a>; Namespace unsuported
<a b={" "} c=" " d="&amp;" e="id=1&group=2" f="&#123456789" g="&#123*;" h="&#x;" />;
<a b="&notanentity;" />;
<a
/>;
<日本語></日本語>;
<AbC_def
test="&#x0026;&#38;">
bar
baz
</AbC_def>;
<a b={x ? <c /> : <d />} />;
<a>{}</a>;
<a>{/* this is a comment */}</a>;
<div>@test content</div>;
<div><br />7x invalid-js-identifier</div>;
<LeftRight left=<a /> right=<b>monkeys /> gorillas</b> />;
~
!!! error TS1005: '{' expected.
~~~~~
!!! error TS1005: '}' expected.
~
!!! error TS1005: '{' expected.
~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
<a.b></a.b>;
~
!!! error TS1003: Identifier expected.
~~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
<a.b.c></a.b.c>;
(<div />) < x;
<div {...props} />;
<div {...props} post="attribute" />;
<div pre="leading" pre2="attribute" {...props}></div>;
<a> </a>;

View file

@ -0,0 +1,82 @@
//// [jsxEsprimaFbTestSuite.tsx]
declare var React: any;
declare var ;
declare var AbC_def;
declare var LeftRight;
declare var x;
declare var a;
declare var props;
<a />;
//<n:a n:v />; Namespace unsuported
//<a n:foo="bar"> {value} <b><c /></b></a>; Namespace unsuported
<a b={" "} c=" " d="&amp;" e="id=1&group=2" f="&#123456789" g="&#123*;" h="&#x;" />;
<a b="&notanentity;" />;
<a
/>;
<日本語></日本語>;
<AbC_def
test="&#x0026;&#38;">
bar
baz
</AbC_def>;
<a b={x ? <c /> : <d />} />;
<a>{}</a>;
<a>{/* this is a comment */}</a>;
<div>@test content</div>;
<div><br />7x invalid-js-identifier</div>;
<LeftRight left=<a /> right=<b>monkeys /> gorillas</b> />;
<a.b></a.b>;
<a.b.c></a.b.c>;
(<div />) < x;
<div {...props} />;
<div {...props} post="attribute" />;
<div pre="leading" pre2="attribute" {...props}></div>;
<a> </a>;
//// [jsxEsprimaFbTestSuite.jsx]
<a />;
//<n:a n:v />; Namespace unsuported
//<a n:foo="bar"> {value} <b><c /></b></a>; Namespace unsuported
<a b={" "} c=" " d="&amp;" e="id=1&group=2" f="&#123456789" g="&#123*;" h="&#x;"/>;
<a b="&notanentity;"/>;
<a />;
<日本語></日本語>;
<AbC_def test="&#x0026;&#38;">
bar
baz
</AbC_def>;
<a b={x ? <c /> : <d />}/>;
<a></a>;
<a></a>;
<div>@test content</div>;
<div><br />7x invalid-js-identifier</div>;
<LeftRight left={<a />} right={<b>monkeys /> gorillas</b> / > }/>
< a.b > ;
a.b > ;
<a.b.c></a.b.c>;
(<div />) < x;
<div {...props}/>;
<div {...props} post="attribute"/>;
<div pre="leading" pre2="attribute" {...props}></div>;
<a> </a>;

View file

@ -0,0 +1,92 @@
=== tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx ===
declare var React: any;
>React : Symbol(React, Decl(jsxEsprimaFbTestSuite.tsx, 0, 11))
declare var 日本語;
>日本語 : Symbol(日本語, Decl(jsxEsprimaFbTestSuite.tsx, 1, 11))
declare var AbC_def;
>AbC_def : Symbol(AbC_def, Decl(jsxEsprimaFbTestSuite.tsx, 2, 11))
declare var LeftRight;
>LeftRight : Symbol(LeftRight, Decl(jsxEsprimaFbTestSuite.tsx, 3, 11))
declare var x;
>x : Symbol(x, Decl(jsxEsprimaFbTestSuite.tsx, 4, 11))
declare var a;
>a : Symbol(a, Decl(jsxEsprimaFbTestSuite.tsx, 5, 11))
declare var props;
>props : Symbol(props, Decl(jsxEsprimaFbTestSuite.tsx, 6, 11))
<a />;
//<n:a n:v />; Namespace unsuported
//<a n:foo="bar"> {value} <b><c /></b></a>; Namespace unsuported
<a b={" "} c=" " d="&amp;" e="id=1&group=2" f="&#123456789" g="&#123*;" h="&#x;" />;
>b : Symbol(unknown)
>c : Symbol(unknown)
>d : Symbol(unknown)
>e : Symbol(unknown)
>f : Symbol(unknown)
>g : Symbol(unknown)
>h : Symbol(unknown)
<a b="&notanentity;" />;
>b : Symbol(unknown)
<a
/>;
<日本語></日本語>;
<AbC_def
>AbC_def : Symbol(AbC_def, Decl(jsxEsprimaFbTestSuite.tsx, 2, 11))
test="&#x0026;&#38;">
>test : Symbol(unknown)
bar
baz
</AbC_def>;
<a b={x ? <c /> : <d />} />;
>b : Symbol(unknown)
>x : Symbol(x, Decl(jsxEsprimaFbTestSuite.tsx, 4, 11))
<a>{}</a>;
<a>{/* this is a comment */}</a>;
<div>@test content</div>;
<div><br />7x invalid-js-identifier</div>;
<LeftRight left=<a /> right=<b>monkeys /> gorillas</b> />;
>LeftRight : Symbol(LeftRight, Decl(jsxEsprimaFbTestSuite.tsx, 3, 11))
>left : Symbol(unknown)
>right : Symbol(unknown)
<a.b></a.b>;
>b : Symbol(unknown)
<a.b.c></a.b.c>;
>c : Symbol(unknown)
(<div />) < x;
>x : Symbol(x, Decl(jsxEsprimaFbTestSuite.tsx, 4, 11))
<div {...props} />;
<div {...props} post="attribute" />;
>post : Symbol(unknown)
<div pre="leading" pre2="attribute" {...props}></div>;
>pre : Symbol(unknown)
>pre2 : Symbol(unknown)
<a> </a>;

View file

@ -0,0 +1,160 @@
=== tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx ===
declare var React: any;
>React : any
declare var 日本語;
>日本語 : any
declare var AbC_def;
>AbC_def : any
declare var LeftRight;
>LeftRight : any
declare var x;
>x : any
declare var a;
>a : any
declare var props;
>props : any
<a />;
><a /> : any
>a : any
//<n:a n:v />; Namespace unsuported
//<a n:foo="bar"> {value} <b><c /></b></a>; Namespace unsuported
<a b={" "} c=" " d="&amp;" e="id=1&group=2" f="&#123456789" g="&#123*;" h="&#x;" />;
><a b={" "} c=" " d="&amp;" e="id=1&group=2" f="&#123456789" g="&#123*;" h="&#x;" /> : any
>a : any
>b : any
>c : any
>d : any
>e : any
>f : any
>g : any
>h : any
<a b="&notanentity;" />;
><a b="&notanentity;" /> : any
>a : any
>b : any
<a
><a/> : any
>a : any
/>;
<日本語></日本語>;
><日本語></日本語> : any
>日本語 : any
>日本語 : any
<AbC_def
><AbC_def test="&#x0026;&#38;">barbaz</AbC_def> : any
>AbC_def : any
test="&#x0026;&#38;">
>test : any
bar
baz
</AbC_def>;
>AbC_def : any
<a b={x ? <c /> : <d />} />;
><a b={x ? <c /> : <d />} /> : any
>a : any
>b : any
>x ? <c /> : <d /> : any
>x : any
><c /> : any
>c : any
><d /> : any
>d : any
<a>{}</a>;
><a>{}</a> : any
>a : any
>a : any
<a>{/* this is a comment */}</a>;
><a>{/* this is a comment */}</a> : any
>a : any
>a : any
<div>@test content</div>;
><div>@test content</div> : any
>div : any
>div : any
<div><br />7x invalid-js-identifier</div>;
><div><br />7x invalid-js-identifier</div> : any
>div : any
><br /> : any
>br : any
>div : any
<LeftRight left=<a /> right=<b>monkeys /> gorillas</b> />;
><LeftRight left=<a /> right=<b>monkeys /> gorillas</b> /> : any
>LeftRight : any
>left : any
><a /> : any
>a : any
>right : any
><b>monkeys /> gorillas</b> : any
>b : any
>b : any
<a.b></a.b>;
><a.b></a.b> : any
>a : any
>b : any
>a : any
>b : any
<a.b.c></a.b.c>;
><a.b.c></a.b.c> : any
>a : any
>b : any
>c : any
>a : any
>b : any
>c : any
(<div />) < x;
>(<div />) < x : boolean
>(<div />) : any
><div /> : any
>div : any
>x : any
<div {...props} />;
><div {...props} /> : any
>div : any
>props : any
<div {...props} post="attribute" />;
><div {...props} post="attribute" /> : any
>div : any
>props : any
>post : any
<div pre="leading" pre2="attribute" {...props}></div>;
><div pre="leading" pre2="attribute" {...props}></div> : any
>div : any
>pre : any
>pre2 : any
>props : any
>div : any
<a> </a>;
><a> </a> : any
>a : any
>a : any

View file

@ -0,0 +1,251 @@
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(3,1): error TS1128: Declaration or statement expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(3,3): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(3,4): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(4,3): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(5,1): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(5,2): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(5,3): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(5,6): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(5,7): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(6,6): error TS1005: '{' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(6,6): error TS2304: Cannot find name 'd'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(6,9): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(6,10): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(7,1): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(7,2): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(7,4): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(8,4): error TS17002: Expected corresponding JSX closing tag for 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(9,13): error TS1002: Unterminated string literal.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(10,1): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(10,2): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(10,3): error TS1005: ';' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(10,4): error TS2304: Cannot find name 'b'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(10,6): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(10,8): error TS2304: Cannot find name 'b'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(10,10): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(11,3): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(11,5): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(11,11): error TS1005: '>' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(11,12): error TS2304: Cannot find name 'b'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(11,16): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(12,2): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(12,5): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(12,13): error TS1005: '>' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(12,14): error TS2304: Cannot find name 'c'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(12,16): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(13,2): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(13,8): error TS17002: Expected corresponding JSX closing tag for 'a.b.c'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(14,1): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(14,2): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(14,5): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(14,7): error TS1128: Declaration or statement expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(14,8): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(14,10): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(15,2): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(15,4): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(15,9): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(16,3): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(16,4): error TS2304: Cannot find name 'foo'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(16,9): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(16,11): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(16,13): error TS2304: Cannot find name 'foo'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(16,18): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(17,3): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(17,11): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(17,13): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(17,22): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(22,10): error TS1005: '}' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(23,20): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(24,15): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(25,7): error TS1005: '...' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(25,7): error TS2304: Cannot find name 'props'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(27,17): error TS1005: '>' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(27,18): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(28,10): error TS2304: Cannot find name 'props'.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(28,28): error TS1005: '>' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(28,29): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(32,6): error TS1005: '{' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(33,6): error TS1005: '{' expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(33,7): error TS1109: Expression expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(35,4): error TS1003: Identifier expected.
tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx(35,21): error TS17002: Expected corresponding JSX closing tag for 'a'.
==== tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx (71 errors) ====
declare var React: any;
</>;
~~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
<a: />;
~
!!! error TS1003: Identifier expected.
<:a />;
~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
<a b=d />;
~
!!! error TS1005: '{' expected.
~
!!! error TS2304: Cannot find name 'd'.
~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
<a>;
~
!!! error TS1003: Identifier expected.
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1109: Expression expected.
<a></b>;
~~~~
!!! error TS17002: Expected corresponding JSX closing tag for 'a'.
<a foo="bar;
!!! error TS1002: Unterminated string literal.
<a:b></b>;
~
!!! error TS1003: Identifier expected.
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1005: ';' expected.
~
!!! error TS2304: Cannot find name 'b'.
~~
!!! error TS1109: Expression expected.
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS1109: Expression expected.
<a:b.c></a:b.c>;
~
!!! error TS1003: Identifier expected.
~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: '>' expected.
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS1109: Expression expected.
<a.b:c></a.b:c>;
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1003: Identifier expected.
~
!!! error TS1005: '>' expected.
~
!!! error TS2304: Cannot find name 'c'.
~
!!! error TS1109: Expression expected.
<a.b.c></a>;
~
!!! error TS2304: Cannot find name 'a'.
~~~~
!!! error TS17002: Expected corresponding JSX closing tag for 'a.b.c'.
<.a></.a>;
~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
~~
!!! error TS1109: Expression expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1109: Expression expected.
<a.></a.>;
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1003: Identifier expected.
~
!!! error TS1003: Identifier expected.
<a[foo]></a[foo]>;
~
!!! error TS1003: Identifier expected.
~~~
!!! error TS2304: Cannot find name 'foo'.
~~
!!! error TS1109: Expression expected.
~
!!! error TS2304: Cannot find name 'a'.
~~~
!!! error TS2304: Cannot find name 'foo'.
~
!!! error TS1109: Expression expected.
<a['foo']></a['foo']>;
~
!!! error TS1003: Identifier expected.
~~
!!! error TS1109: Expression expected.
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1109: Expression expected.
<a><a />;
<a b={}>;
var x = <div>one</div><div>two</div>;;
var x = <div>one</div> /* intervening comment */ <div>two</div>;;
<a>{"str";}</a>;
~
!!! error TS1005: '}' expected.
<span className="a", id="b" />;
~
!!! error TS1003: Identifier expected.
<div className"app">;
~~~~~
!!! error TS1003: Identifier expected.
<div {props} />;
~~~~~
!!! error TS1005: '...' expected.
~~~~~
!!! error TS2304: Cannot find name 'props'.
<div>stuff</div {...props}>;
~
!!! error TS1005: '>' expected.
~~~
!!! error TS1109: Expression expected.
<div {...props}>stuff</div {...props}>;
~~~~~
!!! error TS2304: Cannot find name 'props'.
~
!!! error TS1005: '>' expected.
~~~
!!! error TS1109: Expression expected.
<a>></a>;
<a> ></a>;
<a b=}>;
~
!!! error TS1005: '{' expected.
<a b=<}>;
~
!!! error TS1005: '{' expected.
~
!!! error TS1109: Expression expected.
<a>}</a>;
<a .../*hai*/asdf/>;
~~~
!!! error TS1003: Identifier expected.
!!! error TS17002: Expected corresponding JSX closing tag for 'a'.

View file

@ -0,0 +1,81 @@
//// [jsxInvalidEsprimaTestSuite.tsx]
declare var React: any;
</>;
<a: />;
<:a />;
<a b=d />;
<a>;
<a></b>;
<a foo="bar;
<a:b></b>;
<a:b.c></a:b.c>;
<a.b:c></a.b:c>;
<a.b.c></a>;
<.a></.a>;
<a.></a.>;
<a[foo]></a[foo]>;
<a['foo']></a['foo']>;
<a><a />;
<a b={}>;
var x = <div>one</div><div>two</div>;;
var x = <div>one</div> /* intervening comment */ <div>two</div>;;
<a>{"str";}</a>;
<span className="a", id="b" />;
<div className"app">;
<div {props} />;
<div>stuff</div {...props}>;
<div {...props}>stuff</div {...props}>;
<a>></a>;
<a> ></a>;
<a b=}>;
<a b=<}>;
<a>}</a>;
<a .../*hai*/asdf/>;
//// [jsxInvalidEsprimaTestSuite.jsx]
> ;
<a />;
< ;
a / > ;
<a b={d / > }/>
< a > ;
<a></b>;
<a foo="bar;/>
< a;
b > ;
b > ;
<a b= c=></a>;
b.c > ;
<a.b c=></a.b>;
c > ;
<a.b.c></a>;
< .a > ;
a > ;
<a.></a.>;
<a />;
[foo] > ;
a[foo] > ;
<a />;
['foo'] > ;
a['foo'] > ;
<a><a />;
<a b=>;
var x = <div>one</div><div>two</div>;;
var x = <div>one</div> /* intervening comment */ /* intervening comment */ <div>two</div>;;
<a>{"str"};}</a>;
<span className="a"/>, id="b" />;
<div className=/>"app">;
<div {...props}/>;
<div>stuff</div> {}...props}>;
<div {...props}>stuff</div> {}...props}>;
<a>></a>;
<a> ></a>;
<a b=>;
<a b={ < }>;
<a>}</a>;
<a /> .../*hai*/asdf/>;</></></></>;

View file

@ -0,0 +1,171 @@
//// [jsxReactTestSuite.tsx]
declare var React: any;
declare var Component:any;
declare var Composite:any;
declare var Composite2:any;
declare var Child:any;
declare var Namespace:any;
declare var foo: any;
declare var bar: any;
declare var y:any;
declare var x:any;
declare var z:any;
declare var hasOwnProperty:any;
<div>text</div>;
<div>
{this.props.children}
</div>;
<div>
<div><br /></div>
<Component>{foo}<br />{bar}</Component>
<br />
</div>;
<Composite>
{this.props.children}
</Composite>;
<Composite>
<Composite2 />
</Composite>;
var x =
<div
attr1={
"foo" + "bar"
}
attr2={
"foo" + "bar" +
"baz" + "bug"
}
attr3={
"foo" + "bar" +
"baz" + "bug"
// Extra line here.
}
attr4="baz">
</div>;
(
<div>
{/* A comment at the beginning */}
{/* A second comment at the beginning */}
<span>
{/* A nested comment */}
</span>
{/* A sandwiched comment */}
<br />
{/* A comment at the end */}
{/* A second comment at the end */}
</div>
);
(
<div
/* a multi-line
comment */
attr1="foo">
<span // a double-slash comment
attr2="bar"
/>
</div>
);
<div>&nbsp;</div>;
<div>&nbsp; </div>;
<hasOwnProperty>testing</hasOwnProperty>;
<Component constructor="foo" />;
<Namespace.Component />;
<Namespace.DeepNamespace.Component />;
<Component { ... x } y
={2 } z />;
<Component
{...this.props} sound="moo" />;
<font-face />;
<Component x={y} />;
<x-component />;
<Component {...x} />;
<Component { ...x } y={2} />;
<Component { ... x } y={2} z />;
<Component x={1} {...y} />;
<Component x={1} y="2" {...z} {...z}><Child /></Component>;
<Component x="1" {...(z = { y: 2 }, z)} z={3}>Text</Component>;
//// [jsxReactTestSuite.jsx]
<div>text</div>;
<div>
{this.props.children}
</div>;
<div>
<div><br /></div>
<Component>{foo}<br />{bar}</Component>
<br />
</div>;
<Composite>
{this.props.children}
</Composite>;
<Composite>
<Composite2 />
</Composite>;
var x = <div attr1={"foo" + "bar"} attr2={"foo" + "bar" +
"baz" + "bug"} attr3={"foo" + "bar" +
"baz" + "bug"} attr4="baz">
</div>;
(<div>
<span>
</span>
<br />
</div>);
(<div attr1="foo">
<span // a double-slash comment
attr2="bar"/>
</div>);
<div>&nbsp;</div>;
<div>&nbsp; </div>;
<hasOwnProperty>testing</hasOwnProperty>;
<Component constructor="foo"/>;
<Namespace.Component />;
<Namespace.DeepNamespace.Component />;
<Component {...x} y={2} z=/>;
<Component {...this.props} sound="moo"/>;
<font-face />;
<Component x={y}/>;
<x-component />;
<Component {...x}/>;
<Component {...x} y={2}/>;
<Component {...x} y={2} z=/>;
<Component x={1} {...y}/>;
<Component x={1} y="2" {...z} {...z}><Child /></Component>;
<Component x="1" {...(z = { y: 2 }, z)} z={3}>Text</Component>;

View file

@ -0,0 +1,194 @@
=== tests/cases/conformance/jsx/jsxReactTestSuite.tsx ===
declare var React: any;
>React : Symbol(React, Decl(jsxReactTestSuite.tsx, 1, 11))
declare var Component:any;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
declare var Composite:any;
>Composite : Symbol(Composite, Decl(jsxReactTestSuite.tsx, 3, 11))
declare var Composite2:any;
>Composite2 : Symbol(Composite2, Decl(jsxReactTestSuite.tsx, 4, 11))
declare var Child:any;
>Child : Symbol(Child, Decl(jsxReactTestSuite.tsx, 5, 11))
declare var Namespace:any;
>Namespace : Symbol(Namespace, Decl(jsxReactTestSuite.tsx, 6, 11))
declare var foo: any;
>foo : Symbol(foo, Decl(jsxReactTestSuite.tsx, 7, 11))
declare var bar: any;
>bar : Symbol(bar, Decl(jsxReactTestSuite.tsx, 8, 11))
declare var y:any;
>y : Symbol(y, Decl(jsxReactTestSuite.tsx, 9, 11))
declare var x:any;
>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3))
declare var z:any;
>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11))
declare var hasOwnProperty:any;
>hasOwnProperty : Symbol(hasOwnProperty, Decl(jsxReactTestSuite.tsx, 12, 11))
<div>text</div>;
<div>
{this.props.children}
</div>;
<div>
<div><br /></div>
<Component>{foo}<br />{bar}</Component>
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
<br />
</div>;
<Composite>
>Composite : Symbol(Composite, Decl(jsxReactTestSuite.tsx, 3, 11))
{this.props.children}
</Composite>;
<Composite>
>Composite : Symbol(Composite, Decl(jsxReactTestSuite.tsx, 3, 11))
<Composite2 />
>Composite2 : Symbol(Composite2, Decl(jsxReactTestSuite.tsx, 4, 11))
</Composite>;
var x =
>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3))
<div
attr1={
>attr1 : Symbol(unknown)
"foo" + "bar"
}
attr2={
>attr2 : Symbol(unknown)
"foo" + "bar" +
"baz" + "bug"
}
attr3={
>attr3 : Symbol(unknown)
"foo" + "bar" +
"baz" + "bug"
// Extra line here.
}
attr4="baz">
>attr4 : Symbol(unknown)
</div>;
(
<div>
{/* A comment at the beginning */}
{/* A second comment at the beginning */}
<span>
{/* A nested comment */}
</span>
{/* A sandwiched comment */}
<br />
{/* A comment at the end */}
{/* A second comment at the end */}
</div>
);
(
<div
/* a multi-line
comment */
attr1="foo">
>attr1 : Symbol(unknown)
<span // a double-slash comment
attr2="bar"
>attr2 : Symbol(unknown)
/>
</div>
);
<div>&nbsp;</div>;
<div>&nbsp; </div>;
<hasOwnProperty>testing</hasOwnProperty>;
<Component constructor="foo" />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>constructor : Symbol(unknown)
<Namespace.Component />;
>Component : Symbol(unknown)
<Namespace.DeepNamespace.Component />;
>Component : Symbol(unknown)
<Component { ... x } y
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>y : Symbol(unknown)
={2 } z />;
>z : Symbol(unknown)
<Component
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
{...this.props} sound="moo" />;
>sound : Symbol(unknown)
<font-face />;
<Component x={y} />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(unknown)
<x-component />;
<Component {...x} />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
<Component { ...x } y={2} />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>y : Symbol(unknown)
<Component { ... x } y={2} z />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>y : Symbol(unknown)
>z : Symbol(unknown)
<Component x={1} {...y} />;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(unknown)
<Component x={1} y="2" {...z} {...z}><Child /></Component>;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(unknown)
>y : Symbol(unknown)
>Child : Symbol(Child, Decl(jsxReactTestSuite.tsx, 5, 11))
<Component x="1" {...(z = { y: 2 }, z)} z={3}>Text</Component>;
>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11))
>x : Symbol(unknown)
>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11))
>y : Symbol(y, Decl(jsxReactTestSuite.tsx, 113, 27))
>z : Symbol(z, Decl(jsxReactTestSuite.tsx, 11, 11))
>z : Symbol(unknown)

View file

@ -0,0 +1,332 @@
=== tests/cases/conformance/jsx/jsxReactTestSuite.tsx ===
declare var React: any;
>React : any
declare var Component:any;
>Component : any
declare var Composite:any;
>Composite : any
declare var Composite2:any;
>Composite2 : any
declare var Child:any;
>Child : any
declare var Namespace:any;
>Namespace : any
declare var foo: any;
>foo : any
declare var bar: any;
>bar : any
declare var y:any;
>y : any
declare var x:any;
>x : any
declare var z:any;
>z : any
declare var hasOwnProperty:any;
>hasOwnProperty : any
<div>text</div>;
><div>text</div> : any
>div : any
>div : any
<div>
><div> {this.props.children}</div> : any
>div : any
{this.props.children}
>this.props.children : any
>this.props : any
>this : any
>props : any
>children : any
</div>;
>div : any
<div>
><div> <div><br /></div> <Component>{foo}<br />{bar}</Component> <br /></div> : any
>div : any
<div><br /></div>
><div><br /></div> : any
>div : any
><br /> : any
>br : any
>div : any
<Component>{foo}<br />{bar}</Component>
><Component>{foo}<br />{bar}</Component> : any
>Component : any
>foo : any
><br /> : any
>br : any
>bar : any
>Component : any
<br />
><br /> : any
>br : any
</div>;
>div : any
<Composite>
><Composite> {this.props.children}</Composite> : any
>Composite : any
{this.props.children}
>this.props.children : any
>this.props : any
>this : any
>props : any
>children : any
</Composite>;
>Composite : any
<Composite>
><Composite> <Composite2 /></Composite> : any
>Composite : any
<Composite2 />
><Composite2 /> : any
>Composite2 : any
</Composite>;
>Composite : any
var x =
>x : any
<div
><div attr1={ "foo" + "bar" } attr2={ "foo" + "bar" + "baz" + "bug" } attr3={ "foo" + "bar" + "baz" + "bug" // Extra line here. } attr4="baz"> </div> : any
>div : any
attr1={
>attr1 : any
"foo" + "bar"
>"foo" + "bar" : string
>"foo" : string
>"bar" : string
}
attr2={
>attr2 : any
"foo" + "bar" +
>"foo" + "bar" + "baz" + "bug" : string
>"foo" + "bar" + "baz" : string
>"foo" + "bar" : string
>"foo" : string
>"bar" : string
"baz" + "bug"
>"baz" : string
>"bug" : string
}
attr3={
>attr3 : any
"foo" + "bar" +
>"foo" + "bar" + "baz" + "bug" : string
>"foo" + "bar" + "baz" : string
>"foo" + "bar" : string
>"foo" : string
>"bar" : string
"baz" + "bug"
>"baz" : string
>"bug" : string
// Extra line here.
}
attr4="baz">
>attr4 : any
</div>;
>div : any
(
>( <div> {/* A comment at the beginning */} {/* A second comment at the beginning */} <span> {/* A nested comment */} </span> {/* A sandwiched comment */} <br /> {/* A comment at the end */} {/* A second comment at the end */} </div>) : any
<div>
><div> {/* A comment at the beginning */} {/* A second comment at the beginning */} <span> {/* A nested comment */} </span> {/* A sandwiched comment */} <br /> {/* A comment at the end */} {/* A second comment at the end */} </div> : any
>div : any
{/* A comment at the beginning */}
{/* A second comment at the beginning */}
<span>
><span> {/* A nested comment */} </span> : any
>span : any
{/* A nested comment */}
</span>
>span : any
{/* A sandwiched comment */}
<br />
><br /> : any
>br : any
{/* A comment at the end */}
{/* A second comment at the end */}
</div>
>div : any
);
(
>( <div /* a multi-line comment */ attr1="foo"> <span // a double-slash comment attr2="bar" /> </div>) : any
<div
><div /* a multi-line comment */ attr1="foo"> <span // a double-slash comment attr2="bar" /> </div> : any
>div : any
/* a multi-line
comment */
attr1="foo">
>attr1 : any
<span // a double-slash comment
><span // a double-slash comment attr2="bar" /> : any
>span : any
attr2="bar"
>attr2 : any
/>
</div>
>div : any
);
<div>&nbsp;</div>;
><div>&nbsp;</div> : any
>div : any
>div : any
<div>&nbsp; </div>;
><div>&nbsp; </div> : any
>div : any
>div : any
<hasOwnProperty>testing</hasOwnProperty>;
><hasOwnProperty>testing</hasOwnProperty> : any
>hasOwnProperty : any
>hasOwnProperty : any
<Component constructor="foo" />;
><Component constructor="foo" /> : any
>Component : any
>constructor : any
<Namespace.Component />;
><Namespace.Component /> : any
>Namespace : any
>Component : any
<Namespace.DeepNamespace.Component />;
><Namespace.DeepNamespace.Component /> : any
>Namespace : any
>DeepNamespace : any
>Component : any
<Component { ... x } y
><Component { ... x } y={2 } z /> : any
>Component : any
>x : any
>y : any
={2 } z />;
>z : any
<Component
><Component {...this.props} sound="moo" /> : any
>Component : any
{...this.props} sound="moo" />;
>this.props : any
>this : any
>props : any
>sound : any
<font-face />;
><font-face /> : any
>font-face : any
<Component x={y} />;
><Component x={y} /> : any
>Component : any
>x : any
>y : any
<x-component />;
><x-component /> : any
>x-component : any
<Component {...x} />;
><Component {...x} /> : any
>Component : any
>x : any
<Component { ...x } y={2} />;
><Component { ...x } y={2} /> : any
>Component : any
>x : any
>y : any
<Component { ... x } y={2} z />;
><Component { ... x } y={2} z /> : any
>Component : any
>x : any
>y : any
>z : any
<Component x={1} {...y} />;
><Component x={1} {...y} /> : any
>Component : any
>x : any
>y : any
<Component x={1} y="2" {...z} {...z}><Child /></Component>;
><Component x={1} y="2" {...z} {...z}><Child /></Component> : any
>Component : any
>x : any
>y : any
>z : any
>z : any
><Child /> : any
>Child : any
>Component : any
<Component x="1" {...(z = { y: 2 }, z)} z={3}>Text</Component>;
><Component x="1" {...(z = { y: 2 }, z)} z={3}>Text</Component> : any
>Component : any
>x : any
>(z = { y: 2 }, z) : any
>z = { y: 2 }, z : any
>z = { y: 2 } : { y: number; }
>z : any
>{ y: 2 } : { y: number; }
>y : number
>2 : number
>z : any
>z : any
>Component : any

View file

@ -1,6 +1,6 @@
error TS6053: File 'a.ts' not found.
error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.ts', '.d.ts'.
error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.tsx', '.ts', '.d.ts'.
!!! error TS6053: File 'a.ts' not found.
!!! error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.ts', '.d.ts'.
!!! error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.tsx', '.ts', '.d.ts'.

View file

@ -1,6 +1,6 @@
error TS6053: File 'a.ts' not found.
error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.ts', '.d.ts'.
error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.tsx', '.ts', '.d.ts'.
!!! error TS6053: File 'a.ts' not found.
!!! error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.ts', '.d.ts'.
!!! error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.tsx', '.ts', '.d.ts'.

View file

@ -0,0 +1,40 @@
tests/cases/conformance/jsx/tsxAttributeErrors.tsx(15,6): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxAttributeErrors.tsx(18,6): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/conformance/jsx/tsxAttributeErrors.tsx(22,6): error TS2606: Property 'text' of JSX spread attribute is not assignable to target property.
Type 'number' is not assignable to type 'string'.
==== tests/cases/conformance/jsx/tsxAttributeErrors.tsx (3 errors) ====
declare namespace JSX {
interface Element { }
interface IntrinsicElements {
div: {
text?: string;
width?: number;
}
span: any;
}
}
// Error, number is not assignable to string
<div text={42} />;
~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
// Error, string is not assignable to number
<div width={'foo'} />;
~~~~~~~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
// Error, number is not assignable to string
var attribs = { text: 100 };
<div {...attribs} />;
~~~~~~~~~~~~
!!! error TS2606: Property 'text' of JSX spread attribute is not assignable to target property.
!!! error TS2606: Type 'number' is not assignable to type 'string'.
// No errors here
<span foo='bar' bar={'foo'} />;

View file

@ -0,0 +1,38 @@
//// [tsxAttributeErrors.tsx]
declare namespace JSX {
interface Element { }
interface IntrinsicElements {
div: {
text?: string;
width?: number;
}
span: any;
}
}
// Error, number is not assignable to string
<div text={42} />;
// Error, string is not assignable to number
<div width={'foo'} />;
// Error, number is not assignable to string
var attribs = { text: 100 };
<div {...attribs} />;
// No errors here
<span foo='bar' bar={'foo'} />;
//// [tsxAttributeErrors.jsx]
// Error, number is not assignable to string
<div text={42}/>;
// Error, string is not assignable to number
<div width={'foo'}/>;
// Error, number is not assignable to string
var attribs = { text: 100 };
<div {...attribs}/>;
// No errors here
<span foo='bar' bar={'foo'}/>;

View file

@ -0,0 +1,50 @@
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(10,8): error TS1003: Identifier expected.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(10,10): error TS1005: ';' expected.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(10,10): error TS2304: Cannot find name 'data'.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(10,15): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(10,18): error TS1005: ':' expected.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(10,21): error TS1109: Expression expected.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(10,22): error TS1109: Expression expected.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(11,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(11,8): error TS1003: Identifier expected.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(11,9): error TS2304: Cannot find name 'data'.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(11,13): error TS1005: ';' expected.
tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx(11,20): error TS1161: Unterminated regular expression literal.
==== tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx (12 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: { "data-foo"?: string };
test2: { "data-foo"?: string };
}
}
// Invalid names
<test1 32data={32} />;
~~
!!! error TS1003: Identifier expected.
~~~~
!!! error TS1005: ';' expected.
~~~~
!!! error TS2304: Cannot find name 'data'.
~~~~
!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
~
!!! error TS1005: ':' expected.
~
!!! error TS1109: Expression expected.
~
!!! error TS1109: Expression expected.
<test2 -data={32} />;
~~~~~~
!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
~
!!! error TS1003: Identifier expected.
~~~~
!!! error TS2304: Cannot find name 'data'.
~
!!! error TS1005: ';' expected.
!!! error TS1161: Unterminated regular expression literal.

View file

@ -0,0 +1,23 @@
//// [tsxAttributeInvalidNames.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: { "data-foo"?: string };
test2: { "data-foo"?: string };
}
}
// Invalid names
<test1 32data={32} />;
<test2 -data={32} />;
//// [tsxAttributeInvalidNames.jsx]
// Invalid names
<test1 />;
32;
data = { 32: } / > ;
<test2 /> - data;
{
32;
}
/>;;

View file

@ -0,0 +1,12 @@
//// [tsxAttributeResolution.tsx]
declare namespace JSX {
interface IntrinsicElements {
x: { y: number; z: string; };
}
}
//// [tsxAttributeResolution.jsx]

View file

@ -0,0 +1,17 @@
=== tests/cases/conformance/jsx/tsxAttributeResolution.tsx ===
declare namespace JSX {
>JSX : Symbol(JSX, Decl(tsxAttributeResolution.tsx, 0, 0))
interface IntrinsicElements {
>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxAttributeResolution.tsx, 1, 23))
x: { y: number; z: string; };
>x : Symbol(x, Decl(tsxAttributeResolution.tsx, 2, 30))
>y : Symbol(y, Decl(tsxAttributeResolution.tsx, 3, 6))
>z : Symbol(z, Decl(tsxAttributeResolution.tsx, 3, 17))
}
}

View file

@ -0,0 +1,17 @@
=== tests/cases/conformance/jsx/tsxAttributeResolution.tsx ===
declare namespace JSX {
>JSX : any
interface IntrinsicElements {
>IntrinsicElements : IntrinsicElements
x: { y: number; z: string; };
>x : { y: number; z: string; }
>y : number
>z : string
}
}

View file

@ -0,0 +1,53 @@
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(22,8): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(23,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(24,8): error TS2339: Property 'y' does not exist on type 'Attribs1'.
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(25,8): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(29,1): error TS2324: Property 'reqd' is missing in type '{ reqd: string; }'.
tests/cases/conformance/jsx/tsxAttributeResolution1.tsx(30,8): error TS2322: Type 'number' is not assignable to type 'string'.
==== tests/cases/conformance/jsx/tsxAttributeResolution1.tsx (6 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
test2: { reqd: string };
}
}
interface Attribs1 {
x?: number;
s?: string;
}
// OK
<test1 x={0} />; // OK
<test1 />; // OK
<test1 data-x={true} />; // OK
<test2 reqd='true' />; // OK
<test2 reqd={'true'} />; // OK
// Errors
<test1 x={'0'} />; // Error, '0' is not number
~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
<test1 y={0} />; // Error, no property "y"
~
!!! error TS2339: Property 'y' does not exist on type 'Attribs1'.
<test1 y="foo" />; // Error, no property "y"
~
!!! error TS2339: Property 'y' does not exist on type 'Attribs1'.
<test1 x="32" />; // Error, "32" is not number
~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
// TODO attribute 'var' should be parseable
// <test1 var="10" />; // Error, no 'var' property
<test2 />; // Error, missing reqd
~~~~~~~~~
!!! error TS2324: Property 'reqd' is missing in type '{ reqd: string; }'.
<test2 reqd={10} />; // Error, reqd is not string
~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.

View file

@ -0,0 +1,50 @@
//// [tsxAttributeResolution1.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
test2: { reqd: string };
}
}
interface Attribs1 {
x?: number;
s?: string;
}
// OK
<test1 x={0} />; // OK
<test1 />; // OK
<test1 data-x={true} />; // OK
<test2 reqd='true' />; // OK
<test2 reqd={'true'} />; // OK
// Errors
<test1 x={'0'} />; // Error, '0' is not number
<test1 y={0} />; // Error, no property "y"
<test1 y="foo" />; // Error, no property "y"
<test1 x="32" />; // Error, "32" is not number
// TODO attribute 'var' should be parseable
// <test1 var="10" />; // Error, no 'var' property
<test2 />; // Error, missing reqd
<test2 reqd={10} />; // Error, reqd is not string
//// [tsxAttributeResolution1.jsx]
// OK
<test1 x={0}/>; // OK
<test1 />; // OK
<test1 data-x={true}/>; // OK
<test2 reqd='true'/>; // OK
<test2 reqd={'true'}/>; // OK
// Errors
<test1 x={'0'}/>; // Error, '0' is not number
<test1 y={0}/>; // Error, no property "y"
<test1 y="foo"/>; // Error, no property "y"
<test1 x="32"/>; // Error, "32" is not number
// TODO attribute 'var' should be parseable
// <test1 var="10" />; // Error, no 'var' property
<test2 />; // Error, missing reqd
<test2 reqd={10}/>; // Error, reqd is not string

View file

@ -0,0 +1,24 @@
tests/cases/conformance/jsx/tsxAttributeResolution2.tsx(17,21): error TS2339: Property 'leng' does not exist on type 'string'.
==== tests/cases/conformance/jsx/tsxAttributeResolution2.tsx (1 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
}
}
interface Attribs1 {
c1?: (x: string) => void;
}
// OK
<test1 c1={(x) => x.length} />; // OK
<test1 data-c1={(x) => x.leng} />; // OK
// Errors
<test1 c1={(x) => x.leng} />; // Error, no leng on 'string'
~~~~
!!! error TS2339: Property 'leng' does not exist on type 'string'.

View file

@ -0,0 +1,26 @@
//// [tsxAttributeResolution2.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
}
}
interface Attribs1 {
c1?: (x: string) => void;
}
// OK
<test1 c1={(x) => x.length} />; // OK
<test1 data-c1={(x) => x.leng} />; // OK
// Errors
<test1 c1={(x) => x.leng} />; // Error, no leng on 'string'
//// [tsxAttributeResolution2.jsx]
// OK
<test1 c1={function (x) { return x.length; }}/>; // OK
<test1 data-c1={function (x) { return x.leng; }}/>; // OK
// Errors
<test1 c1={function (x) { return x.leng; }}/>; // Error, no leng on 'string'

View file

@ -0,0 +1,59 @@
tests/cases/conformance/jsx/tsxAttributeResolution3.tsx(19,8): error TS2606: Property 'x' of JSX spread attribute is not assignable to target property.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxAttributeResolution3.tsx(23,1): error TS2324: Property 'x' is missing in type 'Attribs1'.
tests/cases/conformance/jsx/tsxAttributeResolution3.tsx(31,15): error TS2606: Property 'x' of JSX spread attribute is not assignable to target property.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxAttributeResolution3.tsx(39,8): error TS2322: Type 'number' is not assignable to type 'string'.
==== tests/cases/conformance/jsx/tsxAttributeResolution3.tsx (4 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
}
}
interface Attribs1 {
x: string;
y?: number;
z?: string;
}
// OK
var obj1 = { x: 'foo' };
<test1 {...obj1} />
// Error, x is not string
var obj2 = { x: 32 };
<test1 {...obj2} />
~~~~~~~~~
!!! error TS2606: Property 'x' of JSX spread attribute is not assignable to target property.
!!! error TS2606: Type 'number' is not assignable to type 'string'.
// Error, x is missing
var obj3 = { y: 32 };
<test1 {...obj3} />
~~~~~~~~~~~~~~~~~~~
!!! error TS2324: Property 'x' is missing in type 'Attribs1'.
// OK
var obj4 = { x: 32, y: 32 };
<test1 {...obj4} x="ok" />
// Error
var obj5 = { x: 32, y: 32 };
<test1 x="ok" {...obj5} />
~~~~~~~~~
!!! error TS2606: Property 'x' of JSX spread attribute is not assignable to target property.
!!! error TS2606: Type 'number' is not assignable to type 'string'.
// OK
var obj6 = { x: 'ok', y: 32, extra: 100 };
<test1 {...obj6} />
// Error
var obj7 = { x: 'foo' };
<test1 x={32} {...obj7} />
~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.

View file

@ -0,0 +1,64 @@
//// [tsxAttributeResolution3.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
}
}
interface Attribs1 {
x: string;
y?: number;
z?: string;
}
// OK
var obj1 = { x: 'foo' };
<test1 {...obj1} />
// Error, x is not string
var obj2 = { x: 32 };
<test1 {...obj2} />
// Error, x is missing
var obj3 = { y: 32 };
<test1 {...obj3} />
// OK
var obj4 = { x: 32, y: 32 };
<test1 {...obj4} x="ok" />
// Error
var obj5 = { x: 32, y: 32 };
<test1 x="ok" {...obj5} />
// OK
var obj6 = { x: 'ok', y: 32, extra: 100 };
<test1 {...obj6} />
// Error
var obj7 = { x: 'foo' };
<test1 x={32} {...obj7} />
//// [tsxAttributeResolution3.jsx]
// OK
var obj1 = { x: 'foo' };
<test1 {...obj1}/>;
// Error, x is not string
var obj2 = { x: 32 };
<test1 {...obj2}/>;
// Error, x is missing
var obj3 = { y: 32 };
<test1 {...obj3}/>;
// OK
var obj4 = { x: 32, y: 32 };
<test1 {...obj4} x="ok"/>;
// Error
var obj5 = { x: 32, y: 32 };
<test1 x="ok" {...obj5}/>;
// OK
var obj6 = { x: 'ok', y: 32, extra: 100 };
<test1 {...obj6}/>;
// Error
var obj7 = { x: 'foo' };
<test1 x={32} {...obj7}/>;

View file

@ -0,0 +1,22 @@
tests/cases/conformance/jsx/tsxAttributeResolution4.tsx(15,26): error TS2339: Property 'len' does not exist on type 'string'.
==== tests/cases/conformance/jsx/tsxAttributeResolution4.tsx (1 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
}
}
interface Attribs1 {
x(n: string): void;
}
// OK
<test1 {... {x: (n) => 0} } />;
// Error, no member 'len' on 'string'
<test1 {... {x: (n) => n.len} } />;
~~~
!!! error TS2339: Property 'len' does not exist on type 'string'.

View file

@ -0,0 +1,23 @@
//// [tsxAttributeResolution4.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
}
}
interface Attribs1 {
x(n: string): void;
}
// OK
<test1 {... {x: (n) => 0} } />;
// Error, no member 'len' on 'string'
<test1 {... {x: (n) => n.len} } />;
//// [tsxAttributeResolution4.jsx]
// OK
<test1 {...{ x: function (n) { return 0; } }}/>;
// Error, no member 'len' on 'string'
<test1 {...{ x: function (n) { return n.len; } }}/>;

View file

@ -0,0 +1,45 @@
tests/cases/conformance/jsx/tsxAttributeResolution5.tsx(21,16): error TS2606: Property 'x' of JSX spread attribute is not assignable to target property.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxAttributeResolution5.tsx(25,9): error TS2324: Property 'x' is missing in type 'Attribs1'.
tests/cases/conformance/jsx/tsxAttributeResolution5.tsx(29,1): error TS2324: Property 'x' is missing in type 'Attribs1'.
==== tests/cases/conformance/jsx/tsxAttributeResolution5.tsx (3 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
test2: Attribs2;
}
}
interface Attribs1 {
x: string;
}
interface Attribs2 {
toString(): string;
}
function make1<T extends {x: string}> (obj: T) {
return <test1 {...obj} />; // OK
}
function make2<T extends {x: number}> (obj: T) {
return <test1 {...obj} />; // Error (x is number, not string)
~~~~~~~~
!!! error TS2606: Property 'x' of JSX spread attribute is not assignable to target property.
!!! error TS2606: Type 'number' is not assignable to type 'string'.
}
function make3<T extends {y: string}> (obj: T) {
return <test1 {...obj} />; // Error, missing x
~~~~~~~~~~~~~~~~~~
!!! error TS2324: Property 'x' is missing in type 'Attribs1'.
}
<test1 {...{}} />; // Error, missing x
~~~~~~~~~~~~~~~~~
!!! error TS2324: Property 'x' is missing in type 'Attribs1'.
<test2 {...{}} />; // OK

View file

@ -0,0 +1,45 @@
//// [tsxAttributeResolution5.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: Attribs1;
test2: Attribs2;
}
}
interface Attribs1 {
x: string;
}
interface Attribs2 {
toString(): string;
}
function make1<T extends {x: string}> (obj: T) {
return <test1 {...obj} />; // OK
}
function make2<T extends {x: number}> (obj: T) {
return <test1 {...obj} />; // Error (x is number, not string)
}
function make3<T extends {y: string}> (obj: T) {
return <test1 {...obj} />; // Error, missing x
}
<test1 {...{}} />; // Error, missing x
<test2 {...{}} />; // OK
//// [tsxAttributeResolution5.jsx]
function make1(obj) {
return <test1 {...obj}/>; // OK
}
function make2(obj) {
return <test1 {...obj}/>; // Error (x is number, not string)
}
function make3(obj) {
return <test1 {...obj}/>; // Error, missing x
}
<test1 {...{}}/>; // Error, missing x
<test2 {...{}}/>; // OK

View file

@ -0,0 +1,30 @@
tests/cases/conformance/jsx/tsxAttributeResolution6.tsx(10,8): error TS2322: Type 'boolean' is not assignable to type 'string'.
tests/cases/conformance/jsx/tsxAttributeResolution6.tsx(11,8): error TS2322: Type 'string' is not assignable to type 'boolean'.
tests/cases/conformance/jsx/tsxAttributeResolution6.tsx(12,1): error TS2324: Property 'n' is missing in type '{ n: boolean; }'.
==== tests/cases/conformance/jsx/tsxAttributeResolution6.tsx (3 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: { n?: boolean; s?: string};
test2: { n: boolean; };
}
}
// Error
<test1 s />;
~
!!! error TS2322: Type 'boolean' is not assignable to type 'string'.
<test1 n='true' />;
~~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'boolean'.
<test2 />;
~~~~~~~~~
!!! error TS2324: Property 'n' is missing in type '{ n: boolean; }'.
// OK
<test1 n />;
<test1 n={false} />;
<test2 n />;

View file

@ -0,0 +1,29 @@
//// [tsxAttributeResolution6.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: { n?: boolean; s?: string};
test2: { n: boolean; };
}
}
// Error
<test1 s />;
<test1 n='true' />;
<test2 />;
// OK
<test1 n />;
<test1 n={false} />;
<test2 n />;
//// [tsxAttributeResolution6.jsx]
// Error
<test1 s=/>;
<test1 n='true'/>;
<test2 />;
// OK
<test1 n=/>;
<test1 n={false}/>;
<test2 n=/>;

View file

@ -0,0 +1,21 @@
tests/cases/conformance/jsx/tsxAttributeResolution7.tsx(9,8): error TS2322: Type 'number' is not assignable to type 'string'.
==== tests/cases/conformance/jsx/tsxAttributeResolution7.tsx (1 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: { "data-foo"?: string };
}
}
// Error
<test1 data-foo={32} />;
~~~~~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
// OK
<test1 data-foo={'32'} />;
<test1 data-bar={'32'} />;
<test1 data-bar={32} />;

View file

@ -0,0 +1,24 @@
//// [tsxAttributeResolution7.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: { "data-foo"?: string };
}
}
// Error
<test1 data-foo={32} />;
// OK
<test1 data-foo={'32'} />;
<test1 data-bar={'32'} />;
<test1 data-bar={32} />;
//// [tsxAttributeResolution7.jsx]
// Error
<test1 data-foo={32}/>;
// OK
<test1 data-foo={'32'}/>;
<test1 data-bar={'32'}/>;
<test1 data-bar={32}/>;

View file

@ -0,0 +1,16 @@
//// [tsxAttributeResolution8.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
test1: {x: string};
}
}
var x: any;
// Should be OK
<test1 {...x} />
//// [tsxAttributeResolution8.jsx]
var x;
// Should be OK
<test1 {...x}/>;

View file

@ -0,0 +1,23 @@
=== tests/cases/conformance/jsx/tsxAttributeResolution8.tsx ===
declare module JSX {
>JSX : Symbol(JSX, Decl(tsxAttributeResolution8.tsx, 0, 0))
interface Element { }
>Element : Symbol(Element, Decl(tsxAttributeResolution8.tsx, 0, 20))
interface IntrinsicElements {
>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxAttributeResolution8.tsx, 1, 22))
test1: {x: string};
>test1 : Symbol(test1, Decl(tsxAttributeResolution8.tsx, 2, 30))
>x : Symbol(x, Decl(tsxAttributeResolution8.tsx, 3, 10))
}
}
var x: any;
>x : Symbol(x, Decl(tsxAttributeResolution8.tsx, 7, 3))
// Should be OK
<test1 {...x} />
>test1 : Symbol(JSX.IntrinsicElements.test1, Decl(tsxAttributeResolution8.tsx, 2, 30))

View file

@ -0,0 +1,25 @@
=== tests/cases/conformance/jsx/tsxAttributeResolution8.tsx ===
declare module JSX {
>JSX : any
interface Element { }
>Element : Element
interface IntrinsicElements {
>IntrinsicElements : IntrinsicElements
test1: {x: string};
>test1 : { x: string; }
>x : string
}
}
var x: any;
>x : any
// Should be OK
<test1 {...x} />
><test1 {...x} /> : JSX.Element
>test1 : any
>x : any

View file

@ -0,0 +1,55 @@
//// [tsxElementResolution.tsx]
declare namespace JSX {
interface IntrinsicElements {
foundFirst: { x: string };
'string_named';
'var';
}
}
class foundFirst { }
class Other {}
module Dotted {
export class Name { }
}
// Should find the intrinsic element, not the class element
var a = <foundFirst x="hello" />;
var b = <string_named />;
// TODO: This should not be a parse error (should
// parse a property name here, not identifier)
// var c = <var />;
var d = <Other />;
var e = <Dotted.Name />;
//// [tsxElementResolution.jsx]
var foundFirst = (function () {
function foundFirst() {
}
return foundFirst;
})();
var Other = (function () {
function Other() {
}
return Other;
})();
var Dotted;
(function (Dotted) {
var Name = (function () {
function Name() {
}
return Name;
})();
Dotted.Name = Name;
})(Dotted || (Dotted = {}));
// Should find the intrinsic element, not the class element
var a = <foundFirst x="hello"/>;
var b = <string_named />;
// TODO: This should not be a parse error (should
// parse a property name here, not identifier)
// var c = <var />;
var d = <Other />;
var e = <Dotted.Name />;

View file

@ -0,0 +1,51 @@
=== tests/cases/conformance/jsx/tsxElementResolution.tsx ===
declare namespace JSX {
>JSX : Symbol(JSX, Decl(tsxElementResolution.tsx, 0, 0))
interface IntrinsicElements {
>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxElementResolution.tsx, 1, 23))
foundFirst: { x: string };
>foundFirst : Symbol(foundFirst, Decl(tsxElementResolution.tsx, 2, 30))
>x : Symbol(x, Decl(tsxElementResolution.tsx, 3, 15))
'string_named';
'var';
}
}
class foundFirst { }
>foundFirst : Symbol(foundFirst, Decl(tsxElementResolution.tsx, 7, 1))
class Other {}
>Other : Symbol(Other, Decl(tsxElementResolution.tsx, 9, 20))
module Dotted {
>Dotted : Symbol(Dotted, Decl(tsxElementResolution.tsx, 10, 14))
export class Name { }
>Name : Symbol(Name, Decl(tsxElementResolution.tsx, 12, 15))
}
// Should find the intrinsic element, not the class element
var a = <foundFirst x="hello" />;
>a : Symbol(a, Decl(tsxElementResolution.tsx, 17, 3))
>foundFirst : Symbol(JSX.IntrinsicElements.foundFirst, Decl(tsxElementResolution.tsx, 2, 30))
>x : Symbol(x, Decl(tsxElementResolution.tsx, 3, 15))
var b = <string_named />;
>b : Symbol(b, Decl(tsxElementResolution.tsx, 18, 3))
>string_named : Symbol(JSX.IntrinsicElements.'string_named', Decl(tsxElementResolution.tsx, 3, 28))
// TODO: This should not be a parse error (should
// parse a property name here, not identifier)
// var c = <var />;
var d = <Other />;
>d : Symbol(d, Decl(tsxElementResolution.tsx, 22, 3))
>Other : Symbol(Other, Decl(tsxElementResolution.tsx, 9, 20))
var e = <Dotted.Name />;
>e : Symbol(e, Decl(tsxElementResolution.tsx, 23, 3))
>Name : Symbol(Dotted.Name, Decl(tsxElementResolution.tsx, 12, 15))

View file

@ -0,0 +1,56 @@
=== tests/cases/conformance/jsx/tsxElementResolution.tsx ===
declare namespace JSX {
>JSX : any
interface IntrinsicElements {
>IntrinsicElements : IntrinsicElements
foundFirst: { x: string };
>foundFirst : { x: string; }
>x : string
'string_named';
'var';
}
}
class foundFirst { }
>foundFirst : foundFirst
class Other {}
>Other : Other
module Dotted {
>Dotted : typeof Dotted
export class Name { }
>Name : Name
}
// Should find the intrinsic element, not the class element
var a = <foundFirst x="hello" />;
>a : any
><foundFirst x="hello" /> : any
>foundFirst : typeof foundFirst
>x : any
var b = <string_named />;
>b : any
><string_named /> : any
>string_named : any
// TODO: This should not be a parse error (should
// parse a property name here, not identifier)
// var c = <var />;
var d = <Other />;
>d : any
><Other /> : any
>Other : typeof Other
var e = <Dotted.Name />;
>e : any
><Dotted.Name /> : any
>Dotted : any
>Name : any

View file

@ -0,0 +1,18 @@
tests/cases/conformance/jsx/tsxElementResolution1.tsx(12,1): error TS2339: Property 'span' does not exist on type 'JSX.IntrinsicElements'.
==== tests/cases/conformance/jsx/tsxElementResolution1.tsx (1 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
div: any
}
}
// OK
<div />;
// Fail
<span />;
~~~~~~~~
!!! error TS2339: Property 'span' does not exist on type 'JSX.IntrinsicElements'.

View file

@ -0,0 +1,19 @@
//// [tsxElementResolution1.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
div: any
}
}
// OK
<div />;
// Fail
<span />;
//// [tsxElementResolution1.jsx]
// OK
<div />;
// Fail
<span />;

View file

@ -0,0 +1,28 @@
tests/cases/conformance/jsx/tsxElementResolution10.tsx(13,1): error TS2605: JSX element type '{ x: number; }' is not a constructor function for JSX elements.
Property 'render' is missing in type '{ x: number; }'.
==== tests/cases/conformance/jsx/tsxElementResolution10.tsx (1 errors) ====
declare module JSX {
interface Element { }
interface ElementClass {
render: any;
}
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): { x: number };
}
var Obj1: Obj1type;
<Obj1 x={10} />; // Error, no render member
~~~~~~~~~~~~~~~
!!! error TS2605: JSX element type '{ x: number; }' is not a constructor function for JSX elements.
!!! error TS2605: Property 'render' is missing in type '{ x: number; }'.
interface Obj2type {
(n: string): { x: number; render: any; };
}
var Obj2: Obj2type;
<Obj2 x={32} render={100} />; // OK

View file

@ -0,0 +1,27 @@
//// [tsxElementResolution10.tsx]
declare module JSX {
interface Element { }
interface ElementClass {
render: any;
}
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): { x: number };
}
var Obj1: Obj1type;
<Obj1 x={10} />; // Error, no render member
interface Obj2type {
(n: string): { x: number; render: any; };
}
var Obj2: Obj2type;
<Obj2 x={32} render={100} />; // OK
//// [tsxElementResolution10.jsx]
var Obj1;
<Obj1 x={10}/>; // Error, no render member
var Obj2;
<Obj2 x={32} render={100}/>; // OK

View file

@ -0,0 +1,30 @@
tests/cases/conformance/jsx/tsxElementResolution11.tsx(17,7): error TS2339: Property 'x' does not exist on type '{ q?: number; }'.
==== tests/cases/conformance/jsx/tsxElementResolution11.tsx (1 errors) ====
declare module JSX {
interface Element { }
interface ElementAttributesProperty { }
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): any;
}
var Obj1: Obj1type;
<Obj1 x={10} />; // OK
interface Obj2type {
new(n: string): { q?: number };
}
var Obj2: Obj2type;
<Obj2 x={10} />; // Error
~
!!! error TS2339: Property 'x' does not exist on type '{ q?: number; }'.
interface Obj3type {
new(n: string): { x: number; };
}
var Obj3: Obj3type;
<Obj3 x={10} />; // OK

View file

@ -0,0 +1,33 @@
//// [tsxElementResolution11.tsx]
declare module JSX {
interface Element { }
interface ElementAttributesProperty { }
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): any;
}
var Obj1: Obj1type;
<Obj1 x={10} />; // OK
interface Obj2type {
new(n: string): { q?: number };
}
var Obj2: Obj2type;
<Obj2 x={10} />; // Error
interface Obj3type {
new(n: string): { x: number; };
}
var Obj3: Obj3type;
<Obj3 x={10} />; // OK
//// [tsxElementResolution11.jsx]
var Obj1;
<Obj1 x={10}/>; // OK
var Obj2;
<Obj2 x={10}/>; // Error
var Obj3;
<Obj3 x={10}/>; // OK

View file

@ -0,0 +1,43 @@
tests/cases/conformance/jsx/tsxElementResolution12.tsx(17,2): error TS2304: Cannot find name 'Obj2'.
tests/cases/conformance/jsx/tsxElementResolution12.tsx(23,1): error TS2607: JSX element class does not support attributes because it does not have a 'pr' property
tests/cases/conformance/jsx/tsxElementResolution12.tsx(30,7): error TS2322: Type 'string' is not assignable to type 'number'.
==== tests/cases/conformance/jsx/tsxElementResolution12.tsx (3 errors) ====
declare module JSX {
interface Element { }
interface ElementAttributesProperty { pr: any; }
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): any;
}
var Obj1: Obj1type;
<Obj1 x={10} />; // OK
interface Obj2type {
new(n: string): { q?: number; pr: any };
}
var obj2: Obj2type;
<Obj2 x={10} />; // OK
~~~~
!!! error TS2304: Cannot find name 'Obj2'.
interface Obj3type {
new(n: string): { x: number; };
}
var Obj3: Obj3type;
<Obj3 x={10} />; // Error
~~~~~~~~~~~~~~~
!!! error TS2607: JSX element class does not support attributes because it does not have a 'pr' property
interface Obj4type {
new(n: string): { x: number; pr: { x: number; } };
}
var Obj4: Obj4type;
<Obj4 x={10} />; // OK
<Obj4 x={'10'} />; // Error
~~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'number'.

View file

@ -0,0 +1,43 @@
//// [tsxElementResolution12.tsx]
declare module JSX {
interface Element { }
interface ElementAttributesProperty { pr: any; }
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): any;
}
var Obj1: Obj1type;
<Obj1 x={10} />; // OK
interface Obj2type {
new(n: string): { q?: number; pr: any };
}
var obj2: Obj2type;
<Obj2 x={10} />; // OK
interface Obj3type {
new(n: string): { x: number; };
}
var Obj3: Obj3type;
<Obj3 x={10} />; // Error
interface Obj4type {
new(n: string): { x: number; pr: { x: number; } };
}
var Obj4: Obj4type;
<Obj4 x={10} />; // OK
<Obj4 x={'10'} />; // Error
//// [tsxElementResolution12.jsx]
var Obj1;
<Obj1 x={10}/>; // OK
var obj2;
<Obj2 x={10}/>; // OK
var Obj3;
<Obj3 x={10}/>; // Error
var Obj4;
<Obj4 x={10}/>; // OK
<Obj4 x={'10'}/>; // Error

View file

@ -0,0 +1,16 @@
//// [tsxElementResolution13.tsx]
declare module JSX {
interface Element { }
interface ElementAttributesProperty { pr1: any; pr2: any; }
}
interface Obj1 {
new(n: string): any;
}
var obj1: Obj1;
<obj1 x={10} />; // Error
//// [tsxElementResolution13.jsx]
var obj1;
<obj1 x={10}/>; // Error

View file

@ -0,0 +1,26 @@
=== tests/cases/conformance/jsx/tsxElementResolution13.tsx ===
declare module JSX {
>JSX : Symbol(JSX, Decl(tsxElementResolution13.tsx, 0, 0))
interface Element { }
>Element : Symbol(Element, Decl(tsxElementResolution13.tsx, 0, 20))
interface ElementAttributesProperty { pr1: any; pr2: any; }
>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(tsxElementResolution13.tsx, 1, 22))
>pr1 : Symbol(pr1, Decl(tsxElementResolution13.tsx, 2, 38))
>pr2 : Symbol(pr2, Decl(tsxElementResolution13.tsx, 2, 48))
}
interface Obj1 {
>Obj1 : Symbol(Obj1, Decl(tsxElementResolution13.tsx, 3, 1))
new(n: string): any;
>n : Symbol(n, Decl(tsxElementResolution13.tsx, 6, 5))
}
var obj1: Obj1;
>obj1 : Symbol(obj1, Decl(tsxElementResolution13.tsx, 8, 3))
>Obj1 : Symbol(Obj1, Decl(tsxElementResolution13.tsx, 3, 1))
<obj1 x={10} />; // Error
>x : Symbol(unknown)

View file

@ -0,0 +1,28 @@
=== tests/cases/conformance/jsx/tsxElementResolution13.tsx ===
declare module JSX {
>JSX : any
interface Element { }
>Element : Element
interface ElementAttributesProperty { pr1: any; pr2: any; }
>ElementAttributesProperty : ElementAttributesProperty
>pr1 : any
>pr2 : any
}
interface Obj1 {
>Obj1 : Obj1
new(n: string): any;
>n : string
}
var obj1: Obj1;
>obj1 : Obj1
>Obj1 : Obj1
<obj1 x={10} />; // Error
><obj1 x={10} /> : JSX.Element
>obj1 : Obj1
>x : any

View file

@ -0,0 +1,15 @@
//// [tsxElementResolution14.tsx]
declare module JSX {
interface Element { }
}
interface Obj1 {
new(n: string): {};
}
var obj1: Obj1;
<obj1 x={10} />; // OK
//// [tsxElementResolution14.jsx]
var obj1;
<obj1 x={10}/>; // OK

View file

@ -0,0 +1,21 @@
=== tests/cases/conformance/jsx/tsxElementResolution14.tsx ===
declare module JSX {
>JSX : Symbol(JSX, Decl(tsxElementResolution14.tsx, 0, 0))
interface Element { }
>Element : Symbol(Element, Decl(tsxElementResolution14.tsx, 0, 20))
}
interface Obj1 {
>Obj1 : Symbol(Obj1, Decl(tsxElementResolution14.tsx, 2, 1))
new(n: string): {};
>n : Symbol(n, Decl(tsxElementResolution14.tsx, 5, 5))
}
var obj1: Obj1;
>obj1 : Symbol(obj1, Decl(tsxElementResolution14.tsx, 7, 3))
>Obj1 : Symbol(Obj1, Decl(tsxElementResolution14.tsx, 2, 1))
<obj1 x={10} />; // OK
>x : Symbol(unknown)

View file

@ -0,0 +1,23 @@
=== tests/cases/conformance/jsx/tsxElementResolution14.tsx ===
declare module JSX {
>JSX : any
interface Element { }
>Element : Element
}
interface Obj1 {
>Obj1 : Obj1
new(n: string): {};
>n : string
}
var obj1: Obj1;
>obj1 : Obj1
>Obj1 : Obj1
<obj1 x={10} />; // OK
><obj1 x={10} /> : JSX.Element
>obj1 : Obj1
>x : any

View file

@ -0,0 +1,18 @@
tests/cases/conformance/jsx/tsxElementResolution15.tsx(3,12): error TS2608: The global type 'JSX.ElementAttributesProperty' may not have more than one property
==== tests/cases/conformance/jsx/tsxElementResolution15.tsx (1 errors) ====
declare module JSX {
interface Element { }
interface ElementAttributesProperty { pr1: any; pr2: any; }
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2608: The global type 'JSX.ElementAttributesProperty' may not have more than one property
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): {};
}
var Obj1: Obj1type;
<Obj1 x={10} />; // Error

View file

@ -0,0 +1,17 @@
//// [tsxElementResolution15.tsx]
declare module JSX {
interface Element { }
interface ElementAttributesProperty { pr1: any; pr2: any; }
interface IntrinsicElements { }
}
interface Obj1type {
new(n: string): {};
}
var Obj1: Obj1type;
<Obj1 x={10} />; // Error
//// [tsxElementResolution15.jsx]
var Obj1;
<Obj1 x={10}/>; // Error

View file

@ -0,0 +1,18 @@
tests/cases/conformance/jsx/tsxElementResolution16.tsx(8,1): error TS2602: JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.
tests/cases/conformance/jsx/tsxElementResolution16.tsx(8,1): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists
==== tests/cases/conformance/jsx/tsxElementResolution16.tsx (2 errors) ====
declare module JSX {
}
interface Obj1 {
new(n: string): {};
}
var obj1: Obj1;
<obj1 x={10} />; // Error (JSX.Element is implicit any)
~~~~~~~~~~~~~~~
!!! error TS2602: JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.
~~~~~~~~~~~~~~~
!!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists

View file

@ -0,0 +1,14 @@
//// [tsxElementResolution16.tsx]
declare module JSX {
}
interface Obj1 {
new(n: string): {};
}
var obj1: Obj1;
<obj1 x={10} />; // Error (JSX.Element is implicit any)
//// [tsxElementResolution16.jsx]
var obj1;
<obj1 x={10}/>; // Error (JSX.Element is implicit any)

View file

@ -0,0 +1,18 @@
=== tests/cases/conformance/jsx/tsxElementResolution16.tsx ===
declare module JSX {
>JSX : Symbol(JSX, Decl(tsxElementResolution16.tsx, 0, 0))
}
interface Obj1 {
>Obj1 : Symbol(Obj1, Decl(tsxElementResolution16.tsx, 1, 1))
new(n: string): {};
>n : Symbol(n, Decl(tsxElementResolution16.tsx, 4, 5))
}
var obj1: Obj1;
>obj1 : Symbol(obj1, Decl(tsxElementResolution16.tsx, 6, 3))
>Obj1 : Symbol(Obj1, Decl(tsxElementResolution16.tsx, 1, 1))
<obj1 x={10} />; // Error (JSX.Element is missing)
>x : Symbol(unknown)

View file

@ -0,0 +1,20 @@
=== tests/cases/conformance/jsx/tsxElementResolution16.tsx ===
declare module JSX {
>JSX : any
}
interface Obj1 {
>Obj1 : Obj1
new(n: string): {};
>n : string
}
var obj1: Obj1;
>obj1 : Obj1
>Obj1 : Obj1
<obj1 x={10} />; // Error (JSX.Element is missing)
><obj1 x={10} /> : any
>obj1 : Obj1
>x : any

View file

@ -0,0 +1,34 @@
//// [tests/cases/conformance/jsx/tsxElementResolution17.tsx] ////
//// [file.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements { }
}
declare module 'elements1' {
class MyElement {
}
}
declare module 'elements2' {
class MyElement {
}
}
//// [consumer.tsx]
///<reference path="file.tsx" />
// Should keep s1 and elide s2
import s1 = require('elements1');
import s2 = require('elements2');
<s1.MyElement />;
//// [file.jsx]
//// [consumer.jsx]
define(["require", "exports", 'elements1'], function (require, exports, s1) {
<s1.MyElement />;
});

View file

@ -0,0 +1,38 @@
=== tests/cases/conformance/jsx/consumer.tsx ===
///<reference path="file.tsx" />
// Should keep s1 and elide s2
import s1 = require('elements1');
>s1 : Symbol(s1, Decl(consumer.tsx, 0, 0))
import s2 = require('elements2');
>s2 : Symbol(s2, Decl(consumer.tsx, 2, 33))
<s1.MyElement />;
>MyElement : Symbol(s1.MyElement, Decl(file.tsx, 6, 28))
=== tests/cases/conformance/jsx/file.tsx ===
declare module JSX {
>JSX : Symbol(JSX, Decl(file.tsx, 0, 0))
interface Element { }
>Element : Symbol(Element, Decl(file.tsx, 1, 20))
interface IntrinsicElements { }
>IntrinsicElements : Symbol(IntrinsicElements, Decl(file.tsx, 2, 22))
}
declare module 'elements1' {
class MyElement {
>MyElement : Symbol(MyElement, Decl(file.tsx, 6, 28))
}
}
declare module 'elements2' {
class MyElement {
>MyElement : Symbol(MyElement, Decl(file.tsx, 12, 28))
}
}

View file

@ -0,0 +1,40 @@
=== tests/cases/conformance/jsx/consumer.tsx ===
///<reference path="file.tsx" />
// Should keep s1 and elide s2
import s1 = require('elements1');
>s1 : typeof s1
import s2 = require('elements2');
>s2 : typeof s2
<s1.MyElement />;
><s1.MyElement /> : JSX.Element
>s1 : any
>MyElement : any
=== tests/cases/conformance/jsx/file.tsx ===
declare module JSX {
>JSX : any
interface Element { }
>Element : Element
interface IntrinsicElements { }
>IntrinsicElements : IntrinsicElements
}
declare module 'elements1' {
class MyElement {
>MyElement : MyElement
}
}
declare module 'elements2' {
class MyElement {
>MyElement : MyElement
}
}

View file

@ -0,0 +1,13 @@
tests/cases/conformance/jsx/tsxElementResolution18.tsx(6,1): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists
==== tests/cases/conformance/jsx/tsxElementResolution18.tsx (1 errors) ====
declare module JSX {
interface Element { }
}
// Error under implicit any
<div n='x' />;
~~~~~~~~~~~~~
!!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists

View file

@ -0,0 +1,12 @@
//// [tsxElementResolution18.tsx]
declare module JSX {
interface Element { }
}
// Error under implicit any
<div n='x' />;
//// [tsxElementResolution18.jsx]
// Error under implicit any
<div n='x'/>;

View file

@ -0,0 +1,19 @@
//// [tsxElementResolution2.tsx]
declare module JSX {
interface Element { }
interface IntrinsicElements {
[x: string]: any;
}
}
// OK
<div />;
// OK
<span />;
//// [tsxElementResolution2.jsx]
// OK
<div />;
// OK
<span />;

Some files were not shown because too many files have changed in this diff Show more