diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index efee668a24bd4..7f65ed7d50623 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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 = {}; @@ -156,6 +166,14 @@ namespace ts { } }; + const JsxNames = { + JSX: "JSX", + IntrinsicElements: "IntrinsicElements", + ElementClass: "ElementClass", + ElementAttributesPropertyNameContainer: "ElementAttributesProperty", + Element: "Element" + }; + let subtypeRelation: Map = {}; let assignableRelation: Map = {}; let identityRelation: Map = {}; @@ -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 = expr.parent; + let attrsType = getJsxElementAttributesType(attrib.parent); + if (!attrsType || isTypeAny(attrsType)) { + return undefined; + } + else { + return getTypeOfPropertyOfType(attrsType, attrib.name.text); + } + } + + if (expr.kind === SyntaxKind.JsxSpreadAttribute) { + return getJsxElementAttributesType(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(parent, node); case SyntaxKind.TypeAssertionExpression: - return getTypeFromTypeNode((parent).type); + case SyntaxKind.AsExpression: + return getTypeFromTypeNode((parent).type); case SyntaxKind.BinaryExpression: return getContextualTypeForBinaryOperand(node); case SyntaxKind.PropertyAssignment: @@ -6371,6 +6427,9 @@ namespace ts { return getContextualTypeForSubstitutionExpression(parent.parent, node); case SyntaxKind.ParenthesizedExpression: return getContextualType(parent); + case SyntaxKind.JsxExpression: + case SyntaxKind.JsxSpreadAttribute: + return getContextualTypeForJsxExpression(parent); } return undefined; } @@ -6511,7 +6570,6 @@ namespace ts { let restArrayType = checkExpression((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 (lhs).text === (rhs).text; + } + + return (lhs).right.text === (rhs).right.text && + tagNamesAreEquivalent((lhs).left, (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(child); + break; + case SyntaxKind.JsxElement: + checkJsxElement(child); + break; + case SyntaxKind.JsxSelfClosingElement: + checkJsxSelfClosingElement(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((tagName).text); + } + } + + function checkJsxAttribute(node: JsxAttribute, elementAttributesType: Type, nameTable: Map) { + 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 { + // is sugar for + exprType = booleanType; + } + + if (correspondingPropType) { + checkTypeAssignableTo(exprType, correspondingPropType, node); + } + + nameTable[node.name.text] = true; + return exprType; + } + + function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map) { + 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, (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, (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(node.tagName); + } + else { + valueSymbol = checkQualifiedName(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 , 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(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 = {}; + // 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((node.attributes[i]), targetAttributesType, nameTable); + } + else { + Debug.assert(node.attributes[i].kind === SyntaxKind.JsxSpreadAttribute); + let spreadType = checkJsxSpreadAttribute((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(node); case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(node); - case SyntaxKind.TypeAssertionExpression: - return checkTypeAssertion(node); case SyntaxKind.ParenthesizedExpression: return checkExpression((node).expression, contextualMapper); case SyntaxKind.ClassExpression: @@ -8986,6 +9470,9 @@ namespace ts { return checkFunctionExpressionOrObjectLiteralMethod(node, contextualMapper); case SyntaxKind.TypeOfExpression: return checkTypeOfExpression(node); + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + return checkAssertion(node); case SyntaxKind.DeleteExpression: return checkDeleteExpression(node); case SyntaxKind.VoidExpression: @@ -9004,6 +9491,14 @@ namespace ts { return undefinedType; case SyntaxKind.YieldExpression: return checkYieldExpression(node); + case SyntaxKind.JsxExpression: + return checkJsxExpression(node); + case SyntaxKind.JsxElement: + return checkJsxElement(node); + case SyntaxKind.JsxSelfClosingElement: + return checkJsxSelfClosingElement(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(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, meaning); } + else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) || (entityName.parent.kind === SyntaxKind.JsxSelfClosingElement)) { + return getJsxElementTagSymbol(entityName.parent); + } else if (isExpression(entityName)) { if (nodeIsMissing(entityName)) { // Missing entity name. @@ -12332,6 +12837,9 @@ namespace ts { meaning |= SymbolFlags.Alias; return resolveEntityName(entityName, meaning); } + else if (entityName.parent.kind === SyntaxKind.JsxAttribute) { + return getJsxAttributePropertySymbol(entityName.parent); + } if (entityName.parent.kind === SyntaxKind.TypePredicate) { return resolveEntityName(entityName, /*meaning*/ SymbolFlags.FunctionScopedVariable); @@ -12466,6 +12974,7 @@ namespace ts { return unknownType; } + function getTypeOfExpression(expr: Expression): Type { if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) { expr = 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 && (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,(prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); + checkGrammarForInvalidQuestionMark(prop, (prop).questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); if (name.kind === SyntaxKind.NumericLiteral) { checkGrammarNumericLiteral(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 = {}; + for (let attr of node.attributes) { + if (attr.kind === SyntaxKind.JsxSpreadAttribute) { + continue; + } + + let jsxAttr = (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 && !(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 && + ((node).text === "eval" || (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); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 4e401c5c9b322..35c5bc14c844d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -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(json["files"], s => combinePaths(basePath, s)); } } else { - var exclude = json["exclude"] instanceof Array ? map(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(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); } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ced477eeeec54..7b35c5e0d6587 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -702,9 +702,9 @@ namespace ts { /** * List of supported extensions in order of file resolution precedence. */ - export const supportedExtensions = [".ts", ".d.ts"]; + export const supportedExtensions = [".tsx", ".ts", ".d.ts"]; - const extensionsToRemove = [".d.ts", ".ts", ".js"]; + const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"]; export function removeFileExtension(path: string): string { for (let ext of extensionsToRemove) { if (fileExtensionIs(path, ext)) { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a73fcfc9ed031..ec9c444e9e9cc 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -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." }, }; } \ No newline at end of file diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a6178807de2e6..f0c02e7f34e1a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -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 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c2983594919b5..32123c0a21f77 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -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((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((attrs[i]).expression); + } + else { + Debug.assert(attrs[i].kind === SyntaxKind.JsxAttribute); + if (haveOpenedObjectLiteral) { + write(", "); + } + else { + haveOpenedObjectLiteral = true; + if (i > 0) { + write(", "); + } + write("{"); + } + emitJsxAttribute(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(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 && !((children[i]).expression)) { + continue; + } + + // Don't emit empty strings + if (children[i].kind === SyntaxKind.JsxText) { + let text = getTextToEmit(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((node).openingElement, (node).children); + } + else { + Debug.assert(node.kind === SyntaxKind.JsxSelfClosingElement); + emitJsxElement(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) { + for (let i = 0, n = attribs.length; i < n; i++) { + if (i > 0) { + write(" "); + } + + if (attribs[i].kind === SyntaxKind.JsxSpreadAttribute) { + emitJsxSpreadAttribute(attribs[i]); + } + else { + Debug.assert(attribs[i].kind === SyntaxKind.JsxAttribute); + emitJsxAttribute(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(""); + } + + 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(node); + } + else { + Debug.assert(node.kind === SyntaxKind.JsxSelfClosingElement); + emitJsxOpeningOrSelfClosingElement(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 = (expr).expression; + while (expr.kind === SyntaxKind.TypeAssertionExpression || expr.kind === SyntaxKind.AsExpression) { + expr = (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 = (node).expression; + while (node.kind === SyntaxKind.ParenthesizedExpression || node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression) { + node = (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 = (node.expression).expression; // Make sure we consider all nested cast expressions, e.g.: // (-A).x; - while (operand.kind === SyntaxKind.TypeAssertionExpression) { + while (operand.kind === SyntaxKind.TypeAssertionExpression || operand.kind === SyntaxKind.AsExpression) { operand = (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 && !(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 && (importNode).importClause.namedBindings) { - + let namedBindings = (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 && - (node.parent).body === node && + (node.parent).body === node && compilerOptions.target <= ScriptTarget.ES5) { return false; @@ -5879,6 +6195,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return emitTemplateExpression(node); case SyntaxKind.TemplateSpan: return emitTemplateSpan(node); + case SyntaxKind.JsxElement: + case SyntaxKind.JsxSelfClosingElement: + return emitJsxElement(node); + case SyntaxKind.JsxText: + return emitJsxText(node); + case SyntaxKind.JsxExpression: + return emitJsxExpression(node); case SyntaxKind.QualifiedName: return emitQualifiedName(node); case SyntaxKind.ObjectBindingPattern: @@ -5909,6 +6232,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return emitTaggedTemplateExpression(node); case SyntaxKind.TypeAssertionExpression: return emit((node).expression); + case SyntaxKind.AsExpression: + return emit((node).expression); case SyntaxKind.ParenthesizedExpression: return emitParenExpression(node); case SyntaxKind.FunctionDeclaration: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 2c496b8c60d50..b43345bcbf50a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -162,6 +162,9 @@ namespace ts { return visitNode(cbNode, (node).left) || visitNode(cbNode, (node).operatorToken) || visitNode(cbNode, (node).right); + case SyntaxKind.AsExpression: + return visitNode(cbNode, (node).expression) || + visitNode(cbNode, (node).type); case SyntaxKind.ConditionalExpression: return visitNode(cbNode, (node).condition) || visitNode(cbNode, (node).questionToken) || @@ -319,6 +322,25 @@ namespace ts { return visitNode(cbNode, (node).expression); case SyntaxKind.MissingDeclaration: return visitNodes(cbNodes, node.decorators); + + case SyntaxKind.JsxElement: + return visitNode(cbNode, (node).openingElement) || + visitNodes(cbNodes, (node).children) || + visitNode(cbNode, (node).closingElement); + case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxOpeningElement: + return visitNode(cbNode, (node).tagName) || + visitNodes(cbNodes, (node).attributes); + case SyntaxKind.JsxAttribute: + return visitNode(cbNode, (node).name) || + visitNode(cbNode, (node).initializer); + case SyntaxKind.JsxSpreadAttribute: + return visitNode(cbNode, (node).expression); + case SyntaxKind.JsxExpression: + return visitNode(cbNode, (node).expression); + case SyntaxKind.JsxClosingElement: + return visitNode(cbNode, (node).tagName); + case SyntaxKind.JSDocTypeExpression: return visitNode(cbNode, (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(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 = createNode(SyntaxKind.AsExpression, left.pos); + node.expression = left; + node.type = right; + return finishNode(node); + } + function parsePrefixUnaryExpression() { let node = 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 = 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 opening; + } + } + + function parseJsxText(): JsxText { + let node = 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 { + let result = >[]; + 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 = createNode(SyntaxKind.JsxOpeningElement, fullStart); + } + else { + parseExpected(SyntaxKind.SlashToken); + parseExpected(SyntaxKind.GreaterThanToken); + node = 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 = createNode(SyntaxKind.QualifiedName, elementName.pos); + node.left = elementName; + node.right = parseIdentifierName(); + elementName = finishNode(node); + } + return elementName; + } + + function parseJsxExpression(): JsxExpression { + let node = 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 = 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 = createNode(SyntaxKind.JsxSpreadAttribute); + parseExpected(SyntaxKind.OpenBraceToken); + parseExpected(SyntaxKind.DotDotDotToken); + node.expression = parseExpression(); + parseExpected(SyntaxKind.CloseBraceToken); + return finishNode(node); + } + + function parseJsxClosingElement(): JsxClosingElement { + let node = createNode(SyntaxKind.JsxClosingElement); + parseExpected(SyntaxKind.LessThanSlashToken); + node.tagName = parseJsxElementName(); + parseExpected(SyntaxKind.GreaterThanToken); + return finishNode(node); + } function parseTypeAssertion(): TypeAssertion { let node = 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 diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index bcc31c39002e3..1cae922f082ba 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -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.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(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; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f3f203d4e8652..b2b48ba48b0a5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -48,6 +48,7 @@ namespace ts { SemicolonToken, CommaToken, LessThanToken, + LessThanSlashToken, GreaterThanToken, LessThanEqualsToken, GreaterThanEqualsToken, @@ -217,6 +218,8 @@ namespace ts { ClassExpression, OmittedExpression, ExpressionWithTypeArguments, + AsExpression, + // Misc TemplateSpan, SemicolonClassElement, @@ -265,6 +268,16 @@ namespace ts { // Module references ExternalModuleReference, + //JSX + JsxElement, + JsxSelfClosingElement, + JsxOpeningElement, + JsxText, + JsxClosingElement, + JsxAttribute, + JsxSpreadAttribute, + JsxExpression, + // Clauses CaseClause, DefaultClause, @@ -396,6 +409,17 @@ namespace ts { HasAggregatedChildData = 1 << 8 } + export const enum JsxFlags { + None = 0, + IntrinsicNamedElement = 1 << 0, + IntrinsicIndexedElement = 1 << 1, + ClassElement = 1 << 2, + UnknownElement = 1 << 3, + + IntrinsicElement = IntrinsicNamedElement | IntrinsicIndexedElement + } + + /* @internal */ export const enum RelationComparisonResult { Succeeded = 1, // Should be truthy @@ -799,11 +823,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 ... + export interface JsxElement extends PrimaryExpression { + openingElement: JsxOpeningElement; + children: NodeArray; + closingElement: JsxClosingElement; + } + + /// The opening element of a ... JsxElement + export interface JsxOpeningElement extends Expression { + _openingElementBrand?: any; + tagName: EntityName; + attributes: NodeArray; + } + + /// A JSX expression of the form + export interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement { + _selfClosingElementBrand?: any; + } + + /// Either the opening tag in a ... pair, or the lone in a self-closing form + export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; + + export interface JsxAttribute extends Node { + name: Identifier; + /// JSX attribute initializers are optional; is sugar for + initializer?: Expression; + } + + export interface JsxSpreadAttribute extends Node { + expression: Expression; + } + + export interface JsxClosingElement extends Node { + tagName: EntityName; + } + + export interface JsxExpression extends Expression { + expression?: Expression; + } + + export interface JsxText extends Node { + _jsxTextExpressionBrand: any; + } + + 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; // 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[]; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ce166aa2f3612..750482bc8b09f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -169,13 +169,13 @@ namespace ts { return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end); } - export function getSourceTextOfNodeFromSourceFile(sourceFile: SourceFile, node: Node): string { + export function getSourceTextOfNodeFromSourceFile(sourceFile: SourceFile, node: Node, includeTrivia = false): string { if (nodeIsMissing(node)) { return ""; } let text = sourceFile.text; - return text.substring(skipTrivia(text, node.pos), node.end); + return text.substring(includeTrivia ? node.pos : skipTrivia(text, node.pos), node.end); } export function getTextOfNodeFromSourceText(sourceText: string, node: Node): string { @@ -186,8 +186,8 @@ namespace ts { return sourceText.substring(skipTrivia(sourceText, node.pos), node.end); } - export function getTextOfNode(node: Node): string { - return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node); + export function getTextOfNode(node: Node, includeTrivia = false): string { + return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia); } // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' @@ -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 === (parent).expression; + case SyntaxKind.AsExpression: + return node === (parent).expression; case SyntaxKind.TemplateSpan: return node === (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. diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 21e88b9e41aa4..1b399e1b70635 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -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); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 6a55948815010..bd54d24cf732b 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -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[] = []; diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 269e889704c87..fa8d9d2c59759 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -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))); diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 84d79be5c6ecd..da1327543116a 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -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; diff --git a/src/services/formatting/tokenRange.ts b/src/services/formatting/tokenRange.ts index 3391365f32830..19185cdf78d3f 100644 --- a/src/services/formatting/tokenRange.ts +++ b/src/services/formatting/tokenRange.ts @@ -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]); diff --git a/src/services/services.ts b/src/services/services.ts index e3d9480e062b2..d78ad9d8aa49f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -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; public nameTable: Map; @@ -874,7 +875,7 @@ namespace ts { case SyntaxKind.SetAccessor: case SyntaxKind.TypeLiteral: addDeclaration(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 = (contextToken.parent).expression; - isRightOfDot = true; - } - else if (contextToken && contextToken.kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.QualifiedName) { - node = (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 = (contextToken.parent).expression; + isRightOfDot = true; + } + else if (kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.QualifiedName) { + node = (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); - - 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; + else if (getAncestor(contextToken, SyntaxKind.JsxElement) || getAncestor(contextToken, SyntaxKind.JsxSelfClosingElement)) { + // Go up until we hit either the element or expression + let jsxNode = contextToken; - /// TODO filter meaning based on the current context - let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; - symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); + 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(jsxNode); + } + else { + Debug.assert(jsxNode.kind === SyntaxKind.JsxElement); + // Cursor is inside a JSX element + attrsType = typeChecker.getJsxElementAttributesType((jsxNode).openingElement); + } + symbols = typeChecker.getPropertiesOfType(attrsType); + isMemberCompletion = true; + return true; + } + jsxNode = jsxNode.parent; + } } + // 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)); @@ -5825,7 +5877,7 @@ namespace ts { } function isTypeReference(node: Node): boolean { - if (isRightSideOfQualifiedNameOrPropertyAccess(node) ) { + if (isRightSideOfQualifiedNameOrPropertyAccess(node)) { node = node.parent; } @@ -5994,13 +6046,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)); } @@ -6129,7 +6181,7 @@ namespace ts { return result; } - function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]{ + function getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] { return convertClassifications(getEncodedSyntacticClassifications(fileName, span)); } @@ -6140,8 +6192,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); @@ -6496,14 +6548,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; @@ -6718,6 +6770,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)); } @@ -6946,7 +6999,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: @@ -7001,7 +7054,7 @@ namespace ts { case EndOfLineState.InTemplateMiddleOrTail: text = "}\n" + text; offset = 2; - // fallthrough + // fallthrough case EndOfLineState.InTemplateSubstitutionPosition: templateStack.push(SyntaxKind.TemplateHead); break; @@ -7040,9 +7093,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; @@ -7055,7 +7108,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++; @@ -7066,10 +7119,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, @@ -7305,7 +7358,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. */ diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index 9b2675535f22e..ca7078981f793 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -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; diff --git a/tests/baselines/reference/asOperator1.js b/tests/baselines/reference/asOperator1.js new file mode 100644 index 0000000000000..1b23d0a86f7c9 --- /dev/null +++ b/tests/baselines/reference/asOperator1.js @@ -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 = ''; diff --git a/tests/baselines/reference/asOperator1.symbols b/tests/baselines/reference/asOperator1.symbols new file mode 100644 index 0000000000000..27353ec7b30fa --- /dev/null +++ b/tests/baselines/reference/asOperator1.symbols @@ -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)) + diff --git a/tests/baselines/reference/asOperator1.types b/tests/baselines/reference/asOperator1.types new file mode 100644 index 0000000000000..3f69871ea0942 --- /dev/null +++ b/tests/baselines/reference/asOperator1.types @@ -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 + diff --git a/tests/baselines/reference/asOperator2.errors.txt b/tests/baselines/reference/asOperator2.errors.txt new file mode 100644 index 0000000000000..3b074038c26b0 --- /dev/null +++ b/tests/baselines/reference/asOperator2.errors.txt @@ -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. + \ No newline at end of file diff --git a/tests/baselines/reference/asOperator2.js b/tests/baselines/reference/asOperator2.js new file mode 100644 index 0000000000000..32962555d5107 --- /dev/null +++ b/tests/baselines/reference/asOperator2.js @@ -0,0 +1,6 @@ +//// [asOperator2.ts] +var x = 23 as string; + + +//// [asOperator2.js] +var x = 23; diff --git a/tests/baselines/reference/asOperator3.js b/tests/baselines/reference/asOperator3.js new file mode 100644 index 0000000000000..406eae1c9d68b --- /dev/null +++ b/tests/baselines/reference/asOperator3.js @@ -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; diff --git a/tests/baselines/reference/asOperator3.symbols b/tests/baselines/reference/asOperator3.symbols new file mode 100644 index 0000000000000..d29a64d3c3a51 --- /dev/null +++ b/tests/baselines/reference/asOperator3.symbols @@ -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)) + diff --git a/tests/baselines/reference/asOperator3.types b/tests/baselines/reference/asOperator3.types new file mode 100644 index 0000000000000..507dfd8b5726f --- /dev/null +++ b/tests/baselines/reference/asOperator3.types @@ -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 + diff --git a/tests/baselines/reference/asOperatorASI.js b/tests/baselines/reference/asOperatorASI.js new file mode 100644 index 0000000000000..1df39b36e50f5 --- /dev/null +++ b/tests/baselines/reference/asOperatorASI.js @@ -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; diff --git a/tests/baselines/reference/asOperatorASI.symbols b/tests/baselines/reference/asOperatorASI.symbols new file mode 100644 index 0000000000000..7def6d460c15c --- /dev/null +++ b/tests/baselines/reference/asOperatorASI.symbols @@ -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)) + diff --git a/tests/baselines/reference/asOperatorASI.types b/tests/baselines/reference/asOperatorASI.types new file mode 100644 index 0000000000000..61c2d115cf4f6 --- /dev/null +++ b/tests/baselines/reference/asOperatorASI.types @@ -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 + diff --git a/tests/baselines/reference/asOperatorAmbiguity.errors.txt b/tests/baselines/reference/asOperatorAmbiguity.errors.txt new file mode 100644 index 0000000000000..cb7c6d4132c18 --- /dev/null +++ b/tests/baselines/reference/asOperatorAmbiguity.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/expressions/asOperator/asOperatorAmbiguity.ts(7,14): error TS2339: Property 'm' does not exist on type 'A'. + + +==== tests/cases/conformance/expressions/asOperator/asOperatorAmbiguity.ts (1 errors) ==== + interface A { 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[]; + var z = y[0].m; // z should be string + ~ +!!! error TS2339: Property 'm' does not exist on type 'A'. + + \ No newline at end of file diff --git a/tests/baselines/reference/asOperatorAmbiguity.js b/tests/baselines/reference/asOperatorAmbiguity.js new file mode 100644 index 0000000000000..6c336970b65fe --- /dev/null +++ b/tests/baselines/reference/asOperatorAmbiguity.js @@ -0,0 +1,16 @@ +//// [asOperatorAmbiguity.ts] +interface A { 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[]; +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 diff --git a/tests/baselines/reference/asOperatorContextualType.errors.txt b/tests/baselines/reference/asOperatorContextualType.errors.txt new file mode 100644 index 0000000000000..c53b407b5cf02 --- /dev/null +++ b/tests/baselines/reference/asOperatorContextualType.errors.txt @@ -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'. \ No newline at end of file diff --git a/tests/baselines/reference/asOperatorContextualType.js b/tests/baselines/reference/asOperatorContextualType.js new file mode 100644 index 0000000000000..7b495ada8f403 --- /dev/null +++ b/tests/baselines/reference/asOperatorContextualType.js @@ -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; }); diff --git a/tests/baselines/reference/asOperatorNames.errors.txt b/tests/baselines/reference/asOperatorNames.errors.txt new file mode 100644 index 0000000000000..e3dfaab98845b --- /dev/null +++ b/tests/baselines/reference/asOperatorNames.errors.txt @@ -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; + \ No newline at end of file diff --git a/tests/baselines/reference/asOperatorNames.js b/tests/baselines/reference/asOperatorNames.js new file mode 100644 index 0000000000000..35e80d080e334 --- /dev/null +++ b/tests/baselines/reference/asOperatorNames.js @@ -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; diff --git a/tests/baselines/reference/jsxAndTypeAssertion.errors.txt b/tests/baselines/reference/jsxAndTypeAssertion.errors.txt new file mode 100644 index 0000000000000..aebabf15133e8 --- /dev/null +++ b/tests/baselines/reference/jsxAndTypeAssertion.errors.txt @@ -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 = { test: }; + ~~~~ +!!! error TS2304: Cannot find name 'test'. + ~ +!!! error TS1005: '}' expected. + + x = ; + + x = hello {{}} ; + ~ +!!! error TS1005: '}' expected. + + x = {}}>hello; + ~ +!!! error TS1005: '}' expected. + + x = {}}>hello{{}}; + ~ +!!! error TS1005: '}' expected. + + x = x, x = ; + + {{/foo/.test(x) ? : }} + + + + +!!! error TS1005: ':' expected. + +!!! error TS17002: Expected corresponding JSX closing tag for 'any'. + +!!! error TS17002: Expected corresponding JSX closing tag for 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/jsxAndTypeAssertion.js b/tests/baselines/reference/jsxAndTypeAssertion.js new file mode 100644 index 0000000000000..0b402b43de2e4 --- /dev/null +++ b/tests/baselines/reference/jsxAndTypeAssertion.js @@ -0,0 +1,49 @@ +//// [jsxAndTypeAssertion.tsx] + +declare var createElement: any; + +class foo {} + +var x: any; +x = { test: }; + +x = ; + +x = hello {{}} ; + +x = {}}>hello; + +x = {}}>hello{{}}; + +x = x, x = ; + +{{/foo/.test(x) ? : }} + + + + +//// [jsxAndTypeAssertion.jsx] +var foo = (function () { + function foo() { + } + return foo; +})(); +var x; +x = {test}: }; + +x = ; + +x = hello {} }; + +x = }>hello}/>; + +x = }>hello{}}; + +x = x, x = ; + +{{/foo/.test(x) ? : }} + : +} + + +}}/>; diff --git a/tests/baselines/reference/jsxEsprimaFbTestSuite.errors.txt b/tests/baselines/reference/jsxEsprimaFbTestSuite.errors.txt new file mode 100644 index 0000000000000..5758db369600a --- /dev/null +++ b/tests/baselines/reference/jsxEsprimaFbTestSuite.errors.txt @@ -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; + + ; + + //; Namespace unsuported + + // {value} ; Namespace unsuported + + ; + + ; + ; + + <日本語>; + + + bar + baz + ; + + : } />; + + {}; + + {/* this is a comment */}; + +
@test content
; + +

7x invalid-js-identifier
; + + right=monkeys /> gorillas />; + ~ +!!! error TS1005: '{' expected. + ~~~~~ +!!! error TS1005: '}' expected. + ~ +!!! error TS1005: '{' expected. + ~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1109: Expression expected. + + ; + ~ +!!! error TS1003: Identifier expected. + ~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1109: Expression expected. + + ; + + (
) < x; + +
; + +
; + +
; + + ; + \ No newline at end of file diff --git a/tests/baselines/reference/jsxEsprimaFbTestSuite.js b/tests/baselines/reference/jsxEsprimaFbTestSuite.js new file mode 100644 index 0000000000000..1e22826f44068 --- /dev/null +++ b/tests/baselines/reference/jsxEsprimaFbTestSuite.js @@ -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; + +; + +//; Namespace unsuported + +// {value} ; Namespace unsuported + +; + +; +; + +<日本語>; + + +bar +baz +; + + : } />; + +{}; + +{/* this is a comment */}; + +
@test content
; + +

7x invalid-js-identifier
; + + right=monkeys /> gorillas />; + +; + +; + +(
) < x; + +
; + +
; + +
; + + ; + + +//// [jsxEsprimaFbTestSuite.jsx] +; +//; Namespace unsuported +// {value} ; Namespace unsuported +; +; +; +<日本語>; + +bar +baz +; + : }/>; +; +; +
@test content
; +

7x invalid-js-identifier
; +} right={monkeys /> gorillas / > }/> + < a.b > ; +a.b > ; +; +(
) < x; +
; +
; +
; + ; diff --git a/tests/baselines/reference/jsxEsprimaFbTestSuite.symbols b/tests/baselines/reference/jsxEsprimaFbTestSuite.symbols new file mode 100644 index 0000000000000..570bf89f0a4c2 --- /dev/null +++ b/tests/baselines/reference/jsxEsprimaFbTestSuite.symbols @@ -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)) + +; + +//; Namespace unsuported + +// {value} ; Namespace unsuported + +; +>b : Symbol(unknown) +>c : Symbol(unknown) +>d : Symbol(unknown) +>e : Symbol(unknown) +>f : Symbol(unknown) +>g : Symbol(unknown) +>h : Symbol(unknown) + +; +>b : Symbol(unknown) + +; + +<日本語>; + +AbC_def : Symbol(AbC_def, Decl(jsxEsprimaFbTestSuite.tsx, 2, 11)) + + test="&&"> +>test : Symbol(unknown) + +bar +baz +; + + : } />; +>b : Symbol(unknown) +>x : Symbol(x, Decl(jsxEsprimaFbTestSuite.tsx, 4, 11)) + +{}; + +{/* this is a comment */}; + +
@test content
; + +

7x invalid-js-identifier
; + + right=monkeys /> gorillas />; +>LeftRight : Symbol(LeftRight, Decl(jsxEsprimaFbTestSuite.tsx, 3, 11)) +>left : Symbol(unknown) +>right : Symbol(unknown) + +; +>b : Symbol(unknown) + +; +>c : Symbol(unknown) + +(
) < x; +>x : Symbol(x, Decl(jsxEsprimaFbTestSuite.tsx, 4, 11)) + +
; + +
; +>post : Symbol(unknown) + +
; +>pre : Symbol(unknown) +>pre2 : Symbol(unknown) + + ; + diff --git a/tests/baselines/reference/jsxEsprimaFbTestSuite.types b/tests/baselines/reference/jsxEsprimaFbTestSuite.types new file mode 100644 index 0000000000000..f32d62fd03f66 --- /dev/null +++ b/tests/baselines/reference/jsxEsprimaFbTestSuite.types @@ -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 + +; +> : any +>a : any + +//; Namespace unsuported + +// {value} ; Namespace unsuported + +; +> : any +>a : any +>b : any +>c : any +>d : any +>e : any +>f : any +>g : any +>h : any + +; +> : any +>a : any +>b : any + + : any +>a : any + +/>; + +<日本語>; +><日本語> : any +>日本語 : any +>日本語 : any + +barbaz : any +>AbC_def : any + + test="&&"> +>test : any + +bar +baz +; +>AbC_def : any + + : } />; +> : } /> : any +>a : any +>b : any +>x ? : : any +>x : any +> : any +>c : any +> : any +>d : any + +{}; +>{} : any +>a : any +>a : any + +{/* this is a comment */}; +>{/* this is a comment */} : any +>a : any +>a : any + +
@test content
; +>
@test content
: any +>div : any +>div : any + +

7x invalid-js-identifier
; +>

7x invalid-js-identifier
: any +>div : any +>
: any +>br : any +>div : any + + right=monkeys /> gorillas />; +> right=monkeys /> gorillas /> : any +>LeftRight : any +>left : any +> : any +>a : any +>right : any +>monkeys /> gorillas : any +>b : any +>b : any + +; +> : any +>a : any +>b : any +>a : any +>b : any + +; +> : any +>a : any +>b : any +>c : any +>a : any +>b : any +>c : any + +(
) < x; +>(
) < x : boolean +>(
) : any +>
: any +>div : any +>x : any + +
; +>
: any +>div : any +>props : any + +
; +>
: any +>div : any +>props : any +>post : any + +
; +>
: any +>div : any +>pre : any +>pre2 : any +>props : any +>div : any + + ; +>
: any +>a : any +>a : any + diff --git a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.errors.txt b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.errors.txt new file mode 100644 index 0000000000000..3e2a10e993154 --- /dev/null +++ b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.errors.txt @@ -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. + ; + ~ +!!! 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. + ; + ~ +!!! error TS1005: '{' expected. + ~ +!!! error TS2304: Cannot find name 'd'. + ~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1109: Expression expected. + ; + ~ +!!! error TS1003: Identifier expected. + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS1109: Expression expected. + ; + ~~~~ +!!! error TS17002: Expected corresponding JSX closing tag for 'a'. + ; + ~ +!!! error TS1005: '}' expected. + ; + ~ +!!! error TS1003: Identifier expected. +
; + ~~~~~ +!!! error TS1003: Identifier expected. +
; + ~~~~~ +!!! error TS1005: '...' expected. + ~~~~~ +!!! error TS2304: Cannot find name 'props'. + +
stuff
; + ~ +!!! error TS1005: '>' expected. + ~~~ +!!! error TS1109: Expression expected. +
stuff
; + ~~~~~ +!!! error TS2304: Cannot find name 'props'. + ~ +!!! error TS1005: '>' expected. + ~~~ +!!! error TS1109: Expression expected. + +
>; + >; + ; + ~ +!!! error TS1005: '{' expected. + ; + ~ +!!! error TS1005: '{' expected. + ~ +!!! error TS1109: Expression expected. + }; + ; + ~~~ +!!! error TS1003: Identifier expected. + +!!! error TS17002: Expected corresponding JSX closing tag for 'a'. \ No newline at end of file diff --git a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js new file mode 100644 index 0000000000000..13808cc29e0ed --- /dev/null +++ b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.js @@ -0,0 +1,81 @@ +//// [jsxInvalidEsprimaTestSuite.tsx] +declare var React: any; + +; +; +<:a />; +; +; +; +; +; +
; +
; + +
stuff
; +
stuff
; + +
>; + >; +; +; +}; +; + +//// [jsxInvalidEsprimaTestSuite.jsx] + > ; +; + < ; +a / > ; + }/> + < a > ; +; +; +, id="b" />; +
"app">; +
; + +
stuff
{}...props}>; +
stuff
{}...props}>; + +
>; + >; +; +; +}; + .../*hai*/asdf/>;; diff --git a/tests/baselines/reference/jsxReactTestSuite.js b/tests/baselines/reference/jsxReactTestSuite.js new file mode 100644 index 0000000000000..300274a161465 --- /dev/null +++ b/tests/baselines/reference/jsxReactTestSuite.js @@ -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; + +
text
; + +
+ {this.props.children} +
; + +
+

+ {foo}
{bar}
+
+
; + + + + {this.props.children} +; + + + +; + +var x = +
+
; + +( +
+ {/* A comment at the beginning */} + {/* A second comment at the beginning */} + + {/* A nested comment */} + + {/* A sandwiched comment */} +
+ {/* A comment at the end */} + {/* A second comment at the end */} +
+); + +( +
+ +
+); + +
 
; + +
 
; + +testing; + +; + +; + +; + +; + +; + +; + +; + +; + +; + +; + +; + +; + + +; + +Text; + + + + +//// [jsxReactTestSuite.jsx] +
text
; +
+ {this.props.children} +
; +
+

+ {foo}
{bar}
+
+
; + + {this.props.children} +; + + +; +var x =
+
; +(
+ + + + + + +
+ + +
); +(
+ +
); +
 
; +
 
; +testing; +; +; +; +; +; +; +; +; +; +; +; +; +; +Text; diff --git a/tests/baselines/reference/jsxReactTestSuite.symbols b/tests/baselines/reference/jsxReactTestSuite.symbols new file mode 100644 index 0000000000000..9e382742f0d4b --- /dev/null +++ b/tests/baselines/reference/jsxReactTestSuite.symbols @@ -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)) + +
text
; + +
+ {this.props.children} +
; + +
+

+ {foo}
{bar}
+>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) + +
+
; + + + +>Composite : Symbol(Composite, Decl(jsxReactTestSuite.tsx, 3, 11)) + + {this.props.children} +; + + +>Composite : Symbol(Composite, Decl(jsxReactTestSuite.tsx, 3, 11)) + + +>Composite2 : Symbol(Composite2, Decl(jsxReactTestSuite.tsx, 4, 11)) + +; + +var x = +>x : Symbol(x, Decl(jsxReactTestSuite.tsx, 10, 11), Decl(jsxReactTestSuite.tsx, 35, 3)) + +
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) + +
; + +( +
+ {/* A comment at the beginning */} + {/* A second comment at the beginning */} + + {/* A nested comment */} + + {/* A sandwiched comment */} +
+ {/* A comment at the end */} + {/* A second comment at the end */} +
+); + +( +
+>attr1 : Symbol(unknown) + + attr2 : Symbol(unknown) + + /> +
+); + +
 
; + +
 
; + +testing; + +; +>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) +>constructor : Symbol(unknown) + +; +>Component : Symbol(unknown) + +; +>Component : Symbol(unknown) + +Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) +>y : Symbol(unknown) + +={2 } z />; +>z : Symbol(unknown) + +Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) + + {...this.props} sound="moo" />; +>sound : Symbol(unknown) + +; + +; +>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) +>x : Symbol(unknown) + +; + +; +>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) + +; +>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) +>y : Symbol(unknown) + +; +>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) +>y : Symbol(unknown) +>z : Symbol(unknown) + +; +>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) +>x : Symbol(unknown) + + +; +>Component : Symbol(Component, Decl(jsxReactTestSuite.tsx, 2, 11)) +>x : Symbol(unknown) +>y : Symbol(unknown) +>Child : Symbol(Child, Decl(jsxReactTestSuite.tsx, 5, 11)) + +Text; +>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) + + + diff --git a/tests/baselines/reference/jsxReactTestSuite.types b/tests/baselines/reference/jsxReactTestSuite.types new file mode 100644 index 0000000000000..db7ebf8d912dc --- /dev/null +++ b/tests/baselines/reference/jsxReactTestSuite.types @@ -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 + +
text
; +>
text
: any +>div : any +>div : any + +
+>
{this.props.children}
: any +>div : any + + {this.props.children} +>this.props.children : any +>this.props : any +>this : any +>props : any +>children : any + +
; +>div : any + +
+>

{foo}
{bar}

: any +>div : any + +

+>

: any +>div : any +>
: any +>br : any +>div : any + + {foo}
{bar}
+>{foo}
{bar}
: any +>Component : any +>foo : any +>
: any +>br : any +>bar : any +>Component : any + +
+>
: any +>br : any + +
; +>div : any + + + +> {this.props.children} : any +>Composite : any + + {this.props.children} +>this.props.children : any +>this.props : any +>this : any +>props : any +>children : any + +; +>Composite : any + + +> : any +>Composite : any + + +> : any +>Composite2 : any + +; +>Composite : any + +var x = +>x : any + +
: 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 : any + +( +>(
{/* A comment at the beginning */} {/* A second comment at the beginning */} {/* A nested comment */} {/* A sandwiched comment */}
{/* A comment at the end */} {/* A second comment at the end */}
) : any + +
+>
{/* A comment at the beginning */} {/* A second comment at the beginning */} {/* A nested comment */} {/* A sandwiched comment */}
{/* A comment at the end */} {/* A second comment at the end */}
: any +>div : any + + {/* A comment at the beginning */} + {/* A second comment at the beginning */} + +> {/* A nested comment */} : any +>span : any + + {/* A nested comment */} + +>span : any + + {/* A sandwiched comment */} +
+>
: any +>br : any + + {/* A comment at the end */} + {/* A second comment at the end */} +
+>div : any + +); + +( +>(
) : any + +
: any +>div : any + + /* a multi-line + comment */ + attr1="foo"> +>attr1 : any + + : any +>span : any + + attr2="bar" +>attr2 : any + + /> +
+>div : any + +); + +
 
; +>
 
: any +>div : any +>div : any + +
 
; +>
 
: any +>div : any +>div : any + +testing; +>testing : any +>hasOwnProperty : any +>hasOwnProperty : any + +; +> : any +>Component : any +>constructor : any + +; +> : any +>Namespace : any +>Component : any + +; +> : any +>Namespace : any +>DeepNamespace : any +>Component : any + + : any +>Component : any +>x : any +>y : any + +={2 } z />; +>z : any + + : any +>Component : any + + {...this.props} sound="moo" />; +>this.props : any +>this : any +>props : any +>sound : any + +; +> : any +>font-face : any + +; +> : any +>Component : any +>x : any +>y : any + +; +> : any +>x-component : any + +; +> : any +>Component : any +>x : any + +; +> : any +>Component : any +>x : any +>y : any + +; +> : any +>Component : any +>x : any +>y : any +>z : any + +; +> : any +>Component : any +>x : any +>y : any + + +; +> : any +>Component : any +>x : any +>y : any +>z : any +>z : any +> : any +>Child : any +>Component : any + +Text; +>Text : 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 + + + diff --git a/tests/baselines/reference/project/invalidRootFile/amd/invalidRootFile.errors.txt b/tests/baselines/reference/project/invalidRootFile/amd/invalidRootFile.errors.txt index 656b6e1f2a2a1..bafcc39f48d33 100644 --- a/tests/baselines/reference/project/invalidRootFile/amd/invalidRootFile.errors.txt +++ b/tests/baselines/reference/project/invalidRootFile/amd/invalidRootFile.errors.txt @@ -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'. \ No newline at end of file +!!! error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.tsx', '.ts', '.d.ts'. \ No newline at end of file diff --git a/tests/baselines/reference/project/invalidRootFile/node/invalidRootFile.errors.txt b/tests/baselines/reference/project/invalidRootFile/node/invalidRootFile.errors.txt index 656b6e1f2a2a1..bafcc39f48d33 100644 --- a/tests/baselines/reference/project/invalidRootFile/node/invalidRootFile.errors.txt +++ b/tests/baselines/reference/project/invalidRootFile/node/invalidRootFile.errors.txt @@ -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'. \ No newline at end of file +!!! error TS6054: File 'a.t' has unsupported extension. The only supported extensions are '.tsx', '.ts', '.d.ts'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeErrors.errors.txt b/tests/baselines/reference/tsxAttributeErrors.errors.txt new file mode 100644 index 0000000000000..30a897c5163b1 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeErrors.errors.txt @@ -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 +
; + ~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + + // Error, string is not assignable to number +
; + ~~~~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + + // Error, number is not assignable to string + var attribs = { text: 100 }; +
; + ~~~~~~~~~~~~ +!!! 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 + ; + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeErrors.js b/tests/baselines/reference/tsxAttributeErrors.js new file mode 100644 index 0000000000000..2ab862e0efec9 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeErrors.js @@ -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 +
; + +// Error, string is not assignable to number +
; + +// Error, number is not assignable to string +var attribs = { text: 100 }; +
; + +// No errors here +; + + +//// [tsxAttributeErrors.jsx] +// Error, number is not assignable to string +
; +// Error, string is not assignable to number +
; +// Error, number is not assignable to string +var attribs = { text: 100 }; +
; +// No errors here +; diff --git a/tests/baselines/reference/tsxAttributeInvalidNames.errors.txt b/tests/baselines/reference/tsxAttributeInvalidNames.errors.txt new file mode 100644 index 0000000000000..90d0d003c28d6 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeInvalidNames.errors.txt @@ -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 + ; + ~~ +!!! 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. + ; + ~~~~~~ +!!! 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. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeInvalidNames.js b/tests/baselines/reference/tsxAttributeInvalidNames.js new file mode 100644 index 0000000000000..af1de76995c00 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeInvalidNames.js @@ -0,0 +1,23 @@ +//// [tsxAttributeInvalidNames.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: { "data-foo"?: string }; + test2: { "data-foo"?: string }; + } +} + +// Invalid names +; +; + +//// [tsxAttributeInvalidNames.jsx] +// Invalid names +; +32; +data = { 32: } / > ; + - data; +{ + 32; +} +/>;; diff --git a/tests/baselines/reference/tsxAttributeResolution.js b/tests/baselines/reference/tsxAttributeResolution.js new file mode 100644 index 0000000000000..ed3915b7ff2b1 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution.js @@ -0,0 +1,12 @@ +//// [tsxAttributeResolution.tsx] + +declare namespace JSX { + interface IntrinsicElements { + x: { y: number; z: string; }; + } +} + + + + +//// [tsxAttributeResolution.jsx] diff --git a/tests/baselines/reference/tsxAttributeResolution.symbols b/tests/baselines/reference/tsxAttributeResolution.symbols new file mode 100644 index 0000000000000..a40be3861b34e --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution.symbols @@ -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)) + } +} + + + diff --git a/tests/baselines/reference/tsxAttributeResolution.types b/tests/baselines/reference/tsxAttributeResolution.types new file mode 100644 index 0000000000000..f0adc582944b2 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution.types @@ -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 + } +} + + + diff --git a/tests/baselines/reference/tsxAttributeResolution1.errors.txt b/tests/baselines/reference/tsxAttributeResolution1.errors.txt new file mode 100644 index 0000000000000..54666f46abac9 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution1.errors.txt @@ -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 + ; // OK + ; // OK + ; // OK + + ; // OK + ; // OK + + // Errors + ; // Error, '0' is not number + ~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + ; // Error, no property "y" + ~ +!!! error TS2339: Property 'y' does not exist on type 'Attribs1'. + ; // Error, no property "y" + ~ +!!! error TS2339: Property 'y' does not exist on type 'Attribs1'. + ; // Error, "32" is not number + ~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + // TODO attribute 'var' should be parseable + // ; // Error, no 'var' property + + ; // Error, missing reqd + ~~~~~~~~~ +!!! error TS2324: Property 'reqd' is missing in type '{ reqd: string; }'. + ; // Error, reqd is not string + ~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution1.js b/tests/baselines/reference/tsxAttributeResolution1.js new file mode 100644 index 0000000000000..011ac8034e2ce --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution1.js @@ -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 +; // OK +; // OK +; // OK + +; // OK +; // OK + +// Errors +; // Error, '0' is not number +; // Error, no property "y" +; // Error, no property "y" +; // Error, "32" is not number +// TODO attribute 'var' should be parseable +// ; // Error, no 'var' property + +; // Error, missing reqd +; // Error, reqd is not string + + + +//// [tsxAttributeResolution1.jsx] +// OK +; // OK +; // OK +; // OK +; // OK +; // OK +// Errors +; // Error, '0' is not number +; // Error, no property "y" +; // Error, no property "y" +; // Error, "32" is not number +// TODO attribute 'var' should be parseable +// ; // Error, no 'var' property +; // Error, missing reqd +; // Error, reqd is not string diff --git a/tests/baselines/reference/tsxAttributeResolution2.errors.txt b/tests/baselines/reference/tsxAttributeResolution2.errors.txt new file mode 100644 index 0000000000000..d213ccaf54eb5 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution2.errors.txt @@ -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 + x.length} />; // OK + x.leng} />; // OK + + + // Errors + x.leng} />; // Error, no leng on 'string' + ~~~~ +!!! error TS2339: Property 'leng' does not exist on type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution2.js b/tests/baselines/reference/tsxAttributeResolution2.js new file mode 100644 index 0000000000000..564767e6169b5 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution2.js @@ -0,0 +1,26 @@ +//// [tsxAttributeResolution2.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: Attribs1; + } +} +interface Attribs1 { + c1?: (x: string) => void; +} + +// OK + x.length} />; // OK + x.leng} />; // OK + + +// Errors + x.leng} />; // Error, no leng on 'string' + + +//// [tsxAttributeResolution2.jsx] +// OK +; // OK +; // OK +// Errors +; // Error, no leng on 'string' diff --git a/tests/baselines/reference/tsxAttributeResolution3.errors.txt b/tests/baselines/reference/tsxAttributeResolution3.errors.txt new file mode 100644 index 0000000000000..c797362e8d770 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution3.errors.txt @@ -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' }; + + + // Error, x is not string + var obj2 = { x: 32 }; + + ~~~~~~~~~ +!!! 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 }; + + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2324: Property 'x' is missing in type 'Attribs1'. + + // OK + var obj4 = { x: 32, y: 32 }; + + + // Error + var obj5 = { x: 32, y: 32 }; + + ~~~~~~~~~ +!!! 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 }; + + + // Error + var obj7 = { x: 'foo' }; + + ~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution3.js b/tests/baselines/reference/tsxAttributeResolution3.js new file mode 100644 index 0000000000000..8cf853820e19a --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution3.js @@ -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' }; + + +// Error, x is not string +var obj2 = { x: 32 }; + + +// Error, x is missing +var obj3 = { y: 32 }; + + +// OK +var obj4 = { x: 32, y: 32 }; + + +// Error +var obj5 = { x: 32, y: 32 }; + + +// OK +var obj6 = { x: 'ok', y: 32, extra: 100 }; + + +// Error +var obj7 = { x: 'foo' }; + + + +//// [tsxAttributeResolution3.jsx] +// OK +var obj1 = { x: 'foo' }; +; +// Error, x is not string +var obj2 = { x: 32 }; +; +// Error, x is missing +var obj3 = { y: 32 }; +; +// OK +var obj4 = { x: 32, y: 32 }; +; +// Error +var obj5 = { x: 32, y: 32 }; +; +// OK +var obj6 = { x: 'ok', y: 32, extra: 100 }; +; +// Error +var obj7 = { x: 'foo' }; +; diff --git a/tests/baselines/reference/tsxAttributeResolution4.errors.txt b/tests/baselines/reference/tsxAttributeResolution4.errors.txt new file mode 100644 index 0000000000000..211a349b30456 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution4.errors.txt @@ -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 + 0} } />; + + // Error, no member 'len' on 'string' + n.len} } />; + ~~~ +!!! error TS2339: Property 'len' does not exist on type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution4.js b/tests/baselines/reference/tsxAttributeResolution4.js new file mode 100644 index 0000000000000..d56cb4cc2e808 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution4.js @@ -0,0 +1,23 @@ +//// [tsxAttributeResolution4.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: Attribs1; + } +} +interface Attribs1 { + x(n: string): void; +} + +// OK + 0} } />; + +// Error, no member 'len' on 'string' + n.len} } />; + + +//// [tsxAttributeResolution4.jsx] +// OK +; +// Error, no member 'len' on 'string' +; diff --git a/tests/baselines/reference/tsxAttributeResolution5.errors.txt b/tests/baselines/reference/tsxAttributeResolution5.errors.txt new file mode 100644 index 0000000000000..1b42dd014655d --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution5.errors.txt @@ -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 (obj: T) { + return ; // OK + } + + function make2 (obj: T) { + return ; // 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 (obj: T) { + return ; // Error, missing x + ~~~~~~~~~~~~~~~~~~ +!!! error TS2324: Property 'x' is missing in type 'Attribs1'. + } + + + ; // Error, missing x + ~~~~~~~~~~~~~~~~~ +!!! error TS2324: Property 'x' is missing in type 'Attribs1'. + ; // OK + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution5.js b/tests/baselines/reference/tsxAttributeResolution5.js new file mode 100644 index 0000000000000..34fe9a3bfb6c7 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution5.js @@ -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 (obj: T) { + return ; // OK +} + +function make2 (obj: T) { + return ; // Error (x is number, not string) +} + +function make3 (obj: T) { + return ; // Error, missing x +} + + +; // Error, missing x +; // OK + + +//// [tsxAttributeResolution5.jsx] +function make1(obj) { + return ; // OK +} +function make2(obj) { + return ; // Error (x is number, not string) +} +function make3(obj) { + return ; // Error, missing x +} +; // Error, missing x +; // OK diff --git a/tests/baselines/reference/tsxAttributeResolution6.errors.txt b/tests/baselines/reference/tsxAttributeResolution6.errors.txt new file mode 100644 index 0000000000000..4f1960358a560 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution6.errors.txt @@ -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 + ; + ~ +!!! error TS2322: Type 'boolean' is not assignable to type 'string'. + ; + ~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. + ; + ~~~~~~~~~ +!!! error TS2324: Property 'n' is missing in type '{ n: boolean; }'. + + // OK + ; + ; + ; + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution6.js b/tests/baselines/reference/tsxAttributeResolution6.js new file mode 100644 index 0000000000000..f4af0ba875acb --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution6.js @@ -0,0 +1,29 @@ +//// [tsxAttributeResolution6.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: { n?: boolean; s?: string}; + test2: { n: boolean; }; + } +} + +// Error +; +; +; + +// OK +; +; +; + + +//// [tsxAttributeResolution6.jsx] +// Error +; +; +; +// OK +; +; +; diff --git a/tests/baselines/reference/tsxAttributeResolution7.errors.txt b/tests/baselines/reference/tsxAttributeResolution7.errors.txt new file mode 100644 index 0000000000000..4d05254ace8d5 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution7.errors.txt @@ -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 + ; + ~~~~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + + // OK + ; + ; + ; + \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution7.js b/tests/baselines/reference/tsxAttributeResolution7.js new file mode 100644 index 0000000000000..7ebd2e8f4db8a --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution7.js @@ -0,0 +1,24 @@ +//// [tsxAttributeResolution7.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: { "data-foo"?: string }; + } +} + +// Error +; + +// OK +; +; +; + + +//// [tsxAttributeResolution7.jsx] +// Error +; +// OK +; +; +; diff --git a/tests/baselines/reference/tsxAttributeResolution8.js b/tests/baselines/reference/tsxAttributeResolution8.js new file mode 100644 index 0000000000000..50fff6c80fddc --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution8.js @@ -0,0 +1,16 @@ +//// [tsxAttributeResolution8.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: {x: string}; + } +} + +var x: any; +// Should be OK + + +//// [tsxAttributeResolution8.jsx] +var x; +// Should be OK +; diff --git a/tests/baselines/reference/tsxAttributeResolution8.symbols b/tests/baselines/reference/tsxAttributeResolution8.symbols new file mode 100644 index 0000000000000..9bb09c6cd85e4 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution8.symbols @@ -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 : Symbol(JSX.IntrinsicElements.test1, Decl(tsxAttributeResolution8.tsx, 2, 30)) + diff --git a/tests/baselines/reference/tsxAttributeResolution8.types b/tests/baselines/reference/tsxAttributeResolution8.types new file mode 100644 index 0000000000000..db89d6678b669 --- /dev/null +++ b/tests/baselines/reference/tsxAttributeResolution8.types @@ -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 + +> : JSX.Element +>test1 : any +>x : any + diff --git a/tests/baselines/reference/tsxElementResolution.js b/tests/baselines/reference/tsxElementResolution.js new file mode 100644 index 0000000000000..e7a4ae95e9479 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution.js @@ -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 = ; +var b = ; +// TODO: This should not be a parse error (should +// parse a property name here, not identifier) +// var c = ; +var d = ; +var e = ; + + +//// [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 = ; +var b = ; +// TODO: This should not be a parse error (should +// parse a property name here, not identifier) +// var c = ; +var d = ; +var e = ; diff --git a/tests/baselines/reference/tsxElementResolution.symbols b/tests/baselines/reference/tsxElementResolution.symbols new file mode 100644 index 0000000000000..4cdd0c23cf16d --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution.symbols @@ -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 = ; +>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 = ; +>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 d = ; +>d : Symbol(d, Decl(tsxElementResolution.tsx, 22, 3)) +>Other : Symbol(Other, Decl(tsxElementResolution.tsx, 9, 20)) + +var e = ; +>e : Symbol(e, Decl(tsxElementResolution.tsx, 23, 3)) +>Name : Symbol(Dotted.Name, Decl(tsxElementResolution.tsx, 12, 15)) + diff --git a/tests/baselines/reference/tsxElementResolution.types b/tests/baselines/reference/tsxElementResolution.types new file mode 100644 index 0000000000000..89600bbbc2f34 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution.types @@ -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 = ; +>a : any +> : any +>foundFirst : typeof foundFirst +>x : any + +var b = ; +>b : any +> : any +>string_named : any + +// TODO: This should not be a parse error (should +// parse a property name here, not identifier) +// var c = ; +var d = ; +>d : any +> : any +>Other : typeof Other + +var e = ; +>e : any +> : any +>Dotted : any +>Name : any + diff --git a/tests/baselines/reference/tsxElementResolution1.errors.txt b/tests/baselines/reference/tsxElementResolution1.errors.txt new file mode 100644 index 0000000000000..b54430bd106c8 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution1.errors.txt @@ -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 +
; + + // Fail + ; + ~~~~~~~~ +!!! error TS2339: Property 'span' does not exist on type 'JSX.IntrinsicElements'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution1.js b/tests/baselines/reference/tsxElementResolution1.js new file mode 100644 index 0000000000000..c7e0536bde28e --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution1.js @@ -0,0 +1,19 @@ +//// [tsxElementResolution1.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + div: any + } +} + +// OK +
; + +// Fail +; + +//// [tsxElementResolution1.jsx] +// OK +
; +// Fail +; diff --git a/tests/baselines/reference/tsxElementResolution10.errors.txt b/tests/baselines/reference/tsxElementResolution10.errors.txt new file mode 100644 index 0000000000000..6dcee7d18fa8d --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution10.errors.txt @@ -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; + ; // 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; + ; // OK + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution10.js b/tests/baselines/reference/tsxElementResolution10.js new file mode 100644 index 0000000000000..84c8619ab9635 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution10.js @@ -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; +; // Error, no render member + +interface Obj2type { + (n: string): { x: number; render: any; }; +} +var Obj2: Obj2type; +; // OK + + +//// [tsxElementResolution10.jsx] +var Obj1; +; // Error, no render member +var Obj2; +; // OK diff --git a/tests/baselines/reference/tsxElementResolution11.errors.txt b/tests/baselines/reference/tsxElementResolution11.errors.txt new file mode 100644 index 0000000000000..4f3ee00d82f00 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution11.errors.txt @@ -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; + ; // OK + + interface Obj2type { + new(n: string): { q?: number }; + } + var Obj2: Obj2type; + ; // Error + ~ +!!! error TS2339: Property 'x' does not exist on type '{ q?: number; }'. + + interface Obj3type { + new(n: string): { x: number; }; + } + var Obj3: Obj3type; + ; // OK + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution11.js b/tests/baselines/reference/tsxElementResolution11.js new file mode 100644 index 0000000000000..fb8572116b16f --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution11.js @@ -0,0 +1,33 @@ +//// [tsxElementResolution11.tsx] +declare module JSX { + interface Element { } + interface ElementAttributesProperty { } + interface IntrinsicElements { } +} + +interface Obj1type { + new(n: string): any; +} +var Obj1: Obj1type; +; // OK + +interface Obj2type { + new(n: string): { q?: number }; +} +var Obj2: Obj2type; +; // Error + +interface Obj3type { + new(n: string): { x: number; }; +} +var Obj3: Obj3type; +; // OK + + +//// [tsxElementResolution11.jsx] +var Obj1; +; // OK +var Obj2; +; // Error +var Obj3; +; // OK diff --git a/tests/baselines/reference/tsxElementResolution12.errors.txt b/tests/baselines/reference/tsxElementResolution12.errors.txt new file mode 100644 index 0000000000000..71a22b502aa34 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution12.errors.txt @@ -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; + ; // OK + + interface Obj2type { + new(n: string): { q?: number; pr: any }; + } + var obj2: Obj2type; + ; // OK + ~~~~ +!!! error TS2304: Cannot find name 'Obj2'. + + interface Obj3type { + new(n: string): { x: number; }; + } + var Obj3: Obj3type; + ; // 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; + ; // OK + ; // Error + ~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution12.js b/tests/baselines/reference/tsxElementResolution12.js new file mode 100644 index 0000000000000..12973efdda7a1 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution12.js @@ -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; +; // OK + +interface Obj2type { + new(n: string): { q?: number; pr: any }; +} +var obj2: Obj2type; +; // OK + +interface Obj3type { + new(n: string): { x: number; }; +} +var Obj3: Obj3type; +; // Error + +interface Obj4type { + new(n: string): { x: number; pr: { x: number; } }; +} +var Obj4: Obj4type; +; // OK +; // Error + + +//// [tsxElementResolution12.jsx] +var Obj1; +; // OK +var obj2; +; // OK +var Obj3; +; // Error +var Obj4; +; // OK +; // Error diff --git a/tests/baselines/reference/tsxElementResolution13.js b/tests/baselines/reference/tsxElementResolution13.js new file mode 100644 index 0000000000000..f8631bdec0c2b --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution13.js @@ -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; +; // Error + + +//// [tsxElementResolution13.jsx] +var obj1; +; // Error diff --git a/tests/baselines/reference/tsxElementResolution13.symbols b/tests/baselines/reference/tsxElementResolution13.symbols new file mode 100644 index 0000000000000..4022602e53a14 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution13.symbols @@ -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)) + +; // Error +>x : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxElementResolution13.types b/tests/baselines/reference/tsxElementResolution13.types new file mode 100644 index 0000000000000..cd6265de0911a --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution13.types @@ -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 + +; // Error +> : JSX.Element +>obj1 : Obj1 +>x : any + diff --git a/tests/baselines/reference/tsxElementResolution14.js b/tests/baselines/reference/tsxElementResolution14.js new file mode 100644 index 0000000000000..e1e440db5f3bc --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution14.js @@ -0,0 +1,15 @@ +//// [tsxElementResolution14.tsx] +declare module JSX { + interface Element { } +} + +interface Obj1 { + new(n: string): {}; +} +var obj1: Obj1; +; // OK + + +//// [tsxElementResolution14.jsx] +var obj1; +; // OK diff --git a/tests/baselines/reference/tsxElementResolution14.symbols b/tests/baselines/reference/tsxElementResolution14.symbols new file mode 100644 index 0000000000000..58236a4e462f6 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution14.symbols @@ -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)) + +; // OK +>x : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxElementResolution14.types b/tests/baselines/reference/tsxElementResolution14.types new file mode 100644 index 0000000000000..ef03187d28ecb --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution14.types @@ -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 + +; // OK +> : JSX.Element +>obj1 : Obj1 +>x : any + diff --git a/tests/baselines/reference/tsxElementResolution15.errors.txt b/tests/baselines/reference/tsxElementResolution15.errors.txt new file mode 100644 index 0000000000000..24480ab7f2b41 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution15.errors.txt @@ -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; + ; // Error + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution15.js b/tests/baselines/reference/tsxElementResolution15.js new file mode 100644 index 0000000000000..831b3a54b413a --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution15.js @@ -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; +; // Error + + +//// [tsxElementResolution15.jsx] +var Obj1; +; // Error diff --git a/tests/baselines/reference/tsxElementResolution16.errors.txt b/tests/baselines/reference/tsxElementResolution16.errors.txt new file mode 100644 index 0000000000000..0e30cad9673a0 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution16.errors.txt @@ -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; + ; // 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 + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution16.js b/tests/baselines/reference/tsxElementResolution16.js new file mode 100644 index 0000000000000..1961215fa05e2 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution16.js @@ -0,0 +1,14 @@ +//// [tsxElementResolution16.tsx] +declare module JSX { +} + +interface Obj1 { + new(n: string): {}; +} +var obj1: Obj1; +; // Error (JSX.Element is implicit any) + + +//// [tsxElementResolution16.jsx] +var obj1; +; // Error (JSX.Element is implicit any) diff --git a/tests/baselines/reference/tsxElementResolution16.symbols b/tests/baselines/reference/tsxElementResolution16.symbols new file mode 100644 index 0000000000000..e01f19b991f48 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution16.symbols @@ -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)) + +; // Error (JSX.Element is missing) +>x : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxElementResolution16.types b/tests/baselines/reference/tsxElementResolution16.types new file mode 100644 index 0000000000000..3b8604e737d20 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution16.types @@ -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 + +; // Error (JSX.Element is missing) +> : any +>obj1 : Obj1 +>x : any + diff --git a/tests/baselines/reference/tsxElementResolution17.js b/tests/baselines/reference/tsxElementResolution17.js new file mode 100644 index 0000000000000..cd8d7e13beb2f --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution17.js @@ -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] +/// +// Should keep s1 and elide s2 +import s1 = require('elements1'); +import s2 = require('elements2'); +; + + +//// [file.jsx] +//// [consumer.jsx] +define(["require", "exports", 'elements1'], function (require, exports, s1) { + ; +}); diff --git a/tests/baselines/reference/tsxElementResolution17.symbols b/tests/baselines/reference/tsxElementResolution17.symbols new file mode 100644 index 0000000000000..0b4459552de39 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution17.symbols @@ -0,0 +1,38 @@ +=== tests/cases/conformance/jsx/consumer.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)) + +; +>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)) + + } +} + diff --git a/tests/baselines/reference/tsxElementResolution17.types b/tests/baselines/reference/tsxElementResolution17.types new file mode 100644 index 0000000000000..e6396a9a60be5 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution17.types @@ -0,0 +1,40 @@ +=== tests/cases/conformance/jsx/consumer.tsx === +/// +// Should keep s1 and elide s2 +import s1 = require('elements1'); +>s1 : typeof s1 + +import s2 = require('elements2'); +>s2 : typeof s2 + +; +> : 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 + + } +} + diff --git a/tests/baselines/reference/tsxElementResolution18.errors.txt b/tests/baselines/reference/tsxElementResolution18.errors.txt new file mode 100644 index 0000000000000..a4728b2f749e5 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution18.errors.txt @@ -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 +
; + ~~~~~~~~~~~~~ +!!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution18.js b/tests/baselines/reference/tsxElementResolution18.js new file mode 100644 index 0000000000000..0b5138b7b4927 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution18.js @@ -0,0 +1,12 @@ +//// [tsxElementResolution18.tsx] +declare module JSX { + interface Element { } +} + +// Error under implicit any +
; + + +//// [tsxElementResolution18.jsx] +// Error under implicit any +
; diff --git a/tests/baselines/reference/tsxElementResolution2.js b/tests/baselines/reference/tsxElementResolution2.js new file mode 100644 index 0000000000000..1d06656d529a5 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution2.js @@ -0,0 +1,19 @@ +//// [tsxElementResolution2.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [x: string]: any; + } +} + +// OK +
; + +// OK +; + +//// [tsxElementResolution2.jsx] +// OK +
; +// OK +; diff --git a/tests/baselines/reference/tsxElementResolution2.symbols b/tests/baselines/reference/tsxElementResolution2.symbols new file mode 100644 index 0000000000000..2935bcd4f63d5 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution2.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/jsx/tsxElementResolution2.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxElementResolution2.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxElementResolution2.tsx, 0, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxElementResolution2.tsx, 1, 22)) + + [x: string]: any; +>x : Symbol(x, Decl(tsxElementResolution2.tsx, 3, 6)) + } +} + +// OK +
; +>div : Symbol(JSX.IntrinsicElements, Decl(tsxElementResolution2.tsx, 1, 22)) + +// OK +; +>span : Symbol(JSX.IntrinsicElements, Decl(tsxElementResolution2.tsx, 1, 22)) + diff --git a/tests/baselines/reference/tsxElementResolution2.types b/tests/baselines/reference/tsxElementResolution2.types new file mode 100644 index 0000000000000..56ea51582539b --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution2.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/jsx/tsxElementResolution2.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [x: string]: any; +>x : string + } +} + +// OK +
; +>
: JSX.Element +>div : any + +// OK +; +> : JSX.Element +>span : any + diff --git a/tests/baselines/reference/tsxElementResolution3.errors.txt b/tests/baselines/reference/tsxElementResolution3.errors.txt new file mode 100644 index 0000000000000..bc3c7c5ebfc55 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution3.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/jsx/tsxElementResolution3.tsx(12,1): error TS2324: Property 'n' is missing in type '{ n: string; }'. +tests/cases/conformance/jsx/tsxElementResolution3.tsx(12,7): error TS2339: Property 'w' does not exist on type '{ n: string; }'. + + +==== tests/cases/conformance/jsx/tsxElementResolution3.tsx (2 errors) ==== + declare module JSX { + interface Element { } + interface IntrinsicElements { + [x: string]: { n: string; }; + } + } + + // OK +
; + + // Error + ; + ~~~~~~~~~~~~~~~~ +!!! error TS2324: Property 'n' is missing in type '{ n: string; }'. + ~ +!!! error TS2339: Property 'w' does not exist on type '{ n: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution3.js b/tests/baselines/reference/tsxElementResolution3.js new file mode 100644 index 0000000000000..607d1c5ec66fc --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution3.js @@ -0,0 +1,19 @@ +//// [tsxElementResolution3.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [x: string]: { n: string; }; + } +} + +// OK +
; + +// Error +; + +//// [tsxElementResolution3.jsx] +// OK +
; +// Error +; diff --git a/tests/baselines/reference/tsxElementResolution4.errors.txt b/tests/baselines/reference/tsxElementResolution4.errors.txt new file mode 100644 index 0000000000000..0e383af5e7b13 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution4.errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/jsx/tsxElementResolution4.tsx(16,1): error TS2324: Property 'm' is missing in type '{ m: string; }'. +tests/cases/conformance/jsx/tsxElementResolution4.tsx(16,7): error TS2339: Property 'q' does not exist on type '{ m: string; }'. + + +==== tests/cases/conformance/jsx/tsxElementResolution4.tsx (2 errors) ==== + declare module JSX { + interface Element { } + interface IntrinsicElements { + div: { n: string; }; + span: { m: string; }; + } + } + + // OK +
; + + // OK + ; + + // Error + ; + ~~~~~~~~~~~~~ +!!! error TS2324: Property 'm' is missing in type '{ m: string; }'. + ~ +!!! error TS2339: Property 'q' does not exist on type '{ m: string; }'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution4.js b/tests/baselines/reference/tsxElementResolution4.js new file mode 100644 index 0000000000000..ea395cb507762 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution4.js @@ -0,0 +1,26 @@ +//// [tsxElementResolution4.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + div: { n: string; }; + span: { m: string; }; + } +} + +// OK +
; + +// OK +; + +// Error +; + + +//// [tsxElementResolution4.jsx] +// OK +
; +// OK +; +// Error +; diff --git a/tests/baselines/reference/tsxElementResolution5.js b/tests/baselines/reference/tsxElementResolution5.js new file mode 100644 index 0000000000000..8aadfec0f782e --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution5.js @@ -0,0 +1,12 @@ +//// [tsxElementResolution5.tsx] +declare module JSX { + interface Element { } +} + +// OK, but implicit any +
; + + +//// [tsxElementResolution5.jsx] +// OK, but implicit any +
; diff --git a/tests/baselines/reference/tsxElementResolution5.symbols b/tests/baselines/reference/tsxElementResolution5.symbols new file mode 100644 index 0000000000000..8bbbfaaeb689d --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution5.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/jsx/tsxElementResolution5.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxElementResolution5.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxElementResolution5.tsx, 0, 20)) +} + +// OK, but implicit any +
; +>n : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxElementResolution5.types b/tests/baselines/reference/tsxElementResolution5.types new file mode 100644 index 0000000000000..ba3509f4fa135 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution5.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/jsx/tsxElementResolution5.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element +} + +// OK, but implicit any +
; +>
: JSX.Element +>div : any +>n : any + diff --git a/tests/baselines/reference/tsxElementResolution6.errors.txt b/tests/baselines/reference/tsxElementResolution6.errors.txt new file mode 100644 index 0000000000000..1336cc6df0c06 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution6.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/jsx/tsxElementResolution6.tsx(8,1): error TS2339: Property 'div' does not exist on type 'JSX.IntrinsicElements'. + + +==== tests/cases/conformance/jsx/tsxElementResolution6.tsx (1 errors) ==== + declare module JSX { + interface Element { } + interface IntrinsicElements { } + } + + var div: any; + // Still an error +
; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'div' does not exist on type 'JSX.IntrinsicElements'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution6.js b/tests/baselines/reference/tsxElementResolution6.js new file mode 100644 index 0000000000000..1b6d174fea8b0 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution6.js @@ -0,0 +1,15 @@ +//// [tsxElementResolution6.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +var div: any; +// Still an error +
; + + +//// [tsxElementResolution6.jsx] +var div; +// Still an error +
; diff --git a/tests/baselines/reference/tsxElementResolution7.errors.txt b/tests/baselines/reference/tsxElementResolution7.errors.txt new file mode 100644 index 0000000000000..b8549e19535ff --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution7.errors.txt @@ -0,0 +1,30 @@ +tests/cases/conformance/jsx/tsxElementResolution7.tsx(12,5): error TS2339: Property 'other' does not exist on type 'typeof my'. +tests/cases/conformance/jsx/tsxElementResolution7.tsx(19,11): error TS2339: Property 'non' does not exist on type 'typeof my'. + + +==== tests/cases/conformance/jsx/tsxElementResolution7.tsx (2 errors) ==== + declare module JSX { + interface Element { } + interface IntrinsicElements { } + } + + module my { + export var div: any; + } + // OK + ; + // Error + ; + ~~~~~ +!!! error TS2339: Property 'other' does not exist on type 'typeof my'. + + module q { + import mine = my; + // OK + ; + // Error + ; + ~~~ +!!! error TS2339: Property 'non' does not exist on type 'typeof my'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution7.js b/tests/baselines/reference/tsxElementResolution7.js new file mode 100644 index 0000000000000..7df44b052a214 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution7.js @@ -0,0 +1,39 @@ +//// [tsxElementResolution7.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +module my { + export var div: any; +} +// OK +; +// Error +; + +module q { + import mine = my; + // OK + ; + // Error + ; +} + + +//// [tsxElementResolution7.jsx] +var my; +(function (my) { +})(my || (my = {})); +// OK +; +// Error +; +var q; +(function (q) { + var mine = my; + // OK + ; + // Error + ; +})(q || (q = {})); diff --git a/tests/baselines/reference/tsxElementResolution8.errors.txt b/tests/baselines/reference/tsxElementResolution8.errors.txt new file mode 100644 index 0000000000000..5710c4e177d35 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution8.errors.txt @@ -0,0 +1,50 @@ +tests/cases/conformance/jsx/tsxElementResolution8.tsx(8,2): error TS2604: JSX element type 'Div' does not have any construct or call signatures. +tests/cases/conformance/jsx/tsxElementResolution8.tsx(16,2): error TS2601: The return type of a JSX element constructor must return an object type. +tests/cases/conformance/jsx/tsxElementResolution8.tsx(29,2): error TS2601: The return type of a JSX element constructor must return an object type. +tests/cases/conformance/jsx/tsxElementResolution8.tsx(34,2): error TS2604: JSX element type 'Obj3' does not have any construct or call signatures. + + +==== tests/cases/conformance/jsx/tsxElementResolution8.tsx (4 errors) ==== + declare module JSX { + interface Element { } + interface IntrinsicElements { } + } + + // Error + var Div = 3; +
; + ~~~ +!!! error TS2604: JSX element type 'Div' does not have any construct or call signatures. + + // OK + function Fact(): any { return null; } + + + // Error + function Fnum(): number{ return 42; } + + ~~~~ +!!! error TS2601: The return type of a JSX element constructor must return an object type. + + interface Obj1 { + new(): {}; + (): number; + } + var Obj1: Obj1; + ; // OK, prefer construct signatures + + interface Obj2 { + (): number; + } + var Obj2: Obj2; + ; // Error + ~~~~ +!!! error TS2601: The return type of a JSX element constructor must return an object type. + + interface Obj3 { + } + var Obj3: Obj3; + ; // Error + ~~~~ +!!! error TS2604: JSX element type 'Obj3' does not have any construct or call signatures. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution8.js b/tests/baselines/reference/tsxElementResolution8.js new file mode 100644 index 0000000000000..4217761c4025c --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution8.js @@ -0,0 +1,53 @@ +//// [tsxElementResolution8.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +// Error +var Div = 3; +
; + +// OK +function Fact(): any { return null; } + + +// Error +function Fnum(): number{ return 42; } + + +interface Obj1 { + new(): {}; + (): number; +} +var Obj1: Obj1; +; // OK, prefer construct signatures + +interface Obj2 { + (): number; +} +var Obj2: Obj2; +; // Error + +interface Obj3 { +} +var Obj3: Obj3; +; // Error + + +//// [tsxElementResolution8.jsx] +// Error +var Div = 3; +
; +// OK +function Fact() { return null; } +; +// Error +function Fnum() { return 42; } +; +var Obj1; +; // OK, prefer construct signatures +var Obj2; +; // Error +var Obj3; +; // Error diff --git a/tests/baselines/reference/tsxElementResolution9.errors.txt b/tests/baselines/reference/tsxElementResolution9.errors.txt new file mode 100644 index 0000000000000..f4412719b33b3 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution9.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/jsx/tsxElementResolution9.tsx(11,2): error TS2601: The return type of a JSX element constructor must return an object type. +tests/cases/conformance/jsx/tsxElementResolution9.tsx(18,2): error TS2601: The return type of a JSX element constructor must return an object type. + + +==== tests/cases/conformance/jsx/tsxElementResolution9.tsx (2 errors) ==== + declare module JSX { + interface Element { } + interface IntrinsicElements { } + } + + interface Obj1 { + new(n: string): { x: number }; + new(n: number): { y: string }; + } + var Obj1: Obj1; + ; // Error, return type is not an object type + ~~~~ +!!! error TS2601: The return type of a JSX element constructor must return an object type. + + interface Obj2 { + (n: string): { x: number }; + (n: number): { y: string }; + } + var Obj2: Obj2; + ; // Error, return type is not an object type + ~~~~ +!!! error TS2601: The return type of a JSX element constructor must return an object type. + + interface Obj3 { + (n: string): { x: number }; + (n: number): { x: number; y: string }; + } + var Obj3: Obj3; + ; // OK + \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution9.js b/tests/baselines/reference/tsxElementResolution9.js new file mode 100644 index 0000000000000..c897a51eaeb56 --- /dev/null +++ b/tests/baselines/reference/tsxElementResolution9.js @@ -0,0 +1,35 @@ +//// [tsxElementResolution9.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +interface Obj1 { + new(n: string): { x: number }; + new(n: number): { y: string }; +} +var Obj1: Obj1; +; // Error, return type is not an object type + +interface Obj2 { + (n: string): { x: number }; + (n: number): { y: string }; +} +var Obj2: Obj2; +; // Error, return type is not an object type + +interface Obj3 { + (n: string): { x: number }; + (n: number): { x: number; y: string }; +} +var Obj3: Obj3; +; // OK + + +//// [tsxElementResolution9.jsx] +var Obj1; +; // Error, return type is not an object type +var Obj2; +; // Error, return type is not an object type +var Obj3; +; // OK diff --git a/tests/baselines/reference/tsxEmit1.js b/tests/baselines/reference/tsxEmit1.js new file mode 100644 index 0000000000000..baa75526dd775 --- /dev/null +++ b/tests/baselines/reference/tsxEmit1.js @@ -0,0 +1,75 @@ +//// [tsxEmit1.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p; +var selfClosed1 =
; +var selfClosed2 =
; +var selfClosed3 =
; +var selfClosed4 =
; +var selfClosed5 =
; +var selfClosed6 =
; +var selfClosed7 =
; + +var openClosed1 =
; +var openClosed2 =
foo
; +var openClosed3 =
{p}
; +var openClosed4 =
{p < p}
; +var openClosed5 =
{p > p}
; + +class SomeClass { + f() { + var rewrites1 =
{() => this}
; + var rewrites2 =
{[p, ...p, p]}
; + var rewrites3 =
{{p}}
; + + var rewrites4 =
this}>
; + var rewrites5 =
; + var rewrites6 =
; + } +} + +var whitespace1 =
; +var whitespace2 =
{p}
; +var whitespace3 =
+ {p} +
; + + +//// [tsxEmit1.jsx] +var p; +var selfClosed1 =
; +var selfClosed2 =
; +var selfClosed3 =
; +var selfClosed4 =
; +var selfClosed5 =
; +var selfClosed6 =
; +var selfClosed7 =
; +var openClosed1 =
; +var openClosed2 =
foo
; +var openClosed3 =
{p}
; +var openClosed4 =
{p < p}
; +var openClosed5 =
{p > p}
; +var SomeClass = (function () { + function SomeClass() { + } + SomeClass.prototype.f = function () { + var _this = this; + var rewrites1 =
{function () { return _this; }}
; + var rewrites2 =
{[p].concat(p, [p])}
; + var rewrites3 =
{{ p: p }}
; + var rewrites4 =
; + var rewrites5 =
; + var rewrites6 =
; + }; + return SomeClass; +})(); +var whitespace1 =
; +var whitespace2 =
{p}
; +var whitespace3 =
+ {p} +
; diff --git a/tests/baselines/reference/tsxEmit1.symbols b/tests/baselines/reference/tsxEmit1.symbols new file mode 100644 index 0000000000000..284f6cd9ce748 --- /dev/null +++ b/tests/baselines/reference/tsxEmit1.symbols @@ -0,0 +1,144 @@ +=== tests/cases/conformance/jsx/tsxEmit1.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxEmit1.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxEmit1.tsx, 0, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(tsxEmit1.tsx, 3, 3)) + } +} + +var p; +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) + +var selfClosed1 =
; +>selfClosed1 : Symbol(selfClosed1, Decl(tsxEmit1.tsx, 8, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) + +var selfClosed2 =
; +>selfClosed2 : Symbol(selfClosed2, Decl(tsxEmit1.tsx, 9, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>x : Symbol(unknown) + +var selfClosed3 =
; +>selfClosed3 : Symbol(selfClosed3, Decl(tsxEmit1.tsx, 10, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>x : Symbol(unknown) + +var selfClosed4 =
; +>selfClosed4 : Symbol(selfClosed4, Decl(tsxEmit1.tsx, 11, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + +var selfClosed5 =
; +>selfClosed5 : Symbol(selfClosed5, Decl(tsxEmit1.tsx, 12, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + +var selfClosed6 =
; +>selfClosed6 : Symbol(selfClosed6, Decl(tsxEmit1.tsx, 13, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + +var selfClosed7 =
; +>selfClosed7 : Symbol(selfClosed7, Decl(tsxEmit1.tsx, 14, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + +var openClosed1 =
; +>openClosed1 : Symbol(openClosed1, Decl(tsxEmit1.tsx, 16, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) + +var openClosed2 =
foo
; +>openClosed2 : Symbol(openClosed2, Decl(tsxEmit1.tsx, 17, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>n : Symbol(unknown) + +var openClosed3 =
{p}
; +>openClosed3 : Symbol(openClosed3, Decl(tsxEmit1.tsx, 18, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>n : Symbol(unknown) + +var openClosed4 =
{p < p}
; +>openClosed4 : Symbol(openClosed4, Decl(tsxEmit1.tsx, 19, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>n : Symbol(unknown) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) + +var openClosed5 =
{p > p}
; +>openClosed5 : Symbol(openClosed5, Decl(tsxEmit1.tsx, 20, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>n : Symbol(unknown) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) + +class SomeClass { +>SomeClass : Symbol(SomeClass, Decl(tsxEmit1.tsx, 20, 43)) + + f() { +>f : Symbol(f, Decl(tsxEmit1.tsx, 22, 17)) + + var rewrites1 =
{() => this}
; +>rewrites1 : Symbol(rewrites1, Decl(tsxEmit1.tsx, 24, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>this : Symbol(SomeClass, Decl(tsxEmit1.tsx, 20, 43)) + + var rewrites2 =
{[p, ...p, p]}
; +>rewrites2 : Symbol(rewrites2, Decl(tsxEmit1.tsx, 25, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) + + var rewrites3 =
{{p}}
; +>rewrites3 : Symbol(rewrites3, Decl(tsxEmit1.tsx, 26, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 26, 25)) + + var rewrites4 =
this}>
; +>rewrites4 : Symbol(rewrites4, Decl(tsxEmit1.tsx, 28, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>a : Symbol(unknown) +>this : Symbol(SomeClass, Decl(tsxEmit1.tsx, 20, 43)) + + var rewrites5 =
; +>rewrites5 : Symbol(rewrites5, Decl(tsxEmit1.tsx, 29, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>a : Symbol(unknown) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxEmit1.tsx, 7, 3)) + + var rewrites6 =
; +>rewrites6 : Symbol(rewrites6, Decl(tsxEmit1.tsx, 30, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) +>a : Symbol(unknown) +>p : Symbol(p, Decl(tsxEmit1.tsx, 30, 27)) + } +} + +var whitespace1 =
; +>whitespace1 : Symbol(whitespace1, Decl(tsxEmit1.tsx, 34, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) + +var whitespace2 =
{p}
; +>whitespace2 : Symbol(whitespace2, Decl(tsxEmit1.tsx, 35, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) + +var whitespace3 =
+>whitespace3 : Symbol(whitespace3, Decl(tsxEmit1.tsx, 36, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit1.tsx, 1, 22)) + + {p} +
; + diff --git a/tests/baselines/reference/tsxEmit1.types b/tests/baselines/reference/tsxEmit1.types new file mode 100644 index 0000000000000..667ec11333770 --- /dev/null +++ b/tests/baselines/reference/tsxEmit1.types @@ -0,0 +1,194 @@ +=== tests/cases/conformance/jsx/tsxEmit1.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +var p; +>p : any + +var selfClosed1 =
; +>selfClosed1 : JSX.Element +>
: JSX.Element +>div : any + +var selfClosed2 =
; +>selfClosed2 : JSX.Element +>
: JSX.Element +>div : any +>x : any + +var selfClosed3 =
; +>selfClosed3 : JSX.Element +>
: JSX.Element +>div : any +>x : any + +var selfClosed4 =
; +>selfClosed4 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>y : any + +var selfClosed5 =
; +>selfClosed5 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>y : any + +var selfClosed6 =
; +>selfClosed6 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>y : any + +var selfClosed7 =
; +>selfClosed7 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>p : any +>y : any + +var openClosed1 =
; +>openClosed1 : JSX.Element +>
: JSX.Element +>div : any +>div : any + +var openClosed2 =
foo
; +>openClosed2 : JSX.Element +>
foo
: JSX.Element +>div : any +>n : any +>div : any + +var openClosed3 =
{p}
; +>openClosed3 : JSX.Element +>
{p}
: JSX.Element +>div : any +>n : any +>p : any +>div : any + +var openClosed4 =
{p < p}
; +>openClosed4 : JSX.Element +>
{p < p}
: JSX.Element +>div : any +>n : any +>p < p : boolean +>p : any +>p : any +>div : any + +var openClosed5 =
{p > p}
; +>openClosed5 : JSX.Element +>
{p > p}
: JSX.Element +>div : any +>n : any +>p > p : boolean +>p : any +>p : any +>div : any + +class SomeClass { +>SomeClass : SomeClass + + f() { +>f : () => void + + var rewrites1 =
{() => this}
; +>rewrites1 : JSX.Element +>
{() => this}
: JSX.Element +>div : any +>() => this : () => SomeClass +>this : SomeClass +>div : any + + var rewrites2 =
{[p, ...p, p]}
; +>rewrites2 : JSX.Element +>
{[p, ...p, p]}
: JSX.Element +>div : any +>[p, ...p, p] : any[] +>p : any +>...p : any +>p : any +>p : any +>div : any + + var rewrites3 =
{{p}}
; +>rewrites3 : JSX.Element +>
{{p}}
: JSX.Element +>div : any +>{p} : { p: any; } +>p : any +>div : any + + var rewrites4 =
this}>
; +>rewrites4 : JSX.Element +>
this}>
: JSX.Element +>div : any +>a : any +>() => this : () => SomeClass +>this : SomeClass +>div : any + + var rewrites5 =
; +>rewrites5 : JSX.Element +>
: JSX.Element +>div : any +>a : any +>[p, ...p, p] : any[] +>p : any +>...p : any +>p : any +>p : any +>div : any + + var rewrites6 =
; +>rewrites6 : JSX.Element +>
: JSX.Element +>div : any +>a : any +>{p} : { p: any; } +>p : any +>div : any + } +} + +var whitespace1 =
; +>whitespace1 : JSX.Element +>
: JSX.Element +>div : any +>div : any + +var whitespace2 =
{p}
; +>whitespace2 : JSX.Element +>
{p}
: JSX.Element +>div : any +>p : any +>div : any + +var whitespace3 =
+>whitespace3 : JSX.Element +>
{p}
: JSX.Element +>div : any + + {p} +>p : any + +
; +>div : any + diff --git a/tests/baselines/reference/tsxEmit2.js b/tests/baselines/reference/tsxEmit2.js new file mode 100644 index 0000000000000..1101df49a1c43 --- /dev/null +++ b/tests/baselines/reference/tsxEmit2.js @@ -0,0 +1,23 @@ +//// [tsxEmit2.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p1, p2, p3; +var spreads1 =
{p2}
; +var spreads2 =
{p2}
; +var spreads3 =
{p2}
; +var spreads4 =
{p2}
; +var spreads5 =
{p2}
; + + +//// [tsxEmit2.jsx] +var p1, p2, p3; +var spreads1 =
{p2}
; +var spreads2 =
{p2}
; +var spreads3 =
{p2}
; +var spreads4 =
{p2}
; +var spreads5 =
{p2}
; diff --git a/tests/baselines/reference/tsxEmit2.symbols b/tests/baselines/reference/tsxEmit2.symbols new file mode 100644 index 0000000000000..28f6a9f5026fe --- /dev/null +++ b/tests/baselines/reference/tsxEmit2.symbols @@ -0,0 +1,44 @@ +=== tests/cases/conformance/jsx/tsxEmit2.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxEmit2.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxEmit2.tsx, 0, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(tsxEmit2.tsx, 3, 3)) + } +} + +var p1, p2, p3; +>p1 : Symbol(p1, Decl(tsxEmit2.tsx, 7, 3)) +>p2 : Symbol(p2, Decl(tsxEmit2.tsx, 7, 7)) +>p3 : Symbol(p3, Decl(tsxEmit2.tsx, 7, 11)) + +var spreads1 =
{p2}
; +>spreads1 : Symbol(spreads1, Decl(tsxEmit2.tsx, 8, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22)) + +var spreads2 =
{p2}
; +>spreads2 : Symbol(spreads2, Decl(tsxEmit2.tsx, 9, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22)) + +var spreads3 =
{p2}
; +>spreads3 : Symbol(spreads3, Decl(tsxEmit2.tsx, 10, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22)) +>x : Symbol(unknown) + +var spreads4 =
{p2}
; +>spreads4 : Symbol(spreads4, Decl(tsxEmit2.tsx, 11, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22)) +>x : Symbol(unknown) + +var spreads5 =
{p2}
; +>spreads5 : Symbol(spreads5, Decl(tsxEmit2.tsx, 12, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxEmit2.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxEmit2.types b/tests/baselines/reference/tsxEmit2.types new file mode 100644 index 0000000000000..f5633b739e3b1 --- /dev/null +++ b/tests/baselines/reference/tsxEmit2.types @@ -0,0 +1,68 @@ +=== tests/cases/conformance/jsx/tsxEmit2.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +var p1, p2, p3; +>p1 : any +>p2 : any +>p3 : any + +var spreads1 =
{p2}
; +>spreads1 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>p1 : any +>p2 : any +>div : any + +var spreads2 =
{p2}
; +>spreads2 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>p1 : any +>p2 : any +>div : any + +var spreads3 =
{p2}
; +>spreads3 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>x : any +>p3 : any +>p1 : any +>p2 : any +>div : any + +var spreads4 =
{p2}
; +>spreads4 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>p1 : any +>x : any +>p3 : any +>p2 : any +>div : any + +var spreads5 =
{p2}
; +>spreads5 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>x : any +>p2 : any +>p1 : any +>y : any +>p3 : any +>p2 : any +>div : any + diff --git a/tests/baselines/reference/tsxEmit3.js b/tests/baselines/reference/tsxEmit3.js new file mode 100644 index 0000000000000..beae73e2bf142 --- /dev/null +++ b/tests/baselines/reference/tsxEmit3.js @@ -0,0 +1,84 @@ +//// [tsxEmit3.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +module M { + export class Foo { constructor() { } } + export module S { + export class Bar { } + + // Emit Foo + // Foo, ; + } +} + +module M { + // Emit M.Foo + Foo, ; + + export module S { + // Emit M.Foo + Foo, ; + + // Emit S.Bar + Bar, ; + } + +} + +module M { + // Emit M.S.Bar + S.Bar, ; +} + +module M { + var M = 100; + // Emit M_1.Foo + Foo, ; +} + + +//// [tsxEmit3.jsx] +var M; +(function (M) { + var Foo = (function () { + function Foo() { + } + return Foo; + })(); + M.Foo = Foo; + var S; + (function (S) { + var Bar = (function () { + function Bar() { + } + return Bar; + })(); + S.Bar = Bar; + })(S = M.S || (M.S = {})); +})(M || (M = {})); +var M; +(function (M) { + // Emit M.Foo + M.Foo, ; + var S; + (function (S) { + // Emit M.Foo + M.Foo, ; + // Emit S.Bar + S.Bar, ; + })(S = M.S || (M.S = {})); +})(M || (M = {})); +var M; +(function (M) { + // Emit M.S.Bar + M.S.Bar, ; +})(M || (M = {})); +var M; +(function (M_1) { + var M = 100; + // Emit M_1.Foo + M_1.Foo, ; +})(M || (M = {})); diff --git a/tests/baselines/reference/tsxEmit3.symbols b/tests/baselines/reference/tsxEmit3.symbols new file mode 100644 index 0000000000000..4ceed0b9b1e84 --- /dev/null +++ b/tests/baselines/reference/tsxEmit3.symbols @@ -0,0 +1,75 @@ +=== tests/cases/conformance/jsx/tsxEmit3.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxEmit3.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxEmit3.tsx, 0, 20)) + + interface IntrinsicElements { } +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxEmit3.tsx, 1, 22)) +} + +module M { +>M : Symbol(M, Decl(tsxEmit3.tsx, 3, 1), Decl(tsxEmit3.tsx, 13, 1), Decl(tsxEmit3.tsx, 27, 1), Decl(tsxEmit3.tsx, 32, 1)) + + export class Foo { constructor() { } } +>Foo : Symbol(Foo, Decl(tsxEmit3.tsx, 5, 10)) + + export module S { +>S : Symbol(S, Decl(tsxEmit3.tsx, 6, 39), Decl(tsxEmit3.tsx, 17, 14)) + + export class Bar { } +>Bar : Symbol(Bar, Decl(tsxEmit3.tsx, 7, 18)) + + // Emit Foo + // Foo, ; + } +} + +module M { +>M : Symbol(M, Decl(tsxEmit3.tsx, 3, 1), Decl(tsxEmit3.tsx, 13, 1), Decl(tsxEmit3.tsx, 27, 1), Decl(tsxEmit3.tsx, 32, 1)) + + // Emit M.Foo + Foo, ; +>Foo : Symbol(Foo, Decl(tsxEmit3.tsx, 5, 10)) +>Foo : Symbol(Foo, Decl(tsxEmit3.tsx, 5, 10)) + + export module S { +>S : Symbol(S, Decl(tsxEmit3.tsx, 6, 39), Decl(tsxEmit3.tsx, 17, 14)) + + // Emit M.Foo + Foo, ; +>Foo : Symbol(Foo, Decl(tsxEmit3.tsx, 5, 10)) +>Foo : Symbol(Foo, Decl(tsxEmit3.tsx, 5, 10)) + + // Emit S.Bar + Bar, ; +>Bar : Symbol(Bar, Decl(tsxEmit3.tsx, 7, 18)) +>Bar : Symbol(Bar, Decl(tsxEmit3.tsx, 7, 18)) + } + +} + +module M { +>M : Symbol(M, Decl(tsxEmit3.tsx, 3, 1), Decl(tsxEmit3.tsx, 13, 1), Decl(tsxEmit3.tsx, 27, 1), Decl(tsxEmit3.tsx, 32, 1)) + + // Emit M.S.Bar + S.Bar, ; +>S.Bar : Symbol(S.Bar, Decl(tsxEmit3.tsx, 7, 18)) +>S : Symbol(S, Decl(tsxEmit3.tsx, 6, 39), Decl(tsxEmit3.tsx, 17, 14)) +>Bar : Symbol(S.Bar, Decl(tsxEmit3.tsx, 7, 18)) +>Bar : Symbol(S.Bar, Decl(tsxEmit3.tsx, 7, 18)) +} + +module M { +>M : Symbol(M, Decl(tsxEmit3.tsx, 3, 1), Decl(tsxEmit3.tsx, 13, 1), Decl(tsxEmit3.tsx, 27, 1), Decl(tsxEmit3.tsx, 32, 1)) + + var M = 100; +>M : Symbol(M, Decl(tsxEmit3.tsx, 35, 4)) + + // Emit M_1.Foo + Foo, ; +>Foo : Symbol(Foo, Decl(tsxEmit3.tsx, 5, 10)) +>Foo : Symbol(Foo, Decl(tsxEmit3.tsx, 5, 10)) +} + diff --git a/tests/baselines/reference/tsxEmit3.types b/tests/baselines/reference/tsxEmit3.types new file mode 100644 index 0000000000000..4bb92d9aea57b --- /dev/null +++ b/tests/baselines/reference/tsxEmit3.types @@ -0,0 +1,87 @@ +=== tests/cases/conformance/jsx/tsxEmit3.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { } +>IntrinsicElements : IntrinsicElements +} + +module M { +>M : typeof M + + export class Foo { constructor() { } } +>Foo : Foo + + export module S { +>S : typeof S + + export class Bar { } +>Bar : Bar + + // Emit Foo + // Foo, ; + } +} + +module M { +>M : typeof M + + // Emit M.Foo + Foo, ; +>Foo, : JSX.Element +>Foo : typeof Foo +> : JSX.Element +>Foo : typeof Foo + + export module S { +>S : typeof S + + // Emit M.Foo + Foo, ; +>Foo, : JSX.Element +>Foo : typeof Foo +> : JSX.Element +>Foo : typeof Foo + + // Emit S.Bar + Bar, ; +>Bar, : JSX.Element +>Bar : typeof Bar +> : JSX.Element +>Bar : typeof Bar + } + +} + +module M { +>M : typeof M + + // Emit M.S.Bar + S.Bar, ; +>S.Bar, : JSX.Element +>S.Bar : typeof S.Bar +>S : typeof S +>Bar : typeof S.Bar +> : JSX.Element +>S : any +>Bar : any +} + +module M { +>M : typeof M + + var M = 100; +>M : number +>100 : number + + // Emit M_1.Foo + Foo, ; +>Foo, : JSX.Element +>Foo : typeof Foo +> : JSX.Element +>Foo : typeof Foo +} + diff --git a/tests/baselines/reference/tsxErrorRecovery1.errors.txt b/tests/baselines/reference/tsxErrorRecovery1.errors.txt new file mode 100644 index 0000000000000..dc4f4d51afede --- /dev/null +++ b/tests/baselines/reference/tsxErrorRecovery1.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/jsx/tsxErrorRecovery1.tsx(5,19): error TS1109: Expression expected. + + +==== tests/cases/conformance/jsx/tsxErrorRecovery1.tsx (1 errors) ==== + + declare namespace JSX { interface Element { } } + + function foo() { + var x =
{
+ ~~ +!!! error TS1109: Expression expected. + } + // Shouldn't see any errors down here + var y = { a: 1 }; + \ No newline at end of file diff --git a/tests/baselines/reference/tsxErrorRecovery1.js b/tests/baselines/reference/tsxErrorRecovery1.js new file mode 100644 index 0000000000000..8d20951f6edd5 --- /dev/null +++ b/tests/baselines/reference/tsxErrorRecovery1.js @@ -0,0 +1,17 @@ +//// [tsxErrorRecovery1.tsx] + +declare namespace JSX { interface Element { } } + +function foo() { + var x =
{
+} +// Shouldn't see any errors down here +var y = { a: 1 }; + + +//// [tsxErrorRecovery1.jsx] +function foo() { + var x =
{}
; +} +// Shouldn't see any errors down here +var y = { a: 1 }; diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.js b/tests/baselines/reference/tsxGenericArrowFunctionParsing.js new file mode 100644 index 0000000000000..f493347ca9c4a --- /dev/null +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.js @@ -0,0 +1,46 @@ +//// [tsxGenericArrowFunctionParsing.tsx] +declare module JSX { + interface Element { isElement; } +} + +var T, T1, T2; + +// This is an element +var x1 = () => {}; +x1.isElement; + +// This is a generic function +var x2 = () => {}; +x2(); + +// This is a generic function +var x3 = () => {}; +x3(); + +// This is an element +var x4 = () => {}; +x4.isElement; + +// This is an element +var x5 = () => {}; +x5.isElement; + + + +//// [tsxGenericArrowFunctionParsing.jsx] +var T, T1, T2; +// This is an element +var x1 = () => ; +x1.isElement; +// This is a generic function +var x2 = function () { }; +x2(); +// This is a generic function +var x3 = function () { }; +x3(); +// This is an element +var x4 = () => ; +x4.isElement; +// This is an element +var x5 = () => ; +x5.isElement; diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols b/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols new file mode 100644 index 0000000000000..8bd68b2e8e7e5 --- /dev/null +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.symbols @@ -0,0 +1,64 @@ +=== tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxGenericArrowFunctionParsing.tsx, 0, 0)) + + interface Element { isElement; } +>Element : Symbol(Element, Decl(tsxGenericArrowFunctionParsing.tsx, 0, 20)) +>isElement : Symbol(isElement, Decl(tsxGenericArrowFunctionParsing.tsx, 1, 20)) +} + +var T, T1, T2; +>T : Symbol(T, Decl(tsxGenericArrowFunctionParsing.tsx, 4, 3)) +>T1 : Symbol(T1, Decl(tsxGenericArrowFunctionParsing.tsx, 4, 6)) +>T2 : Symbol(T2, Decl(tsxGenericArrowFunctionParsing.tsx, 4, 10)) + +// This is an element +var x1 = () => {}; +>x1 : Symbol(x1, Decl(tsxGenericArrowFunctionParsing.tsx, 7, 3)) +>T : Symbol(T, Decl(tsxGenericArrowFunctionParsing.tsx, 4, 3)) + +x1.isElement; +>x1.isElement : Symbol(JSX.Element.isElement, Decl(tsxGenericArrowFunctionParsing.tsx, 1, 20)) +>x1 : Symbol(x1, Decl(tsxGenericArrowFunctionParsing.tsx, 7, 3)) +>isElement : Symbol(JSX.Element.isElement, Decl(tsxGenericArrowFunctionParsing.tsx, 1, 20)) + +// This is a generic function +var x2 = () => {}; +>x2 : Symbol(x2, Decl(tsxGenericArrowFunctionParsing.tsx, 11, 3)) +>T : Symbol(T, Decl(tsxGenericArrowFunctionParsing.tsx, 11, 10)) + +x2(); +>x2 : Symbol(x2, Decl(tsxGenericArrowFunctionParsing.tsx, 11, 3)) + +// This is a generic function +var x3 = () => {}; +>x3 : Symbol(x3, Decl(tsxGenericArrowFunctionParsing.tsx, 15, 3)) +>T : Symbol(T, Decl(tsxGenericArrowFunctionParsing.tsx, 15, 10)) +>T1 : Symbol(T1, Decl(tsxGenericArrowFunctionParsing.tsx, 15, 12)) + +x3(); +>x3 : Symbol(x3, Decl(tsxGenericArrowFunctionParsing.tsx, 15, 3)) + +// This is an element +var x4 = () => {}; +>x4 : Symbol(x4, Decl(tsxGenericArrowFunctionParsing.tsx, 19, 3)) +>T : Symbol(T, Decl(tsxGenericArrowFunctionParsing.tsx, 4, 3)) +>extends : Symbol(unknown) + +x4.isElement; +>x4.isElement : Symbol(JSX.Element.isElement, Decl(tsxGenericArrowFunctionParsing.tsx, 1, 20)) +>x4 : Symbol(x4, Decl(tsxGenericArrowFunctionParsing.tsx, 19, 3)) +>isElement : Symbol(JSX.Element.isElement, Decl(tsxGenericArrowFunctionParsing.tsx, 1, 20)) + +// This is an element +var x5 = () => {}; +>x5 : Symbol(x5, Decl(tsxGenericArrowFunctionParsing.tsx, 23, 3)) +>T : Symbol(T, Decl(tsxGenericArrowFunctionParsing.tsx, 4, 3)) +>extends : Symbol(unknown) + +x5.isElement; +>x5.isElement : Symbol(JSX.Element.isElement, Decl(tsxGenericArrowFunctionParsing.tsx, 1, 20)) +>x5 : Symbol(x5, Decl(tsxGenericArrowFunctionParsing.tsx, 23, 3)) +>isElement : Symbol(JSX.Element.isElement, Decl(tsxGenericArrowFunctionParsing.tsx, 1, 20)) + + diff --git a/tests/baselines/reference/tsxGenericArrowFunctionParsing.types b/tests/baselines/reference/tsxGenericArrowFunctionParsing.types new file mode 100644 index 0000000000000..a7d98d35b640a --- /dev/null +++ b/tests/baselines/reference/tsxGenericArrowFunctionParsing.types @@ -0,0 +1,75 @@ +=== tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx === +declare module JSX { +>JSX : any + + interface Element { isElement; } +>Element : Element +>isElement : any +} + +var T, T1, T2; +>T : any +>T1 : any +>T2 : any + +// This is an element +var x1 = () => {}; +>x1 : JSX.Element +>() => {} : JSX.Element +>T : any +>T : any + +x1.isElement; +>x1.isElement : any +>x1 : JSX.Element +>isElement : any + +// This is a generic function +var x2 = () => {}; +>x2 : () => void +>() => {} : () => void +>T : T + +x2(); +>x2() : void +>x2 : () => void + +// This is a generic function +var x3 = () => {}; +>x3 : () => void +>() => {} : () => void +>T : T +>T1 : T1 + +x3(); +>x3() : void +>x3 : () => void + +// This is an element +var x4 = () => {}; +>x4 : JSX.Element +>() => {} : JSX.Element +>T : any +>extends : any +>true : boolean +>T : any + +x4.isElement; +>x4.isElement : any +>x4 : JSX.Element +>isElement : any + +// This is an element +var x5 = () => {}; +>x5 : JSX.Element +>() => {} : JSX.Element +>T : any +>extends : any +>T : any + +x5.isElement; +>x5.isElement : any +>x5 : JSX.Element +>isElement : any + + diff --git a/tests/baselines/reference/tsxInArrowFunction.js b/tests/baselines/reference/tsxInArrowFunction.js new file mode 100644 index 0000000000000..ba4a0dd1d1470 --- /dev/null +++ b/tests/baselines/reference/tsxInArrowFunction.js @@ -0,0 +1,34 @@ +//// [tsxInArrowFunction.tsx] + +declare namespace JSX { + interface Element { } + interface IntrinsicElements { + div: { + text?: string; + } + } +} + + +// didn't work +
{() =>
}
; + +// didn't work +
{x =>
}
; + +// worked +
{() => (
)}
; + +// worked (!) +
{() =>
}
; + + +//// [tsxInArrowFunction.jsx] +// didn't work +
{function () { return
; }}
; +// didn't work +
{function (x) { return
; }}
; +// worked +
{function () { return (
); }}
; +// worked (!) +
{function () { return
; }}
; diff --git a/tests/baselines/reference/tsxInArrowFunction.symbols b/tests/baselines/reference/tsxInArrowFunction.symbols new file mode 100644 index 0000000000000..814f2577bf095 --- /dev/null +++ b/tests/baselines/reference/tsxInArrowFunction.symbols @@ -0,0 +1,46 @@ +=== tests/cases/conformance/jsx/tsxInArrowFunction.tsx === + +declare namespace JSX { +>JSX : Symbol(JSX, Decl(tsxInArrowFunction.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxInArrowFunction.tsx, 1, 23)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxInArrowFunction.tsx, 2, 25)) + + div: { +>div : Symbol(div, Decl(tsxInArrowFunction.tsx, 3, 33)) + + text?: string; +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) + } + } +} + + +// didn't work +
{() =>
}
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) + +// didn't work +
{x =>
}
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>x : Symbol(x, Decl(tsxInArrowFunction.tsx, 15, 6)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) + +// worked +
{() => (
)}
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) + +// worked (!) +
{() =>
}
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxInArrowFunction.tsx, 3, 33)) +>text : Symbol(text, Decl(tsxInArrowFunction.tsx, 4, 14)) + diff --git a/tests/baselines/reference/tsxInArrowFunction.types b/tests/baselines/reference/tsxInArrowFunction.types new file mode 100644 index 0000000000000..e4b2aeb50fe2c --- /dev/null +++ b/tests/baselines/reference/tsxInArrowFunction.types @@ -0,0 +1,64 @@ +=== tests/cases/conformance/jsx/tsxInArrowFunction.tsx === + +declare namespace JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + div: { +>div : { text?: string; } + + text?: string; +>text : string + } + } +} + + +// didn't work +
{() =>
}
; +>
{() =>
}
: JSX.Element +>div : any +>() =>
: () => JSX.Element +>
: JSX.Element +>div : any +>text : any +>div : any + +// didn't work +
{x =>
}
; +>
{x =>
}
: JSX.Element +>div : any +>x =>
: (x: any) => JSX.Element +>x : any +>
: JSX.Element +>div : any +>text : any +>div : any + +// worked +
{() => (
)}
; +>
{() => (
)}
: JSX.Element +>div : any +>() => (
) : () => JSX.Element +>(
) : JSX.Element +>
: JSX.Element +>div : any +>text : any +>div : any + +// worked (!) +
{() =>
}
; +>
{() =>
}
: JSX.Element +>div : any +>() =>
: () => JSX.Element +>
: JSX.Element +>div : any +>text : any +>div : any +>div : any + diff --git a/tests/baselines/reference/tsxNoJsx.js b/tests/baselines/reference/tsxNoJsx.js new file mode 100644 index 0000000000000..37663adf2a75f --- /dev/null +++ b/tests/baselines/reference/tsxNoJsx.js @@ -0,0 +1,7 @@ +//// [tsxNoJsx.tsx] + +; + + +//// [tsxNoJsx.jsx] +; diff --git a/tests/baselines/reference/tsxNoJsx.symbols b/tests/baselines/reference/tsxNoJsx.symbols new file mode 100644 index 0000000000000..6744c2edb10eb --- /dev/null +++ b/tests/baselines/reference/tsxNoJsx.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/jsx/tsxNoJsx.tsx === + +No type information for this code.; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/tsxNoJsx.types b/tests/baselines/reference/tsxNoJsx.types new file mode 100644 index 0000000000000..52e6769795eb7 --- /dev/null +++ b/tests/baselines/reference/tsxNoJsx.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/jsx/tsxNoJsx.tsx === + +; +> : any +>nope : any + diff --git a/tests/baselines/reference/tsxOpeningClosingNames.js b/tests/baselines/reference/tsxOpeningClosingNames.js new file mode 100644 index 0000000000000..80adad0f406dc --- /dev/null +++ b/tests/baselines/reference/tsxOpeningClosingNames.js @@ -0,0 +1,14 @@ +//// [tsxOpeningClosingNames.tsx] +declare module JSX { + interface Element { } +} + +declare module A.B.C { + var D: any; +} + +foo + + +//// [tsxOpeningClosingNames.jsx] +foo; diff --git a/tests/baselines/reference/tsxOpeningClosingNames.symbols b/tests/baselines/reference/tsxOpeningClosingNames.symbols new file mode 100644 index 0000000000000..3ff2a3ff68d1b --- /dev/null +++ b/tests/baselines/reference/tsxOpeningClosingNames.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/jsx/tsxOpeningClosingNames.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxOpeningClosingNames.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxOpeningClosingNames.tsx, 0, 20)) +} + +declare module A.B.C { +>A : Symbol(A, Decl(tsxOpeningClosingNames.tsx, 2, 1)) +>B : Symbol(B, Decl(tsxOpeningClosingNames.tsx, 4, 17)) +>C : Symbol(C, Decl(tsxOpeningClosingNames.tsx, 4, 19)) + + var D: any; +>D : Symbol(D, Decl(tsxOpeningClosingNames.tsx, 5, 5)) +} + +foo +>D : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxOpeningClosingNames.types b/tests/baselines/reference/tsxOpeningClosingNames.types new file mode 100644 index 0000000000000..b02564ae104a7 --- /dev/null +++ b/tests/baselines/reference/tsxOpeningClosingNames.types @@ -0,0 +1,28 @@ +=== tests/cases/conformance/jsx/tsxOpeningClosingNames.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element +} + +declare module A.B.C { +>A : typeof A +>B : typeof B +>C : typeof C + + var D: any; +>D : any +} + +foo +>foo : JSX.Element +>A : any +>B : any +>C : any +>D : any +>A : any +>B : any +>C : any +>D : any + diff --git a/tests/baselines/reference/tsxParseTests1.js b/tests/baselines/reference/tsxParseTests1.js new file mode 100644 index 0000000000000..7ab98cab31441 --- /dev/null +++ b/tests/baselines/reference/tsxParseTests1.js @@ -0,0 +1,11 @@ +//// [tsxParseTests1.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { div; span; } +} + +var x =
; + + +//// [tsxParseTests1.jsx] +var x =
; diff --git a/tests/baselines/reference/tsxParseTests1.symbols b/tests/baselines/reference/tsxParseTests1.symbols new file mode 100644 index 0000000000000..dbe11dbcbba35 --- /dev/null +++ b/tests/baselines/reference/tsxParseTests1.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/jsx/tsxParseTests1.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxParseTests1.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxParseTests1.tsx, 0, 20)) + + interface IntrinsicElements { div; span; } +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxParseTests1.tsx, 1, 22)) +>div : Symbol(div, Decl(tsxParseTests1.tsx, 2, 30)) +>span : Symbol(span, Decl(tsxParseTests1.tsx, 2, 35)) +} + +var x =
; +>x : Symbol(x, Decl(tsxParseTests1.tsx, 5, 3)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxParseTests1.tsx, 2, 30)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxParseTests1.tsx, 2, 30)) +>span : Symbol(JSX.IntrinsicElements.span, Decl(tsxParseTests1.tsx, 2, 35)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(tsxParseTests1.tsx, 2, 30)) + diff --git a/tests/baselines/reference/tsxParseTests1.types b/tests/baselines/reference/tsxParseTests1.types new file mode 100644 index 0000000000000..78e49a227e224 --- /dev/null +++ b/tests/baselines/reference/tsxParseTests1.types @@ -0,0 +1,28 @@ +=== tests/cases/conformance/jsx/tsxParseTests1.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { div; span; } +>IntrinsicElements : IntrinsicElements +>div : any +>span : any +} + +var x =
; +>x : JSX.Element +>
: JSX.Element +>div : any +>
: JSX.Element +>div : any +>
: JSX.Element +>span : any +>
: JSX.Element +>div : any +>div : any +>span : any +>div : any +>div : any + diff --git a/tests/baselines/reference/tsxReactEmit1.js b/tests/baselines/reference/tsxReactEmit1.js new file mode 100644 index 0000000000000..b6c5fd96183fc --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit1.js @@ -0,0 +1,73 @@ +//// [tsxReactEmit1.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p; +var selfClosed1 =
; +var selfClosed2 =
; +var selfClosed3 =
; +var selfClosed4 =
; +var selfClosed5 =
; +var selfClosed6 =
; +var selfClosed7 =
; + +var openClosed1 =
; +var openClosed2 =
foo
; +var openClosed3 =
{p}
; +var openClosed4 =
{p < p}
; +var openClosed5 =
{p > p}
; + +class SomeClass { + f() { + var rewrites1 =
{() => this}
; + var rewrites2 =
{[p, ...p, p]}
; + var rewrites3 =
{{p}}
; + + var rewrites4 =
this}>
; + var rewrites5 =
; + var rewrites6 =
; + } +} + +var whitespace1 =
; +var whitespace2 =
{p}
; +var whitespace3 =
+ {p} +
; + + +//// [tsxReactEmit1.js] +var p; +var selfClosed1 = React.createElement("div", null); +var selfClosed2 = React.createElement("div", {x: "1"}); +var selfClosed3 = React.createElement("div", {x: '1'}); +var selfClosed4 = React.createElement("div", {x: "1", y: '0'}); +var selfClosed5 = React.createElement("div", {x: 0, y: '0'}); +var selfClosed6 = React.createElement("div", {x: "1", y: '0'}); +var selfClosed7 = React.createElement("div", {x: p, y: 'p', b: true}); +var openClosed1 = React.createElement("div", null); +var openClosed2 = React.createElement("div", {n: 'm'}, "foo"); +var openClosed3 = React.createElement("div", {n: 'm'}, p); +var openClosed4 = React.createElement("div", {n: 'm'}, p < p); +var openClosed5 = React.createElement("div", {n: 'm', b: true}, p > p); +var SomeClass = (function () { + function SomeClass() { + } + SomeClass.prototype.f = function () { + var _this = this; + var rewrites1 = React.createElement("div", null, function () { return _this; }); + var rewrites2 = React.createElement("div", null, [p].concat(p, [p])); + var rewrites3 = React.createElement("div", null, { p: p }); + var rewrites4 = React.createElement("div", {a: function () { return _this; }}); + var rewrites5 = React.createElement("div", {a: [p].concat(p, [p])}); + var rewrites6 = React.createElement("div", {a: { p: p }}); + }; + return SomeClass; +})(); +var whitespace1 = React.createElement("div", null); +var whitespace2 = React.createElement("div", null, p); +var whitespace3 = React.createElement("div", null, p); diff --git a/tests/baselines/reference/tsxReactEmit1.symbols b/tests/baselines/reference/tsxReactEmit1.symbols new file mode 100644 index 0000000000000..60fa5e70b0a73 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit1.symbols @@ -0,0 +1,146 @@ +=== tests/cases/conformance/jsx/tsxReactEmit1.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxReactEmit1.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxReactEmit1.tsx, 0, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(tsxReactEmit1.tsx, 3, 3)) + } +} + +var p; +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) + +var selfClosed1 =
; +>selfClosed1 : Symbol(selfClosed1, Decl(tsxReactEmit1.tsx, 8, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) + +var selfClosed2 =
; +>selfClosed2 : Symbol(selfClosed2, Decl(tsxReactEmit1.tsx, 9, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>x : Symbol(unknown) + +var selfClosed3 =
; +>selfClosed3 : Symbol(selfClosed3, Decl(tsxReactEmit1.tsx, 10, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>x : Symbol(unknown) + +var selfClosed4 =
; +>selfClosed4 : Symbol(selfClosed4, Decl(tsxReactEmit1.tsx, 11, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + +var selfClosed5 =
; +>selfClosed5 : Symbol(selfClosed5, Decl(tsxReactEmit1.tsx, 12, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + +var selfClosed6 =
; +>selfClosed6 : Symbol(selfClosed6, Decl(tsxReactEmit1.tsx, 13, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + +var selfClosed7 =
; +>selfClosed7 : Symbol(selfClosed7, Decl(tsxReactEmit1.tsx, 14, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) +>b : Symbol(unknown) + +var openClosed1 =
; +>openClosed1 : Symbol(openClosed1, Decl(tsxReactEmit1.tsx, 16, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) + +var openClosed2 =
foo
; +>openClosed2 : Symbol(openClosed2, Decl(tsxReactEmit1.tsx, 17, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>n : Symbol(unknown) + +var openClosed3 =
{p}
; +>openClosed3 : Symbol(openClosed3, Decl(tsxReactEmit1.tsx, 18, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>n : Symbol(unknown) + +var openClosed4 =
{p < p}
; +>openClosed4 : Symbol(openClosed4, Decl(tsxReactEmit1.tsx, 19, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>n : Symbol(unknown) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) + +var openClosed5 =
{p > p}
; +>openClosed5 : Symbol(openClosed5, Decl(tsxReactEmit1.tsx, 20, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>n : Symbol(unknown) +>b : Symbol(unknown) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) + +class SomeClass { +>SomeClass : Symbol(SomeClass, Decl(tsxReactEmit1.tsx, 20, 45)) + + f() { +>f : Symbol(f, Decl(tsxReactEmit1.tsx, 22, 17)) + + var rewrites1 =
{() => this}
; +>rewrites1 : Symbol(rewrites1, Decl(tsxReactEmit1.tsx, 24, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>this : Symbol(SomeClass, Decl(tsxReactEmit1.tsx, 20, 45)) + + var rewrites2 =
{[p, ...p, p]}
; +>rewrites2 : Symbol(rewrites2, Decl(tsxReactEmit1.tsx, 25, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) + + var rewrites3 =
{{p}}
; +>rewrites3 : Symbol(rewrites3, Decl(tsxReactEmit1.tsx, 26, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 26, 25)) + + var rewrites4 =
this}>
; +>rewrites4 : Symbol(rewrites4, Decl(tsxReactEmit1.tsx, 28, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>a : Symbol(unknown) +>this : Symbol(SomeClass, Decl(tsxReactEmit1.tsx, 20, 45)) + + var rewrites5 =
; +>rewrites5 : Symbol(rewrites5, Decl(tsxReactEmit1.tsx, 29, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>a : Symbol(unknown) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 7, 3)) + + var rewrites6 =
; +>rewrites6 : Symbol(rewrites6, Decl(tsxReactEmit1.tsx, 30, 5)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) +>a : Symbol(unknown) +>p : Symbol(p, Decl(tsxReactEmit1.tsx, 30, 27)) + } +} + +var whitespace1 =
; +>whitespace1 : Symbol(whitespace1, Decl(tsxReactEmit1.tsx, 34, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) + +var whitespace2 =
{p}
; +>whitespace2 : Symbol(whitespace2, Decl(tsxReactEmit1.tsx, 35, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) + +var whitespace3 =
+>whitespace3 : Symbol(whitespace3, Decl(tsxReactEmit1.tsx, 36, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit1.tsx, 1, 22)) + + {p} +
; + diff --git a/tests/baselines/reference/tsxReactEmit1.types b/tests/baselines/reference/tsxReactEmit1.types new file mode 100644 index 0000000000000..d23cad4560a27 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit1.types @@ -0,0 +1,196 @@ +=== tests/cases/conformance/jsx/tsxReactEmit1.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +var p; +>p : any + +var selfClosed1 =
; +>selfClosed1 : JSX.Element +>
: JSX.Element +>div : any + +var selfClosed2 =
; +>selfClosed2 : JSX.Element +>
: JSX.Element +>div : any +>x : any + +var selfClosed3 =
; +>selfClosed3 : JSX.Element +>
: JSX.Element +>div : any +>x : any + +var selfClosed4 =
; +>selfClosed4 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>y : any + +var selfClosed5 =
; +>selfClosed5 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>y : any + +var selfClosed6 =
; +>selfClosed6 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>y : any + +var selfClosed7 =
; +>selfClosed7 : JSX.Element +>
: JSX.Element +>div : any +>x : any +>p : any +>y : any +>b : any + +var openClosed1 =
; +>openClosed1 : JSX.Element +>
: JSX.Element +>div : any +>div : any + +var openClosed2 =
foo
; +>openClosed2 : JSX.Element +>
foo
: JSX.Element +>div : any +>n : any +>div : any + +var openClosed3 =
{p}
; +>openClosed3 : JSX.Element +>
{p}
: JSX.Element +>div : any +>n : any +>p : any +>div : any + +var openClosed4 =
{p < p}
; +>openClosed4 : JSX.Element +>
{p < p}
: JSX.Element +>div : any +>n : any +>p < p : boolean +>p : any +>p : any +>div : any + +var openClosed5 =
{p > p}
; +>openClosed5 : JSX.Element +>
{p > p}
: JSX.Element +>div : any +>n : any +>b : any +>p > p : boolean +>p : any +>p : any +>div : any + +class SomeClass { +>SomeClass : SomeClass + + f() { +>f : () => void + + var rewrites1 =
{() => this}
; +>rewrites1 : JSX.Element +>
{() => this}
: JSX.Element +>div : any +>() => this : () => SomeClass +>this : SomeClass +>div : any + + var rewrites2 =
{[p, ...p, p]}
; +>rewrites2 : JSX.Element +>
{[p, ...p, p]}
: JSX.Element +>div : any +>[p, ...p, p] : any[] +>p : any +>...p : any +>p : any +>p : any +>div : any + + var rewrites3 =
{{p}}
; +>rewrites3 : JSX.Element +>
{{p}}
: JSX.Element +>div : any +>{p} : { p: any; } +>p : any +>div : any + + var rewrites4 =
this}>
; +>rewrites4 : JSX.Element +>
this}>
: JSX.Element +>div : any +>a : any +>() => this : () => SomeClass +>this : SomeClass +>div : any + + var rewrites5 =
; +>rewrites5 : JSX.Element +>
: JSX.Element +>div : any +>a : any +>[p, ...p, p] : any[] +>p : any +>...p : any +>p : any +>p : any +>div : any + + var rewrites6 =
; +>rewrites6 : JSX.Element +>
: JSX.Element +>div : any +>a : any +>{p} : { p: any; } +>p : any +>div : any + } +} + +var whitespace1 =
; +>whitespace1 : JSX.Element +>
: JSX.Element +>div : any +>div : any + +var whitespace2 =
{p}
; +>whitespace2 : JSX.Element +>
{p}
: JSX.Element +>div : any +>p : any +>div : any + +var whitespace3 =
+>whitespace3 : JSX.Element +>
{p}
: JSX.Element +>div : any + + {p} +>p : any + +
; +>div : any + diff --git a/tests/baselines/reference/tsxReactEmit2.js b/tests/baselines/reference/tsxReactEmit2.js new file mode 100644 index 0000000000000..f4a12946ed98f --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit2.js @@ -0,0 +1,23 @@ +//// [tsxReactEmit2.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p1, p2, p3; +var spreads1 =
{p2}
; +var spreads2 =
{p2}
; +var spreads3 =
{p2}
; +var spreads4 =
{p2}
; +var spreads5 =
{p2}
; + + +//// [tsxReactEmit2.js] +var p1, p2, p3; +var spreads1 = React.createElement("div", React.__spread({}, p1), p2); +var spreads2 = React.createElement("div", React.__spread({}, p1), p2); +var spreads3 = React.createElement("div", React.__spread({x: p3}, p1), p2); +var spreads4 = React.createElement("div", React.__spread({}, p1, {x: p3}), p2); +var spreads5 = React.createElement("div", React.__spread({x: p2}, p1, {y: p3}), p2); diff --git a/tests/baselines/reference/tsxReactEmit2.symbols b/tests/baselines/reference/tsxReactEmit2.symbols new file mode 100644 index 0000000000000..9607d9330da48 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit2.symbols @@ -0,0 +1,44 @@ +=== tests/cases/conformance/jsx/tsxReactEmit2.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxReactEmit2.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxReactEmit2.tsx, 0, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(tsxReactEmit2.tsx, 3, 3)) + } +} + +var p1, p2, p3; +>p1 : Symbol(p1, Decl(tsxReactEmit2.tsx, 7, 3)) +>p2 : Symbol(p2, Decl(tsxReactEmit2.tsx, 7, 7)) +>p3 : Symbol(p3, Decl(tsxReactEmit2.tsx, 7, 11)) + +var spreads1 =
{p2}
; +>spreads1 : Symbol(spreads1, Decl(tsxReactEmit2.tsx, 8, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22)) + +var spreads2 =
{p2}
; +>spreads2 : Symbol(spreads2, Decl(tsxReactEmit2.tsx, 9, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22)) + +var spreads3 =
{p2}
; +>spreads3 : Symbol(spreads3, Decl(tsxReactEmit2.tsx, 10, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22)) +>x : Symbol(unknown) + +var spreads4 =
{p2}
; +>spreads4 : Symbol(spreads4, Decl(tsxReactEmit2.tsx, 11, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22)) +>x : Symbol(unknown) + +var spreads5 =
{p2}
; +>spreads5 : Symbol(spreads5, Decl(tsxReactEmit2.tsx, 12, 3)) +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmit2.tsx, 1, 22)) +>x : Symbol(unknown) +>y : Symbol(unknown) + diff --git a/tests/baselines/reference/tsxReactEmit2.types b/tests/baselines/reference/tsxReactEmit2.types new file mode 100644 index 0000000000000..9f8d6e494d0dd --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit2.types @@ -0,0 +1,68 @@ +=== tests/cases/conformance/jsx/tsxReactEmit2.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +var p1, p2, p3; +>p1 : any +>p2 : any +>p3 : any + +var spreads1 =
{p2}
; +>spreads1 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>p1 : any +>p2 : any +>div : any + +var spreads2 =
{p2}
; +>spreads2 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>p1 : any +>p2 : any +>div : any + +var spreads3 =
{p2}
; +>spreads3 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>x : any +>p3 : any +>p1 : any +>p2 : any +>div : any + +var spreads4 =
{p2}
; +>spreads4 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>p1 : any +>x : any +>p3 : any +>p2 : any +>div : any + +var spreads5 =
{p2}
; +>spreads5 : JSX.Element +>
{p2}
: JSX.Element +>div : any +>x : any +>p2 : any +>p1 : any +>y : any +>p3 : any +>p2 : any +>div : any + diff --git a/tests/baselines/reference/tsxReactEmit3.js b/tests/baselines/reference/tsxReactEmit3.js new file mode 100644 index 0000000000000..d31fec1c55035 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit3.js @@ -0,0 +1,10 @@ +//// [tsxReactEmit3.tsx] + +declare module JSX { interface Element { } } + +declare var Foo, Bar, baz; + + q s ; + +//// [tsxReactEmit3.js] +React.createElement(Foo, null, React.createElement(Bar, null, "q "), React.createElement(Bar, null), "s ", React.createElement(Bar, null), React.createElement(Bar, null)); diff --git a/tests/baselines/reference/tsxReactEmit3.symbols b/tests/baselines/reference/tsxReactEmit3.symbols new file mode 100644 index 0000000000000..8ef0ccab2419a --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit3.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/jsx/tsxReactEmit3.tsx === + +declare module JSX { interface Element { } } +>JSX : Symbol(JSX, Decl(tsxReactEmit3.tsx, 0, 0)) +>Element : Symbol(Element, Decl(tsxReactEmit3.tsx, 1, 20)) + +declare var Foo, Bar, baz; +>Foo : Symbol(Foo, Decl(tsxReactEmit3.tsx, 3, 11)) +>Bar : Symbol(Bar, Decl(tsxReactEmit3.tsx, 3, 16)) +>baz : Symbol(baz, Decl(tsxReactEmit3.tsx, 3, 21)) + + q s ; +>Foo : Symbol(Foo, Decl(tsxReactEmit3.tsx, 3, 11)) +>Bar : Symbol(Bar, Decl(tsxReactEmit3.tsx, 3, 16)) +>Bar : Symbol(Bar, Decl(tsxReactEmit3.tsx, 3, 16)) +>Bar : Symbol(Bar, Decl(tsxReactEmit3.tsx, 3, 16)) +>Bar : Symbol(Bar, Decl(tsxReactEmit3.tsx, 3, 16)) + diff --git a/tests/baselines/reference/tsxReactEmit3.types b/tests/baselines/reference/tsxReactEmit3.types new file mode 100644 index 0000000000000..9e5d9fece5642 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit3.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/jsx/tsxReactEmit3.tsx === + +declare module JSX { interface Element { } } +>JSX : any +>Element : Element + +declare var Foo, Bar, baz; +>Foo : any +>Bar : any +>baz : any + + q s ; +> q s : JSX.Element +>Foo : any +> q : JSX.Element +>Bar : any +>Bar : any +> : JSX.Element +>Bar : any +> : JSX.Element +>Bar : any +> : JSX.Element +>Bar : any +>Foo : any + diff --git a/tests/baselines/reference/tsxReactEmit4.errors.txt b/tests/baselines/reference/tsxReactEmit4.errors.txt new file mode 100644 index 0000000000000..00b7cb8d019ec --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit4.errors.txt @@ -0,0 +1,22 @@ +tests/cases/conformance/jsx/tsxReactEmit4.tsx(11,5): error TS2304: Cannot find name 'blah'. + + +==== tests/cases/conformance/jsx/tsxReactEmit4.tsx (1 errors) ==== + declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } + } + + var p; + var openClosed1 =
+ + {blah} + ~~~~ +!!! error TS2304: Cannot find name 'blah'. + +
; + + // Should emit React.__spread({}, p, {x: 0}) + var spread1 =
; \ No newline at end of file diff --git a/tests/baselines/reference/tsxReactEmit4.js b/tests/baselines/reference/tsxReactEmit4.js new file mode 100644 index 0000000000000..2254c4dd651c4 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmit4.js @@ -0,0 +1,23 @@ +//// [tsxReactEmit4.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p; +var openClosed1 =
+ + {blah} + +
; + +// Should emit React.__spread({}, p, {x: 0}) +var spread1 =
; + +//// [tsxReactEmit4.js] +var p; +var openClosed1 = React.createElement("div", null, blah); +// Should emit React.__spread({}, p, {x: 0}) +var spread1 = React.createElement("div", React.__spread({}, p, {x: 0})); diff --git a/tests/baselines/reference/tsxReactEmitWhitespace.js b/tests/baselines/reference/tsxReactEmitWhitespace.js new file mode 100644 index 0000000000000..2f32295c279fa --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitWhitespace.js @@ -0,0 +1,75 @@ +//// [tsxReactEmitWhitespace.tsx] +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +// THIS FILE HAS TEST-SIGNIFICANT LEADING/TRAILING +// WHITESPACE, DO NOT RUN 'FORMAT DOCUMENT' ON IT + +var p = 0; +// Emit " " +
; +// Emit " ", p, " " +
{p}
; +// Emit only p +
+ {p} +
; + +// Emit only p +
+ {p} +
; + +// Emit " 3" +
3 +
; + +// Emit " 3 " +
3
; + +// Emit "3" +
+ 3 +
; + +// Emit no args +
+
; + +// Emit "foo" + ' ' + "bar" +
+ + foo + + bar + +
; + + + +//// [tsxReactEmitWhitespace.js] +// THIS FILE HAS TEST-SIGNIFICANT LEADING/TRAILING +// WHITESPACE, DO NOT RUN 'FORMAT DOCUMENT' ON IT +var p = 0; +// Emit " " +React.createElement("div", null); +// Emit " ", p, " " +React.createElement("div", null, p); +// Emit only p +React.createElement("div", null, p); +// Emit only p +React.createElement("div", null, p); +// Emit " 3" +React.createElement("div", null, "3"); +// Emit " 3 " +React.createElement("div", null, "3 "); +// Emit "3" +React.createElement("div", null, "3"); +// Emit no args +React.createElement("div", null); +// Emit "foo" + ' ' + "bar" +React.createElement("div", null, "foo" + ' ' + "bar"); diff --git a/tests/baselines/reference/tsxReactEmitWhitespace.symbols b/tests/baselines/reference/tsxReactEmitWhitespace.symbols new file mode 100644 index 0000000000000..afbb694498197 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitWhitespace.symbols @@ -0,0 +1,77 @@ +=== tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(tsxReactEmitWhitespace.tsx, 0, 0)) + + interface Element { } +>Element : Symbol(Element, Decl(tsxReactEmitWhitespace.tsx, 0, 20)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + + [s: string]: any; +>s : Symbol(s, Decl(tsxReactEmitWhitespace.tsx, 3, 3)) + } +} + +// THIS FILE HAS TEST-SIGNIFICANT LEADING/TRAILING +// WHITESPACE, DO NOT RUN 'FORMAT DOCUMENT' ON IT + +var p = 0; +>p : Symbol(p, Decl(tsxReactEmitWhitespace.tsx, 10, 3)) + +// Emit " " +
; +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + +// Emit " ", p, " " +
{p}
; +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + +// Emit only p +
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + + {p} +
; + +// Emit only p +
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + + {p} +
; + +// Emit " 3" +
3 +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + +
; + +// Emit " 3 " +
3
; +>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + +// Emit "3" +
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + + 3 +
; + +// Emit no args +
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + +
; + +// Emit "foo" + ' ' + "bar" +
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxReactEmitWhitespace.tsx, 1, 22)) + + foo + + bar + +
; + + diff --git a/tests/baselines/reference/tsxReactEmitWhitespace.types b/tests/baselines/reference/tsxReactEmitWhitespace.types new file mode 100644 index 0000000000000..e0e3639fa9b20 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitWhitespace.types @@ -0,0 +1,101 @@ +=== tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx === +declare module JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + [s: string]: any; +>s : string + } +} + +// THIS FILE HAS TEST-SIGNIFICANT LEADING/TRAILING +// WHITESPACE, DO NOT RUN 'FORMAT DOCUMENT' ON IT + +var p = 0; +>p : number +>0 : number + +// Emit " " +
; +>
: JSX.Element +>div : any +>div : any + +// Emit " ", p, " " +
{p}
; +>
{p}
: JSX.Element +>div : any +>p : any +>div : any + +// Emit only p +
+>
{p}
: JSX.Element +>div : any + + {p} +>p : any + +
; +>div : any + +// Emit only p +
+>
{p}
: JSX.Element +>div : any + + {p} +>p : any + +
; +>div : any + +// Emit " 3" +
3 +>
3
: JSX.Element +>div : any + +
; +>div : any + +// Emit " 3 " +
3
; +>
3
: JSX.Element +>div : any +>div : any + +// Emit "3" +
+>
3
: JSX.Element +>div : any + + 3 +
; +>div : any + +// Emit no args +
+>
: JSX.Element +>div : any + +
; +>div : any + +// Emit "foo" + ' ' + "bar" +
+>
foo bar
: JSX.Element +>div : any + + foo + + bar + +
; +>div : any + + diff --git a/tests/baselines/reference/tsxTypeErrors.js b/tests/baselines/reference/tsxTypeErrors.js new file mode 100644 index 0000000000000..f195a459747bd --- /dev/null +++ b/tests/baselines/reference/tsxTypeErrors.js @@ -0,0 +1,60 @@ +//// [tsxTypeErrors.tsx] + +// A built-in element (OK) +var a1 =
; + +// A built-in element with a mistyped property (error) +var a2 = + +// A built-in element with a badly-typed attribute value (error) +var thing = { oops: 100 }; +var a3 =
+ +// Mistyped html name (error) +var e1 = + +// A custom type +class MyClass { + props: { + pt?: { x: number; y: number; }; + name?: string; + reqd: boolean; + } +} + +// Let's use it +// TODO: Error on missing 'reqd' +var b1 = ; + +// Mistyped attribute member +// sample.tsx(23,22): error TS2322: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'. +// Types of property 'y' are incompatible. +// Type 'string' is not assignable to type 'number'. +var b2 = ; + + + +//// [tsxTypeErrors.jsx] +// A built-in element (OK) +var a1 =
; +// A built-in element with a mistyped property (error) +var a2 = ; +// A built-in element with a badly-typed attribute value (error) +var thing = { oops: 100 }; +var a3 =
; +// Mistyped html name (error) +var e1 = ; +// A custom type +var MyClass = (function () { + function MyClass() { + } + return MyClass; +})(); +// Let's use it +// TODO: Error on missing 'reqd' +var b1 = ; +// Mistyped attribute member +// sample.tsx(23,22): error TS2322: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'. +// Types of property 'y' are incompatible. +// Type 'string' is not assignable to type 'number'. +var b2 = ; diff --git a/tests/baselines/reference/tsxTypeErrors.symbols b/tests/baselines/reference/tsxTypeErrors.symbols new file mode 100644 index 0000000000000..bfe0c5686403e --- /dev/null +++ b/tests/baselines/reference/tsxTypeErrors.symbols @@ -0,0 +1,65 @@ +=== tests/cases/conformance/jsx/tsxTypeErrors.tsx === + +// A built-in element (OK) +var a1 =
; +>a1 : Symbol(a1, Decl(tsxTypeErrors.tsx, 2, 3)) +>id : Symbol(unknown) + +// A built-in element with a mistyped property (error) +var a2 = +>a2 : Symbol(a2, Decl(tsxTypeErrors.tsx, 5, 3)) +>srce : Symbol(unknown) + +// A built-in element with a badly-typed attribute value (error) +var thing = { oops: 100 }; +>thing : Symbol(thing, Decl(tsxTypeErrors.tsx, 8, 3)) +>oops : Symbol(oops, Decl(tsxTypeErrors.tsx, 8, 13)) + +var a3 =
+>a3 : Symbol(a3, Decl(tsxTypeErrors.tsx, 9, 3)) +>id : Symbol(unknown) + +// Mistyped html name (error) +var e1 = +>e1 : Symbol(e1, Decl(tsxTypeErrors.tsx, 12, 3)) +>src : Symbol(unknown) + +// A custom type +class MyClass { +>MyClass : Symbol(MyClass, Decl(tsxTypeErrors.tsx, 12, 31)) + + props: { +>props : Symbol(props, Decl(tsxTypeErrors.tsx, 15, 15)) + + pt?: { x: number; y: number; }; +>pt : Symbol(pt, Decl(tsxTypeErrors.tsx, 16, 10)) +>x : Symbol(x, Decl(tsxTypeErrors.tsx, 17, 10)) +>y : Symbol(y, Decl(tsxTypeErrors.tsx, 17, 21)) + + name?: string; +>name : Symbol(name, Decl(tsxTypeErrors.tsx, 17, 35)) + + reqd: boolean; +>reqd : Symbol(reqd, Decl(tsxTypeErrors.tsx, 18, 15)) + } +} + +// Let's use it +// TODO: Error on missing 'reqd' +var b1 = ; +>b1 : Symbol(b1, Decl(tsxTypeErrors.tsx, 25, 3)) +>MyClass : Symbol(MyClass, Decl(tsxTypeErrors.tsx, 12, 31)) +>reqd : Symbol(unknown) + +// Mistyped attribute member +// sample.tsx(23,22): error TS2322: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'. +// Types of property 'y' are incompatible. +// Type 'string' is not assignable to type 'number'. +var b2 = ; +>b2 : Symbol(b2, Decl(tsxTypeErrors.tsx, 31, 3)) +>MyClass : Symbol(MyClass, Decl(tsxTypeErrors.tsx, 12, 31)) +>pt : Symbol(unknown) +>x : Symbol(x, Decl(tsxTypeErrors.tsx, 31, 23)) +>y : Symbol(y, Decl(tsxTypeErrors.tsx, 31, 28)) + + diff --git a/tests/baselines/reference/tsxTypeErrors.types b/tests/baselines/reference/tsxTypeErrors.types new file mode 100644 index 0000000000000..92c7148b3147f --- /dev/null +++ b/tests/baselines/reference/tsxTypeErrors.types @@ -0,0 +1,82 @@ +=== tests/cases/conformance/jsx/tsxTypeErrors.tsx === + +// A built-in element (OK) +var a1 =
; +>a1 : any +>
: any +>div : any +>id : any + +// A built-in element with a mistyped property (error) +var a2 = +>a2 : any +> : any +>img : any +>srce : any + +// A built-in element with a badly-typed attribute value (error) +var thing = { oops: 100 }; +>thing : { oops: number; } +>{ oops: 100 } : { oops: number; } +>oops : number +>100 : number + +var a3 =
+>a3 : any +>
: any +>div : any +>id : any +>thing : any + +// Mistyped html name (error) +var e1 = +>e1 : any +> : any +>imag : any +>src : any + +// A custom type +class MyClass { +>MyClass : MyClass + + props: { +>props : { pt?: { x: number; y: number; }; name?: string; reqd: boolean; } + + pt?: { x: number; y: number; }; +>pt : { x: number; y: number; } +>x : number +>y : number + + name?: string; +>name : string + + reqd: boolean; +>reqd : boolean + } +} + +// Let's use it +// TODO: Error on missing 'reqd' +var b1 = ; +>b1 : any +> : any +>MyClass : typeof MyClass +>reqd : any +>true : boolean + +// Mistyped attribute member +// sample.tsx(23,22): error TS2322: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'. +// Types of property 'y' are incompatible. +// Type 'string' is not assignable to type 'number'. +var b2 = ; +>b2 : any +> : any +>MyClass : typeof MyClass +>pt : any +>{x: 4, y: 'oops'} : { x: number; y: string; } +>x : number +>4 : number +>y : string +>'oops' : string + + diff --git a/tests/cases/conformance/expressions/asOperator/asOperator1.ts b/tests/cases/conformance/expressions/asOperator/asOperator1.ts new file mode 100644 index 0000000000000..cf953d75ab46e --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOperator1.ts @@ -0,0 +1,8 @@ +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 = ''; diff --git a/tests/cases/conformance/expressions/asOperator/asOperator2.ts b/tests/cases/conformance/expressions/asOperator/asOperator2.ts new file mode 100644 index 0000000000000..1fa5f2c938d78 --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOperator2.ts @@ -0,0 +1 @@ +var x = 23 as string; diff --git a/tests/cases/conformance/expressions/asOperator/asOperator3.ts b/tests/cases/conformance/expressions/asOperator/asOperator3.ts new file mode 100644 index 0000000000000..4c136247e001f --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOperator3.ts @@ -0,0 +1,10 @@ +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; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/asOperator/asOperatorASI.ts b/tests/cases/conformance/expressions/asOperator/asOperatorASI.ts new file mode 100644 index 0000000000000..a4dd44a15add1 --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOperatorASI.ts @@ -0,0 +1,10 @@ +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 diff --git a/tests/cases/conformance/expressions/asOperator/asOperatorAmbiguity.ts b/tests/cases/conformance/expressions/asOperator/asOperatorAmbiguity.ts new file mode 100644 index 0000000000000..e4921314ba7e7 --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOperatorAmbiguity.ts @@ -0,0 +1,8 @@ +interface A { 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[]; +var z = y[0].m; // z should be string + diff --git a/tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts b/tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts new file mode 100644 index 0000000000000..d3a23e224ba3d --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts @@ -0,0 +1,2 @@ +// should error +var x = (v => v) as (x: number) => string; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/asOperator/asOperatorNames.ts b/tests/cases/conformance/expressions/asOperator/asOperatorNames.ts new file mode 100644 index 0000000000000..a0b54d43e8451 --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOperatorNames.ts @@ -0,0 +1,4 @@ +var a = 20; +var b = a as string; +var as = "hello"; +var as1 = as as string; diff --git a/tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx b/tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx new file mode 100644 index 0000000000000..b20dea210a98f --- /dev/null +++ b/tests/cases/conformance/jsx/jsxAndTypeAssertion.tsx @@ -0,0 +1,22 @@ +// @jsx: preserve + +declare var createElement: any; + +class foo {} + +var x: any; +x = { test: }; + +x = ; + +x = hello {{}} ; + +x = {}}>hello; + +x = {}}>hello{{}}; + +x = x, x = ; + +{{/foo/.test(x) ? : }} + + diff --git a/tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx b/tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx new file mode 100644 index 0000000000000..163357454aacc --- /dev/null +++ b/tests/cases/conformance/jsx/jsxEsprimaFbTestSuite.tsx @@ -0,0 +1,54 @@ +// @jsx: preserve +declare var React: any; +declare var 日本語; +declare var AbC_def; +declare var LeftRight; +declare var x; +declare var a; +declare var props; + +; + +//; Namespace unsuported + +// {value} ; Namespace unsuported + +; + +; +; + +<日本語>; + + +bar +baz +; + + : } />; + +{}; + +{/* this is a comment */}; + +
@test content
; + +

7x invalid-js-identifier
; + + right=monkeys /> gorillas />; + +; + +; + +(
) < x; + +
; + +
; + +
; + + ; diff --git a/tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx b/tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx new file mode 100644 index 0000000000000..815cd4abb217d --- /dev/null +++ b/tests/cases/conformance/jsx/jsxInvalidEsprimaTestSuite.tsx @@ -0,0 +1,36 @@ +// @jsx: preserve +declare var React: any; + +; +; +<:a />; +; +; +
; +; +; +
; +
; + +
stuff
; +
stuff
; + +
>; + >; +; +; +}; +; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/jsxReactTestSuite.tsx b/tests/cases/conformance/jsx/jsxReactTestSuite.tsx new file mode 100644 index 0000000000000..96b91987cbcc2 --- /dev/null +++ b/tests/cases/conformance/jsx/jsxReactTestSuite.tsx @@ -0,0 +1,117 @@ +// @jsx: preserve + +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; + +
text
; + +
+ {this.props.children} +
; + +
+

+ {foo}
{bar}
+
+
; + + + + {this.props.children} +; + + + +; + +var x = +
+
; + +( +
+ {/* A comment at the beginning */} + {/* A second comment at the beginning */} + + {/* A nested comment */} + + {/* A sandwiched comment */} +
+ {/* A comment at the end */} + {/* A second comment at the end */} +
+); + +( +
+ +
+); + +
 
; + +
 
; + +testing; + +; + +; + +; + +; + +; + +; + +; + +; + +; + +; + +; + +; + + +; + +Text; + + diff --git a/tests/cases/conformance/jsx/tsxAttributeErrors.tsx b/tests/cases/conformance/jsx/tsxAttributeErrors.tsx new file mode 100644 index 0000000000000..477135e15441f --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeErrors.tsx @@ -0,0 +1,26 @@ +// @jsx: preserve + +declare namespace JSX { + interface Element { } + interface IntrinsicElements { + div: { + text?: string; + width?: number; + } + + span: any; + } +} + +// Error, number is not assignable to string +
; + +// Error, string is not assignable to number +
; + +// Error, number is not assignable to string +var attribs = { text: 100 }; +
; + +// No errors here +; diff --git a/tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx b/tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx new file mode 100644 index 0000000000000..4471c5a9c9278 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeInvalidNames.tsx @@ -0,0 +1,13 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: { "data-foo"?: string }; + test2: { "data-foo"?: string }; + } +} + +// Invalid names +; +; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution.tsx new file mode 100644 index 0000000000000..3e5d8e3a7c85a --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution.tsx @@ -0,0 +1,9 @@ +//@jsx: preserve + +declare namespace JSX { + interface IntrinsicElements { + x: { y: number; z: string; }; + } +} + + diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution1.jsx b/tests/cases/conformance/jsx/tsxAttributeResolution1.jsx new file mode 100644 index 0000000000000..fb54f9d7c82b3 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution1.jsx @@ -0,0 +1,15 @@ +// OK +; // OK +; // OK +; // OK +; // OK +; // OK +// Errors +; // Error, '0' is not number +; // Error, no property "y" +; // Error, no property "y" +; // Error, "32" is not number +// TODO attribute 'var' should be parseable +// ; // Error, no 'var' property +; // Error, missing reqd +; // Error, reqd is not string diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution1.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution1.tsx new file mode 100644 index 0000000000000..edb203655efa8 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution1.tsx @@ -0,0 +1,33 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: Attribs1; + test2: { reqd: string }; + } +} +interface Attribs1 { + x?: number; + s?: string; +} + +// OK +; // OK +; // OK +; // OK + +; // OK +; // OK + +// Errors +; // Error, '0' is not number +; // Error, no property "y" +; // Error, no property "y" +; // Error, "32" is not number +// TODO attribute 'var' should be parseable +// ; // Error, no 'var' property + +; // Error, missing reqd +; // Error, reqd is not string + diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution2.jsx b/tests/cases/conformance/jsx/tsxAttributeResolution2.jsx new file mode 100644 index 0000000000000..7c47046dcdeb5 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution2.jsx @@ -0,0 +1,5 @@ +// OK +; // OK +; // OK +// Errors +; // Error, no leng on 'string' diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution2.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution2.tsx new file mode 100644 index 0000000000000..c9bc2de978a75 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution2.tsx @@ -0,0 +1,19 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: Attribs1; + } +} +interface Attribs1 { + c1?: (x: string) => void; +} + +// OK + x.length} />; // OK + x.leng} />; // OK + + +// Errors + x.leng} />; // Error, no leng on 'string' diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution3.jsx b/tests/cases/conformance/jsx/tsxAttributeResolution3.jsx new file mode 100644 index 0000000000000..46cb5d8ff6980 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution3.jsx @@ -0,0 +1,21 @@ +// OK +var obj1 = { x: 'foo' }; +; +// Error, x is not string +var obj2 = { x: 32 }; +; +// Error, x is missing +var obj3 = { y: 32 }; +; +// OK +var obj4 = { x: 32, y: 32 }; +; +// Error +var obj5 = { x: 32, y: 32 }; +; +// OK +var obj6 = { x: 'ok', y: 32, extra: 100 }; +; +// Error +var obj7 = { x: 'foo' }; +; diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx new file mode 100644 index 0000000000000..dc0c2fed8d638 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx @@ -0,0 +1,41 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: Attribs1; + } +} +interface Attribs1 { + x: string; + y?: number; + z?: string; +} + +// OK +var obj1 = { x: 'foo' }; + + +// Error, x is not string +var obj2 = { x: 32 }; + + +// Error, x is missing +var obj3 = { y: 32 }; + + +// OK +var obj4 = { x: 32, y: 32 }; + + +// Error +var obj5 = { x: 32, y: 32 }; + + +// OK +var obj6 = { x: 'ok', y: 32, extra: 100 }; + + +// Error +var obj7 = { x: 'foo' }; + diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution4.jsx b/tests/cases/conformance/jsx/tsxAttributeResolution4.jsx new file mode 100644 index 0000000000000..da2e1d12038c2 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution4.jsx @@ -0,0 +1,4 @@ +// OK +; +// Error, no member 'len' on 'string' +; diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution4.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution4.tsx new file mode 100644 index 0000000000000..caaad3559c31a --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution4.tsx @@ -0,0 +1,17 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: Attribs1; + } +} +interface Attribs1 { + x(n: string): void; +} + +// OK + 0} } />; + +// Error, no member 'len' on 'string' + n.len} } />; diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution5.jsx b/tests/cases/conformance/jsx/tsxAttributeResolution5.jsx new file mode 100644 index 0000000000000..3e4c89d06fb8a --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution5.jsx @@ -0,0 +1,11 @@ +function make1(obj) { + return ; // OK +} +function make2(obj) { + return ; // Error (x is number, not string) +} +function make3(obj) { + return ; // Error, missing x +} +; // Error, missing x +; // OK diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution5.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution5.tsx new file mode 100644 index 0000000000000..dd16ade10e31e --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution5.tsx @@ -0,0 +1,32 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: Attribs1; + test2: Attribs2; + } +} +interface Attribs1 { + x: string; +} + +interface Attribs2 { + toString(): string; +} + +function make1 (obj: T) { + return ; // OK +} + +function make2 (obj: T) { + return ; // Error (x is number, not string) +} + +function make3 (obj: T) { + return ; // Error, missing x +} + + +; // Error, missing x +; // OK diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution6.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution6.tsx new file mode 100644 index 0000000000000..b083247ba7a62 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution6.tsx @@ -0,0 +1,19 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: { n?: boolean; s?: string}; + test2: { n: boolean; }; + } +} + +// Error +; +; +; + +// OK +; +; +; diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution7.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution7.tsx new file mode 100644 index 0000000000000..1fc6a8731875c --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution7.tsx @@ -0,0 +1,16 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: { "data-foo"?: string }; + } +} + +// Error +; + +// OK +; +; +; diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution8.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution8.tsx new file mode 100644 index 0000000000000..ac99cd155930a --- /dev/null +++ b/tests/cases/conformance/jsx/tsxAttributeResolution8.tsx @@ -0,0 +1,12 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + test1: {x: string}; + } +} + +var x: any; +// Should be OK + \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxElementResolution.tsx b/tests/cases/conformance/jsx/tsxElementResolution.tsx new file mode 100644 index 0000000000000..e5c3c191f05a9 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution.tsx @@ -0,0 +1,25 @@ +//@jsx: preserve + +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 = ; +var b = ; +// TODO: This should not be a parse error (should +// parse a property name here, not identifier) +// var c = ; +var d = ; +var e = ; diff --git a/tests/cases/conformance/jsx/tsxElementResolution1.jsx b/tests/cases/conformance/jsx/tsxElementResolution1.jsx new file mode 100644 index 0000000000000..97357dbba8e74 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution1.jsx @@ -0,0 +1,4 @@ +// OK +
; +// Fail +; diff --git a/tests/cases/conformance/jsx/tsxElementResolution1.tsx b/tests/cases/conformance/jsx/tsxElementResolution1.tsx new file mode 100644 index 0000000000000..b9c1b91d05e31 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution1.tsx @@ -0,0 +1,14 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + div: any + } +} + +// OK +
; + +// Fail +; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxElementResolution10.tsx b/tests/cases/conformance/jsx/tsxElementResolution10.tsx new file mode 100644 index 0000000000000..526c0529e1bda --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution10.tsx @@ -0,0 +1,21 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface ElementClass { + render: any; + } + interface IntrinsicElements { } +} + +interface Obj1type { + new(n: string): { x: number }; +} +var Obj1: Obj1type; +; // Error, no render member + +interface Obj2type { + (n: string): { x: number; render: any; }; +} +var Obj2: Obj2type; +; // OK diff --git a/tests/cases/conformance/jsx/tsxElementResolution11.jsx b/tests/cases/conformance/jsx/tsxElementResolution11.jsx new file mode 100644 index 0000000000000..6349906508c23 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution11.jsx @@ -0,0 +1,6 @@ +var Obj1; +; // OK +var Obj2; +; // Error +var Obj3; +; // OK diff --git a/tests/cases/conformance/jsx/tsxElementResolution11.tsx b/tests/cases/conformance/jsx/tsxElementResolution11.tsx new file mode 100644 index 0000000000000..0fc74335500df --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution11.tsx @@ -0,0 +1,25 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface ElementAttributesProperty { } + interface IntrinsicElements { } +} + +interface Obj1type { + new(n: string): any; +} +var Obj1: Obj1type; +; // OK + +interface Obj2type { + new(n: string): { q?: number }; +} +var Obj2: Obj2type; +; // Error + +interface Obj3type { + new(n: string): { x: number; }; +} +var Obj3: Obj3type; +; // OK diff --git a/tests/cases/conformance/jsx/tsxElementResolution12.jsx b/tests/cases/conformance/jsx/tsxElementResolution12.jsx new file mode 100644 index 0000000000000..ef137fd0e2960 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution12.jsx @@ -0,0 +1,9 @@ +var obj1; +; // OK +var obj2; +; // OK +var obj3; +; // Error +var obj4; +; // OK +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution12.tsx b/tests/cases/conformance/jsx/tsxElementResolution12.tsx new file mode 100644 index 0000000000000..a5d8f2d812b4b --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution12.tsx @@ -0,0 +1,32 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface ElementAttributesProperty { pr: any; } + interface IntrinsicElements { } +} + +interface Obj1type { + new(n: string): any; +} +var Obj1: Obj1type; +; // OK + +interface Obj2type { + new(n: string): { q?: number; pr: any }; +} +var obj2: Obj2type; +; // OK + +interface Obj3type { + new(n: string): { x: number; }; +} +var Obj3: Obj3type; +; // Error + +interface Obj4type { + new(n: string): { x: number; pr: { x: number; } }; +} +var Obj4: Obj4type; +; // OK +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution13.jsx b/tests/cases/conformance/jsx/tsxElementResolution13.jsx new file mode 100644 index 0000000000000..6a55efa612d9f --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution13.jsx @@ -0,0 +1,2 @@ +var obj1; +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution13.tsx b/tests/cases/conformance/jsx/tsxElementResolution13.tsx new file mode 100644 index 0000000000000..32ee20afbfe19 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution13.tsx @@ -0,0 +1,12 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface ElementAttributesProperty { pr1: any; pr2: any; } +} + +interface Obj1 { + new(n: string): any; +} +var obj1: Obj1; +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution14.jsx b/tests/cases/conformance/jsx/tsxElementResolution14.jsx new file mode 100644 index 0000000000000..29df7710af1fe --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution14.jsx @@ -0,0 +1,2 @@ +var obj1; +; // OK diff --git a/tests/cases/conformance/jsx/tsxElementResolution14.tsx b/tests/cases/conformance/jsx/tsxElementResolution14.tsx new file mode 100644 index 0000000000000..f76af00bbeb5e --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution14.tsx @@ -0,0 +1,11 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } +} + +interface Obj1 { + new(n: string): {}; +} +var obj1: Obj1; +; // OK diff --git a/tests/cases/conformance/jsx/tsxElementResolution15.jsx b/tests/cases/conformance/jsx/tsxElementResolution15.jsx new file mode 100644 index 0000000000000..6a55efa612d9f --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution15.jsx @@ -0,0 +1,2 @@ +var obj1; +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution15.tsx b/tests/cases/conformance/jsx/tsxElementResolution15.tsx new file mode 100644 index 0000000000000..61cea63ce763c --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution15.tsx @@ -0,0 +1,13 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface ElementAttributesProperty { pr1: any; pr2: any; } + interface IntrinsicElements { } +} + +interface Obj1type { + new(n: string): {}; +} +var Obj1: Obj1type; +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution16.jsx b/tests/cases/conformance/jsx/tsxElementResolution16.jsx new file mode 100644 index 0000000000000..e1987489bbb44 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution16.jsx @@ -0,0 +1,2 @@ +var obj1; +; // Error (JSX.Element is missing) diff --git a/tests/cases/conformance/jsx/tsxElementResolution16.tsx b/tests/cases/conformance/jsx/tsxElementResolution16.tsx new file mode 100644 index 0000000000000..3b5b23d77f52d --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution16.tsx @@ -0,0 +1,11 @@ +//@filename: file.tsx +//@jsx: preserve +//@noImplicitAny: true +declare module JSX { +} + +interface Obj1 { + new(n: string): {}; +} +var obj1: Obj1; +; // Error (JSX.Element is implicit any) diff --git a/tests/cases/conformance/jsx/tsxElementResolution17.tsx b/tests/cases/conformance/jsx/tsxElementResolution17.tsx new file mode 100644 index 0000000000000..97777d76a5884 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution17.tsx @@ -0,0 +1,27 @@ +//@jsx: preserve +//@module: amd + +//@filename: file.tsx +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +declare module 'elements1' { + class MyElement { + + } +} + +declare module 'elements2' { + class MyElement { + + } +} + +//@filename: consumer.tsx +/// +// Should keep s1 and elide s2 +import s1 = require('elements1'); +import s2 = require('elements2'); +; diff --git a/tests/cases/conformance/jsx/tsxElementResolution18.tsx b/tests/cases/conformance/jsx/tsxElementResolution18.tsx new file mode 100644 index 0000000000000..89081d7629f06 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution18.tsx @@ -0,0 +1,9 @@ +//@jsx: preserve +//@filename: file1.tsx +//@noimplicitany: true +declare module JSX { + interface Element { } +} + +// Error under implicit any +
; diff --git a/tests/cases/conformance/jsx/tsxElementResolution2.tsx b/tests/cases/conformance/jsx/tsxElementResolution2.tsx new file mode 100644 index 0000000000000..75e4956e728be --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution2.tsx @@ -0,0 +1,14 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + [x: string]: any; + } +} + +// OK +
; + +// OK +; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxElementResolution3.tsx b/tests/cases/conformance/jsx/tsxElementResolution3.tsx new file mode 100644 index 0000000000000..c3f057c4ff5ae --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution3.tsx @@ -0,0 +1,14 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + [x: string]: { n: string; }; + } +} + +// OK +
; + +// Error +; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxElementResolution4.tsx b/tests/cases/conformance/jsx/tsxElementResolution4.tsx new file mode 100644 index 0000000000000..413ae6d5ed904 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution4.tsx @@ -0,0 +1,18 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + div: { n: string; }; + span: { m: string; }; + } +} + +// OK +
; + +// OK +; + +// Error +; diff --git a/tests/cases/conformance/jsx/tsxElementResolution5.tsx b/tests/cases/conformance/jsx/tsxElementResolution5.tsx new file mode 100644 index 0000000000000..c12c07d3e60b4 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution5.tsx @@ -0,0 +1,8 @@ +//@jsx: preserve +//@filename: file1.tsx +declare module JSX { + interface Element { } +} + +// OK, but implicit any +
; diff --git a/tests/cases/conformance/jsx/tsxElementResolution6.tsx b/tests/cases/conformance/jsx/tsxElementResolution6.tsx new file mode 100644 index 0000000000000..74d3324ea0f28 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution6.tsx @@ -0,0 +1,10 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +var div: any; +// Still an error +
; diff --git a/tests/cases/conformance/jsx/tsxElementResolution7.jsx b/tests/cases/conformance/jsx/tsxElementResolution7.jsx new file mode 100644 index 0000000000000..e95505539abba --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution7.jsx @@ -0,0 +1,14 @@ +var my; +(function (my) { +})(my || (my = {})); +// OK +; +// Error +; +var q; +(function (q) { + // OK + ; + // Error + ; +})(q || (q = {})); diff --git a/tests/cases/conformance/jsx/tsxElementResolution7.tsx b/tests/cases/conformance/jsx/tsxElementResolution7.tsx new file mode 100644 index 0000000000000..c7ab23e76eab8 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution7.tsx @@ -0,0 +1,22 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +module my { + export var div: any; +} +// OK +; +// Error +; + +module q { + import mine = my; + // OK + ; + // Error + ; +} diff --git a/tests/cases/conformance/jsx/tsxElementResolution8.jsx b/tests/cases/conformance/jsx/tsxElementResolution8.jsx new file mode 100644 index 0000000000000..e0f95dc6d2227 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution8.jsx @@ -0,0 +1,15 @@ +// Error +var div = 3; +
; +// OK +function fact() { return null; } +; +// Error +function fnum() { return 42; } +; +var obj1; +; // OK, prefer construct signatures +var obj2; +; // Error +var obj3; +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution8.tsx b/tests/cases/conformance/jsx/tsxElementResolution8.tsx new file mode 100644 index 0000000000000..624302da06203 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution8.tsx @@ -0,0 +1,36 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +// Error +var Div = 3; +
; + +// OK +function Fact(): any { return null; } + + +// Error +function Fnum(): number{ return 42; } + + +interface Obj1 { + new(): {}; + (): number; +} +var Obj1: Obj1; +; // OK, prefer construct signatures + +interface Obj2 { + (): number; +} +var Obj2: Obj2; +; // Error + +interface Obj3 { +} +var Obj3: Obj3; +; // Error diff --git a/tests/cases/conformance/jsx/tsxElementResolution9.jsx b/tests/cases/conformance/jsx/tsxElementResolution9.jsx new file mode 100644 index 0000000000000..2b62d86eac5f9 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution9.jsx @@ -0,0 +1,6 @@ +var obj1; +; // Error, return type is not an object type +var obj2; +; // Error, return type is not an object type +var obj3; +; // OK diff --git a/tests/cases/conformance/jsx/tsxElementResolution9.tsx b/tests/cases/conformance/jsx/tsxElementResolution9.tsx new file mode 100644 index 0000000000000..7165f8277b339 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxElementResolution9.tsx @@ -0,0 +1,27 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +interface Obj1 { + new(n: string): { x: number }; + new(n: number): { y: string }; +} +var Obj1: Obj1; +; // Error, return type is not an object type + +interface Obj2 { + (n: string): { x: number }; + (n: number): { y: string }; +} +var Obj2: Obj2; +; // Error, return type is not an object type + +interface Obj3 { + (n: string): { x: number }; + (n: number): { x: number; y: string }; +} +var Obj3: Obj3; +; // OK diff --git a/tests/cases/conformance/jsx/tsxEmit1.jsx b/tests/cases/conformance/jsx/tsxEmit1.jsx new file mode 100644 index 0000000000000..45ca6e2469f38 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxEmit1.jsx @@ -0,0 +1,34 @@ +var p; +/* +var selfClosed1 =
; +var selfClosed2 =
; +var selfClosed3 =
; +var selfClosed4 =
; +var selfClosed5 =
; +var selfClosed6 =
; +var selfClosed7 =
; + +var openClosed1 =
; +var openClosed2 =
foo
; +var openClosed3 =
{p}
; +var openClosed4 =
{p < p}
; +var openClosed5 =
{p > p}
; +*/ +var SomeClass = (function () { + function SomeClass() { + } + SomeClass.prototype.f = function () { + var _this = this; + var rewrites1 =
{function () { return _this; }}
; + var rewrites4 =
; + }; + return SomeClass; +})(); +/* +var q = () => this; +var rewrites2 =
{[p, ...p, p]}
; +var rewrites3 =
{{p}}
; + +var rewrites5 =
; +var rewrites6 =
; +*/ diff --git a/tests/cases/conformance/jsx/tsxEmit1.tsx b/tests/cases/conformance/jsx/tsxEmit1.tsx new file mode 100644 index 0000000000000..9f3d9ca3a5e25 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxEmit1.tsx @@ -0,0 +1,41 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p; +var selfClosed1 =
; +var selfClosed2 =
; +var selfClosed3 =
; +var selfClosed4 =
; +var selfClosed5 =
; +var selfClosed6 =
; +var selfClosed7 =
; + +var openClosed1 =
; +var openClosed2 =
foo
; +var openClosed3 =
{p}
; +var openClosed4 =
{p < p}
; +var openClosed5 =
{p > p}
; + +class SomeClass { + f() { + var rewrites1 =
{() => this}
; + var rewrites2 =
{[p, ...p, p]}
; + var rewrites3 =
{{p}}
; + + var rewrites4 =
this}>
; + var rewrites5 =
; + var rewrites6 =
; + } +} + +var whitespace1 =
; +var whitespace2 =
{p}
; +var whitespace3 =
+ {p} +
; diff --git a/tests/cases/conformance/jsx/tsxEmit2.tsx b/tests/cases/conformance/jsx/tsxEmit2.tsx new file mode 100644 index 0000000000000..24f51a4583d86 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxEmit2.tsx @@ -0,0 +1,15 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p1, p2, p3; +var spreads1 =
{p2}
; +var spreads2 =
{p2}
; +var spreads3 =
{p2}
; +var spreads4 =
{p2}
; +var spreads5 =
{p2}
; diff --git a/tests/cases/conformance/jsx/tsxEmit3.jsx b/tests/cases/conformance/jsx/tsxEmit3.jsx new file mode 100644 index 0000000000000..7c979051d00b3 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxEmit3.jsx @@ -0,0 +1,41 @@ +var M; +(function (M) { + var Foo = (function () { + function Foo() { + } + return Foo; + })(); + M.Foo = Foo; + var S; + (function (S) { + var Bar = (function () { + function Bar() { + } + return Bar; + })(); + S.Bar = Bar; + })(S = M.S || (M.S = {})); +})(M || (M = {})); +var M; +(function (M) { + // Emit M.Foo + M.Foo, ; + var S; + (function (S) { + // Emit M.Foo + M.Foo, ; + // Emit S.Bar + S.Bar, ; + })(S = M.S || (M.S = {})); +})(M || (M = {})); +var M; +(function (M) { + // Emit M.S.Bar + M.S.Bar, ; +})(M || (M = {})); +var M; +(function (M_1) { + var M = 100; + // Emit M_1.Foo + M_1.Foo, ; +})(M || (M = {})); diff --git a/tests/cases/conformance/jsx/tsxEmit3.tsx b/tests/cases/conformance/jsx/tsxEmit3.tsx new file mode 100644 index 0000000000000..b3c3350dd116f --- /dev/null +++ b/tests/cases/conformance/jsx/tsxEmit3.tsx @@ -0,0 +1,41 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { } +} + +module M { + export class Foo { constructor() { } } + export module S { + export class Bar { } + + // Emit Foo + // Foo, ; + } +} + +module M { + // Emit M.Foo + Foo, ; + + export module S { + // Emit M.Foo + Foo, ; + + // Emit S.Bar + Bar, ; + } + +} + +module M { + // Emit M.S.Bar + S.Bar, ; +} + +module M { + var M = 100; + // Emit M_1.Foo + Foo, ; +} diff --git a/tests/cases/conformance/jsx/tsxErrorRecovery1.tsx b/tests/cases/conformance/jsx/tsxErrorRecovery1.tsx new file mode 100644 index 0000000000000..881b3c95376d9 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxErrorRecovery1.tsx @@ -0,0 +1,10 @@ +//@filename: file.tsx +//@jsx: preserve + +declare namespace JSX { interface Element { } } + +function foo() { + var x =
{
+} +// Shouldn't see any errors down here +var y = { a: 1 }; diff --git a/tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx b/tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx new file mode 100644 index 0000000000000..b3d3d34020a98 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxGenericArrowFunctionParsing.tsx @@ -0,0 +1,28 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { isElement; } +} + +var T, T1, T2; + +// This is an element +var x1 = () => {}; +x1.isElement; + +// This is a generic function +var x2 = () => {}; +x2(); + +// This is a generic function +var x3 = () => {}; +x3(); + +// This is an element +var x4 = () => {}; +x4.isElement; + +// This is an element +var x5 = () => {}; +x5.isElement; + diff --git a/tests/cases/conformance/jsx/tsxInArrowFunction.tsx b/tests/cases/conformance/jsx/tsxInArrowFunction.tsx new file mode 100644 index 0000000000000..36951e0d09292 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxInArrowFunction.tsx @@ -0,0 +1,23 @@ +// @jsx: preserve + +declare namespace JSX { + interface Element { } + interface IntrinsicElements { + div: { + text?: string; + } + } +} + + +// didn't work +
{() =>
}
; + +// didn't work +
{x =>
}
; + +// worked +
{() => (
)}
; + +// worked (!) +
{() =>
}
; diff --git a/tests/cases/conformance/jsx/tsxNoJsx.tsx b/tests/cases/conformance/jsx/tsxNoJsx.tsx new file mode 100644 index 0000000000000..03b827b7e61cd --- /dev/null +++ b/tests/cases/conformance/jsx/tsxNoJsx.tsx @@ -0,0 +1,3 @@ +//@jsx: preserve + +; diff --git a/tests/cases/conformance/jsx/tsxOpeningClosingNames.tsx b/tests/cases/conformance/jsx/tsxOpeningClosingNames.tsx new file mode 100644 index 0000000000000..8f21517474fb8 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxOpeningClosingNames.tsx @@ -0,0 +1,11 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } +} + +declare module A.B.C { + var D: any; +} + +foo diff --git a/tests/cases/conformance/jsx/tsxParseTests1.tsx b/tests/cases/conformance/jsx/tsxParseTests1.tsx new file mode 100644 index 0000000000000..7675aee796239 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxParseTests1.tsx @@ -0,0 +1,8 @@ +//@filename: file.tsx +//@jsx: preserve +declare module JSX { + interface Element { } + interface IntrinsicElements { div; span; } +} + +var x =
; diff --git a/tests/cases/conformance/jsx/tsxReactEmit1.tsx b/tests/cases/conformance/jsx/tsxReactEmit1.tsx new file mode 100644 index 0000000000000..b8f14b0ba229c --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmit1.tsx @@ -0,0 +1,41 @@ +//@filename: file.tsx +//@jsx: react +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p; +var selfClosed1 =
; +var selfClosed2 =
; +var selfClosed3 =
; +var selfClosed4 =
; +var selfClosed5 =
; +var selfClosed6 =
; +var selfClosed7 =
; + +var openClosed1 =
; +var openClosed2 =
foo
; +var openClosed3 =
{p}
; +var openClosed4 =
{p < p}
; +var openClosed5 =
{p > p}
; + +class SomeClass { + f() { + var rewrites1 =
{() => this}
; + var rewrites2 =
{[p, ...p, p]}
; + var rewrites3 =
{{p}}
; + + var rewrites4 =
this}>
; + var rewrites5 =
; + var rewrites6 =
; + } +} + +var whitespace1 =
; +var whitespace2 =
{p}
; +var whitespace3 =
+ {p} +
; diff --git a/tests/cases/conformance/jsx/tsxReactEmit2.tsx b/tests/cases/conformance/jsx/tsxReactEmit2.tsx new file mode 100644 index 0000000000000..39a78a7da8791 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmit2.tsx @@ -0,0 +1,15 @@ +//@filename: file.tsx +//@jsx: react +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p1, p2, p3; +var spreads1 =
{p2}
; +var spreads2 =
{p2}
; +var spreads3 =
{p2}
; +var spreads4 =
{p2}
; +var spreads5 =
{p2}
; diff --git a/tests/cases/conformance/jsx/tsxReactEmit3.tsx b/tests/cases/conformance/jsx/tsxReactEmit3.tsx new file mode 100644 index 0000000000000..eb63be44f3b7a --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmit3.tsx @@ -0,0 +1,8 @@ +//@jsx: react +//@filename: test.tsx + +declare module JSX { interface Element { } } + +declare var Foo, Bar, baz; + + q s ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxReactEmit4.tsx b/tests/cases/conformance/jsx/tsxReactEmit4.tsx new file mode 100644 index 0000000000000..f007c35c24a9c --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmit4.tsx @@ -0,0 +1,18 @@ +//@filename: file.tsx +//@jsx: react +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +var p; +var openClosed1 =
+ + {blah} + +
; + +// Should emit React.__spread({}, p, {x: 0}) +var spread1 =
; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx b/tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx new file mode 100644 index 0000000000000..38c966fa70026 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx @@ -0,0 +1,52 @@ +//@filename: file.tsx +//@jsx: react +declare module JSX { + interface Element { } + interface IntrinsicElements { + [s: string]: any; + } +} + +// THIS FILE HAS TEST-SIGNIFICANT LEADING/TRAILING +// WHITESPACE, DO NOT RUN 'FORMAT DOCUMENT' ON IT + +var p = 0; +// Emit " " +
; +// Emit " ", p, " " +
{p}
; +// Emit only p +
+ {p} +
; + +// Emit only p +
+ {p} +
; + +// Emit " 3" +
3 +
; + +// Emit " 3 " +
3
; + +// Emit "3" +
+ 3 +
; + +// Emit no args +
+
; + +// Emit "foo" + ' ' + "bar" +
+ + foo + + bar + +
; + diff --git a/tests/cases/conformance/jsx/tsxTypeErrors.tsx b/tests/cases/conformance/jsx/tsxTypeErrors.tsx new file mode 100644 index 0000000000000..f8288b68ce336 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxTypeErrors.tsx @@ -0,0 +1,34 @@ +//@jsx: preserve + +// A built-in element (OK) +var a1 =
; + +// A built-in element with a mistyped property (error) +var a2 = + +// A built-in element with a badly-typed attribute value (error) +var thing = { oops: 100 }; +var a3 =
+ +// Mistyped html name (error) +var e1 = + +// A custom type +class MyClass { + props: { + pt?: { x: number; y: number; }; + name?: string; + reqd: boolean; + } +} + +// Let's use it +// TODO: Error on missing 'reqd' +var b1 = ; + +// Mistyped attribute member +// sample.tsx(23,22): error TS2322: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'. +// Types of property 'y' are incompatible. +// Type 'string' is not assignable to type 'number'. +var b2 = ; + diff --git a/tests/cases/fourslash/asOperatorFormatting.ts b/tests/cases/fourslash/asOperatorFormatting.ts new file mode 100644 index 0000000000000..f697ffd8bb6c2 --- /dev/null +++ b/tests/cases/fourslash/asOperatorFormatting.ts @@ -0,0 +1,7 @@ +/// + +//// /**/var x = 3 as number; + +goTo.marker(); +format.document(); +verify.currentLineContentIs("var x = 3 as number;"); diff --git a/tests/cases/fourslash/server/tsxIncrementalServer.ts b/tests/cases/fourslash/server/tsxIncrementalServer.ts new file mode 100644 index 0000000000000..9ae51406c2fa8 --- /dev/null +++ b/tests/cases/fourslash/server/tsxIncrementalServer.ts @@ -0,0 +1,13 @@ +/// + +//// /**/ + +goTo.marker(); +edit.insert("<"); +edit.insert("div"); +edit.insert(" "); +edit.insert(" id"); +edit.insert("="); +edit.insert("\"foo"); +edit.insert("\""); +edit.insert(">"); diff --git a/tests/cases/fourslash/tsxCompletion1.ts b/tests/cases/fourslash/tsxCompletion1.ts new file mode 100644 index 0000000000000..f638b0b6e4fa8 --- /dev/null +++ b/tests/cases/fourslash/tsxCompletion1.ts @@ -0,0 +1,14 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// div: { ONE: string; TWO: number; } +//// } +//// } +//// var x =
; + +goTo.marker(); +verify.completionListContains('ONE'); +verify.completionListContains('TWO'); diff --git a/tests/cases/fourslash/tsxCompletion2.ts b/tests/cases/fourslash/tsxCompletion2.ts new file mode 100644 index 0000000000000..d33f910687719 --- /dev/null +++ b/tests/cases/fourslash/tsxCompletion2.ts @@ -0,0 +1,15 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props; } +//// } +//// class MyComp { props: { ONE: string; TWO: number } } +//// var x = ; + +goTo.marker(); +verify.completionListContains('ONE'); +verify.completionListContains('TWO'); diff --git a/tests/cases/fourslash/tsxGoToDefinitionClasses.ts b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts new file mode 100644 index 0000000000000..11ff3afeb8ae3 --- /dev/null +++ b/tests/cases/fourslash/tsxGoToDefinitionClasses.ts @@ -0,0 +1,23 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { } +//// interface ElementAttributesProperty { props; } +//// } +//// /*ct*/class MyClass { +//// props: { +//// /*pt*/foo: string; +//// } +//// } +//// var x = ; +//// var y = ; + +goTo.marker('c'); +goTo.definition(); +verify.caretAtMarker('ct'); + +goTo.marker('p'); +goTo.definition(); +verify.caretAtMarker('pt'); diff --git a/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts b/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts new file mode 100644 index 0000000000000..bbdf395e4789a --- /dev/null +++ b/tests/cases/fourslash/tsxGoToDefinitionIntrinsics.ts @@ -0,0 +1,29 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// /*dt*/div: { +//// /*pt*/name?: string; +//// isOpen?: boolean; +//// }; +//// /*st*/span: { n: string; }; +//// } +//// } +//// var x = ; +//// var y = ; +//// var z =
; + +goTo.marker('ds'); +goTo.definition(); +verify.caretAtMarker('dt'); + +goTo.marker('ss'); +goTo.definition(); +verify.caretAtMarker('st'); + +goTo.marker('ps'); +goTo.definition(); +verify.caretAtMarker('pt'); + diff --git a/tests/cases/fourslash/tsxIncremental.ts b/tests/cases/fourslash/tsxIncremental.ts new file mode 100644 index 0000000000000..c901401fff979 --- /dev/null +++ b/tests/cases/fourslash/tsxIncremental.ts @@ -0,0 +1,13 @@ +/// + +//// /**/ + +goTo.marker(); +edit.insert("<"); +edit.insert("div"); +edit.insert(" "); +edit.insert(" id"); +edit.insert("="); +edit.insert("\"foo"); +edit.insert("\""); +edit.insert(">"); diff --git a/tests/cases/fourslash/tsxParsing.ts b/tests/cases/fourslash/tsxParsing.ts new file mode 100644 index 0000000000000..e5b2e7ea841ae --- /dev/null +++ b/tests/cases/fourslash/tsxParsing.ts @@ -0,0 +1,5 @@ +//// var x =
; +//// var y = /**/x; + +goTo.marker(); +verify.quickInfoExists(); diff --git a/tests/cases/fourslash/tsxRename1.ts b/tests/cases/fourslash/tsxRename1.ts new file mode 100644 index 0000000000000..3fb973ec99621 --- /dev/null +++ b/tests/cases/fourslash/tsxRename1.ts @@ -0,0 +1,17 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// [|div|]: { +//// name?: string; +//// isOpen?: boolean; +//// }; +//// span: { n: string; }; +//// } +//// } +//// var x = <[|di/*ds*/v|] />; + +goTo.marker('ds'); +verify.renameLocations(false, false); diff --git a/tests/cases/fourslash/tsxRename2.ts b/tests/cases/fourslash/tsxRename2.ts new file mode 100644 index 0000000000000..d0f5737214b96 --- /dev/null +++ b/tests/cases/fourslash/tsxRename2.ts @@ -0,0 +1,17 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// div: { +//// [|name|]?: string; +//// isOpen?: boolean; +//// }; +//// span: { n: string; }; +//// } +//// } +//// var x =
; + +goTo.marker(); +verify.renameLocations(false, false); diff --git a/tests/cases/fourslash/tsxRename3.ts b/tests/cases/fourslash/tsxRename3.ts new file mode 100644 index 0000000000000..1ab9c8a591595 --- /dev/null +++ b/tests/cases/fourslash/tsxRename3.ts @@ -0,0 +1,20 @@ +/// + +//@Filename: file.tsx +//// declare module JSX { +//// interface Element { } +//// interface IntrinsicElements { +//// } +//// interface ElementAttributesProperty { props } +//// } +//// class MyClass { +//// props: { +//// [|name|]?: string; +//// size?: number; +//// } +//// +//// +//// var x = ; + +goTo.marker(); +verify.renameLocations(false, false);